at v5.1 4.6 kB view raw
1/* 2 * async.h: Asynchronous function calls for boot performance 3 * 4 * (C) Copyright 2009 Intel Corporation 5 * Author: Arjan van de Ven <arjan@linux.intel.com> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; version 2 10 * of the License. 11 */ 12#ifndef __ASYNC_H__ 13#define __ASYNC_H__ 14 15#include <linux/types.h> 16#include <linux/list.h> 17#include <linux/numa.h> 18#include <linux/device.h> 19 20typedef u64 async_cookie_t; 21typedef void (*async_func_t) (void *data, async_cookie_t cookie); 22struct async_domain { 23 struct list_head pending; 24 unsigned registered:1; 25}; 26 27/* 28 * domain participates in global async_synchronize_full 29 */ 30#define ASYNC_DOMAIN(_name) \ 31 struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ 32 .registered = 1 } 33 34/* 35 * domain is free to go out of scope as soon as all pending work is 36 * complete, this domain does not participate in async_synchronize_full 37 */ 38#define ASYNC_DOMAIN_EXCLUSIVE(_name) \ 39 struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \ 40 .registered = 0 } 41 42async_cookie_t async_schedule_node(async_func_t func, void *data, 43 int node); 44async_cookie_t async_schedule_node_domain(async_func_t func, void *data, 45 int node, 46 struct async_domain *domain); 47 48/** 49 * async_schedule - schedule a function for asynchronous execution 50 * @func: function to execute asynchronously 51 * @data: data pointer to pass to the function 52 * 53 * Returns an async_cookie_t that may be used for checkpointing later. 54 * Note: This function may be called from atomic or non-atomic contexts. 55 */ 56static inline async_cookie_t async_schedule(async_func_t func, void *data) 57{ 58 return async_schedule_node(func, data, NUMA_NO_NODE); 59} 60 61/** 62 * async_schedule_domain - schedule a function for asynchronous execution within a certain domain 63 * @func: function to execute asynchronously 64 * @data: data pointer to pass to the function 65 * @domain: the domain 66 * 67 * Returns an async_cookie_t that may be used for checkpointing later. 68 * @domain may be used in the async_synchronize_*_domain() functions to 69 * wait within a certain synchronization domain rather than globally. 70 * Note: This function may be called from atomic or non-atomic contexts. 71 */ 72static inline async_cookie_t 73async_schedule_domain(async_func_t func, void *data, 74 struct async_domain *domain) 75{ 76 return async_schedule_node_domain(func, data, NUMA_NO_NODE, domain); 77} 78 79/** 80 * async_schedule_dev - A device specific version of async_schedule 81 * @func: function to execute asynchronously 82 * @dev: device argument to be passed to function 83 * 84 * Returns an async_cookie_t that may be used for checkpointing later. 85 * @dev is used as both the argument for the function and to provide NUMA 86 * context for where to run the function. By doing this we can try to 87 * provide for the best possible outcome by operating on the device on the 88 * CPUs closest to the device. 89 * Note: This function may be called from atomic or non-atomic contexts. 90 */ 91static inline async_cookie_t 92async_schedule_dev(async_func_t func, struct device *dev) 93{ 94 return async_schedule_node(func, dev, dev_to_node(dev)); 95} 96 97/** 98 * async_schedule_dev_domain - A device specific version of async_schedule_domain 99 * @func: function to execute asynchronously 100 * @dev: device argument to be passed to function 101 * @domain: the domain 102 * 103 * Returns an async_cookie_t that may be used for checkpointing later. 104 * @dev is used as both the argument for the function and to provide NUMA 105 * context for where to run the function. By doing this we can try to 106 * provide for the best possible outcome by operating on the device on the 107 * CPUs closest to the device. 108 * @domain may be used in the async_synchronize_*_domain() functions to 109 * wait within a certain synchronization domain rather than globally. 110 * Note: This function may be called from atomic or non-atomic contexts. 111 */ 112static inline async_cookie_t 113async_schedule_dev_domain(async_func_t func, struct device *dev, 114 struct async_domain *domain) 115{ 116 return async_schedule_node_domain(func, dev, dev_to_node(dev), domain); 117} 118 119void async_unregister_domain(struct async_domain *domain); 120extern void async_synchronize_full(void); 121extern void async_synchronize_full_domain(struct async_domain *domain); 122extern void async_synchronize_cookie(async_cookie_t cookie); 123extern void async_synchronize_cookie_domain(async_cookie_t cookie, 124 struct async_domain *domain); 125extern bool current_is_async(void); 126#endif