1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_SCHED_RCUPDATE_WAIT_H 3 #define _LINUX_SCHED_RCUPDATE_WAIT_H 4 5 /* 6 * RCU synchronization types and methods: 7 */ 8 9 #include <linux/rcupdate.h> 10 #include <linux/completion.h> 11 12 /* 13 * Structure allowing asynchronous waiting on RCU. 14 */ 15 struct rcu_synchronize { 16 struct rcu_head head; 17 struct completion completion; 18 }; 19 void wakeme_after_rcu(struct rcu_head *head); 20 21 void __wait_rcu_gp(bool checktiny, int n, call_rcu_func_t *crcu_array, 22 struct rcu_synchronize *rs_array); 23 24 #define _wait_rcu_gp(checktiny, ...) \ 25 do { \ 26 call_rcu_func_t __crcu_array[] = { __VA_ARGS__ }; \ 27 struct rcu_synchronize __rs_array[ARRAY_SIZE(__crcu_array)]; \ 28 __wait_rcu_gp(checktiny, ARRAY_SIZE(__crcu_array), \ 29 __crcu_array, __rs_array); \ 30 } while (0) 31 32 #define wait_rcu_gp(...) _wait_rcu_gp(false, __VA_ARGS__) 33 34 /** 35 * synchronize_rcu_mult - Wait concurrently for multiple grace periods 36 * @...: List of call_rcu() functions for different grace periods to wait on 37 * 38 * This macro waits concurrently for multiple types of RCU grace periods. 39 * For example, synchronize_rcu_mult(call_rcu, call_rcu_tasks) would wait 40 * on concurrent RCU and RCU-tasks grace periods. Waiting on a given SRCU 41 * domain requires you to write a wrapper function for that SRCU domain's 42 * call_srcu() function, with this wrapper supplying the pointer to the 43 * corresponding srcu_struct. 44 * 45 * The first argument tells Tiny RCU's _wait_rcu_gp() not to 46 * bother waiting for RCU. The reason for this is because anywhere 47 * synchronize_rcu_mult() can be called is automatically already a full 48 * grace period. 49 */ 50 #define synchronize_rcu_mult(...) \ 51 _wait_rcu_gp(IS_ENABLED(CONFIG_TINY_RCU), __VA_ARGS__) 52 53 #endif /* _LINUX_SCHED_RCUPDATE_WAIT_H */ 54