]>
Commit | Line | Data |
---|---|---|
b886d83c | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
22a9d645 AV |
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> | |
22a9d645 | 7 | */ |
2955b47d DW |
8 | #ifndef __ASYNC_H__ |
9 | #define __ASYNC_H__ | |
22a9d645 AV |
10 | |
11 | #include <linux/types.h> | |
12 | #include <linux/list.h> | |
6be9238e AD |
13 | #include <linux/numa.h> |
14 | #include <linux/device.h> | |
22a9d645 AV |
15 | |
16 | typedef u64 async_cookie_t; | |
362f2b09 | 17 | typedef void (*async_func_t) (void *data, async_cookie_t cookie); |
2955b47d | 18 | struct async_domain { |
52722794 | 19 | struct list_head pending; |
2955b47d DW |
20 | unsigned registered:1; |
21 | }; | |
22 | ||
23 | /* | |
24 | * domain participates in global async_synchronize_full | |
25 | */ | |
26 | #define ASYNC_DOMAIN(_name) \ | |
cc2a8b1a | 27 | struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ |
2955b47d DW |
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) \ | |
cc2a8b1a | 35 | struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ |
2955b47d | 36 | .registered = 0 } |
22a9d645 | 37 | |
6be9238e AD |
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 | static 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 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 | async_schedule_dev(async_func_t func, struct device *dev) | |
89 | { | |
90 | 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 | ||
22a9d645 | 115 | extern void async_synchronize_full(void); |
2955b47d | 116 | extern void async_synchronize_full_domain(struct async_domain *domain); |
22a9d645 | 117 | extern void async_synchronize_cookie(async_cookie_t cookie); |
766ccb9e | 118 | extern void async_synchronize_cookie_domain(async_cookie_t cookie, |
2955b47d | 119 | struct async_domain *domain); |
84b233ad | 120 | extern bool current_is_async(void); |
2955b47d | 121 | #endif |