125 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * async.h: Asynchronous function calls for boot performance4 *5 * (C) Copyright 2009 Intel Corporation6 * Author: Arjan van de Ven <arjan@linux.intel.com>7 */8#ifndef __ASYNC_H__9#define __ASYNC_H__10 11#include <linux/types.h>12#include <linux/list.h>13#include <linux/numa.h>14#include <linux/device.h>15 16typedef u64 async_cookie_t;17typedef void (*async_func_t) (void *data, async_cookie_t cookie);18struct async_domain {19 struct list_head pending;20 unsigned registered:1;21};22 23/*24 * domain participates in global async_synchronize_full25 */26#define ASYNC_DOMAIN(_name) \27 struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \28 .registered = 1 }29 30/*31 * domain is free to go out of scope as soon as all pending work is32 * complete, this domain does not participate in async_synchronize_full33 */34#define ASYNC_DOMAIN_EXCLUSIVE(_name) \35 struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \36 .registered = 0 }37 38async_cookie_t async_schedule_node(async_func_t func, void *data,39 int node) HWJS_SUSPENDS;40async_cookie_t async_schedule_node_domain(async_func_t func, void *data,41 int node,42 struct async_domain *domain) HWJS_SUSPENDS;43 44/**45 * async_schedule - schedule a function for asynchronous execution46 * @func: function to execute asynchronously47 * @data: data pointer to pass to the function48 *49 * Returns an async_cookie_t that may be used for checkpointing later.50 * Note: This function may be called from atomic or non-atomic contexts.51 */52static inline async_cookie_t async_schedule(async_func_t func, void *data)53{54 return async_schedule_node(func, data, NUMA_NO_NODE);55}56 57/**58 * async_schedule_domain - schedule a function for asynchronous execution within a certain domain59 * @func: function to execute asynchronously60 * @data: data pointer to pass to the function61 * @domain: the domain62 *63 * Returns an async_cookie_t that may be used for checkpointing later.64 * @domain may be used in the async_synchronize_*_domain() functions to65 * wait within a certain synchronization domain rather than globally.66 * Note: This function may be called from atomic or non-atomic contexts.67 */68static inline async_cookie_t69async_schedule_domain(async_func_t func, void *data,70 struct async_domain *domain)71{72 return async_schedule_node_domain(func, data, NUMA_NO_NODE, domain);73}74 75/**76 * async_schedule_dev - A device specific version of async_schedule77 * @func: function to execute asynchronously78 * @dev: device argument to be passed to function79 *80 * Returns an async_cookie_t that may be used for checkpointing later.81 * @dev is used as both the argument for the function and to provide NUMA82 * context for where to run the function. By doing this we can try to83 * provide for the best possible outcome by operating on the device on the84 * CPUs closest to the device.85 * Note: This function may be called from atomic or non-atomic contexts.86 */87static inline async_cookie_t88async_schedule_dev(async_func_t func, struct device *dev)89{90 return async_schedule_node(func, dev, dev_to_node(dev));91}92 93bool async_schedule_dev_nocall(async_func_t func, struct device *dev) HWJS_SUSPENDS;94 95/**96 * async_schedule_dev_domain - A device specific version of async_schedule_domain97 * @func: function to execute asynchronously98 * @dev: device argument to be passed to function99 * @domain: the domain100 *101 * Returns an async_cookie_t that may be used for checkpointing later.102 * @dev is used as both the argument for the function and to provide NUMA103 * context for where to run the function. By doing this we can try to104 * provide for the best possible outcome by operating on the device on the105 * CPUs closest to the device.106 * @domain may be used in the async_synchronize_*_domain() functions to107 * wait within a certain synchronization domain rather than globally.108 * Note: This function may be called from atomic or non-atomic contexts.109 */110static inline async_cookie_t111async_schedule_dev_domain(async_func_t func, struct device *dev,112 struct async_domain *domain)113{114 return async_schedule_node_domain(func, dev, dev_to_node(dev), domain);115}116 117extern void async_synchronize_full(void) HWJS_SUSPENDS;118extern void async_synchronize_full_domain(struct async_domain *domain) HWJS_SUSPENDS;119extern void async_synchronize_cookie(async_cookie_t cookie) HWJS_SUSPENDS;120extern void async_synchronize_cookie_domain(async_cookie_t cookie,121 struct async_domain *domain) HWJS_SUSPENDS;122extern bool current_is_async(void);123extern void async_init(void) HWJS_SUSPENDS;124#endif125