async.h (4367B)
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 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_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 38async_cookie_t async_schedule_node(async_func_t func, void *data, 39 int node); 40async_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 */ 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 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 */ 68static inline async_cookie_t 69async_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 */ 87static inline async_cookie_t 88async_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 */ 108static inline async_cookie_t 109async_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 115extern void async_synchronize_full(void); 116extern void async_synchronize_full_domain(struct async_domain *domain); 117extern void async_synchronize_cookie(async_cookie_t cookie); 118extern void async_synchronize_cookie_domain(async_cookie_t cookie, 119 struct async_domain *domain); 120extern bool current_is_async(void); 121#endif