Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */ 2 : /* 3 : * async.h: Asynchronous function calls for boot performance 4 : * 5 : * (C) Copyright 2009 Intel Corporation 6 : * 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 : 16 : typedef u64 async_cookie_t; 17 : typedef void (*async_func_t) (void *data, async_cookie_t cookie); 18 : struct async_domain { 19 : struct list_head pending; 20 : unsigned registered:1; 21 : }; 22 : 23 : /* 24 : * domain participates in global async_synchronize_full 25 : */ 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 is 32 : * complete, this domain does not participate in async_synchronize_full 33 : */ 34 : #define ASYNC_DOMAIN_EXCLUSIVE(_name) \ 35 : struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ 36 : .registered = 0 } 37 : 38 : async_cookie_t async_schedule_node(async_func_t func, void *data, 39 : int node); 40 : async_cookie_t async_schedule_node_domain(async_func_t func, void *data, 41 : int node, 42 : struct async_domain *domain); 43 : 44 : /** 45 : * async_schedule - schedule a function for asynchronous execution 46 : * @func: function to execute asynchronously 47 : * @data: data pointer to pass to the function 48 : * 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 : */ 52 0 : static inline async_cookie_t async_schedule(async_func_t func, void *data) 53 : { 54 0 : 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 domain 59 : * @func: function to execute asynchronously 60 : * @data: data pointer to pass to the function 61 : * @domain: the domain 62 : * 63 : * Returns an async_cookie_t that may be used for checkpointing later. 64 : * @domain may be used in the async_synchronize_*_domain() functions to 65 : * wait within a certain synchronization domain rather than globally. 66 : * Note: This function may be called from atomic or non-atomic contexts. 67 : */ 68 : static inline async_cookie_t 69 : async_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_schedule 77 : * @func: function to execute asynchronously 78 : * @dev: device argument to be passed to function 79 : * 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 NUMA 82 : * context for where to run the function. By doing this we can try to 83 : * provide for the best possible outcome by operating on the device on the 84 : * CPUs closest to the device. 85 : * Note: This function may be called from atomic or non-atomic contexts. 86 : */ 87 : static inline async_cookie_t 88 0 : async_schedule_dev(async_func_t func, struct device *dev) 89 : { 90 0 : return async_schedule_node(func, dev, dev_to_node(dev)); 91 : } 92 : 93 : /** 94 : * async_schedule_dev_domain - A device specific version of async_schedule_domain 95 : * @func: function to execute asynchronously 96 : * @dev: device argument to be passed to function 97 : * @domain: the domain 98 : * 99 : * Returns an async_cookie_t that may be used for checkpointing later. 100 : * @dev is used as both the argument for the function and to provide NUMA 101 : * context for where to run the function. By doing this we can try to 102 : * provide for the best possible outcome by operating on the device on the 103 : * CPUs closest to the device. 104 : * @domain may be used in the async_synchronize_*_domain() functions to 105 : * wait within a certain synchronization domain rather than globally. 106 : * Note: This function may be called from atomic or non-atomic contexts. 107 : */ 108 : static inline async_cookie_t 109 : async_schedule_dev_domain(async_func_t func, struct device *dev, 110 : struct async_domain *domain) 111 : { 112 : return async_schedule_node_domain(func, dev, dev_to_node(dev), domain); 113 : } 114 : 115 : void async_unregister_domain(struct async_domain *domain); 116 : extern void async_synchronize_full(void); 117 : extern void async_synchronize_full_domain(struct async_domain *domain); 118 : extern void async_synchronize_cookie(async_cookie_t cookie); 119 : extern void async_synchronize_cookie_domain(async_cookie_t cookie, 120 : struct async_domain *domain); 121 : extern bool current_is_async(void); 122 : #endif