1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * RCU-based infrastructure for lightweight reader-writer locking 4 * 5 * Copyright (c) 2015, Red Hat, Inc. 6 * 7 * Author: Oleg Nesterov <oleg@redhat.com> 8 */ 9 10 #ifndef _LINUX_RCU_SYNC_H_ 11 #define _LINUX_RCU_SYNC_H_ 12 13 #include <linux/wait.h> 14 #include <linux/rcupdate.h> 15 16 enum rcu_sync_type { RCU_SYNC, RCU_SCHED_SYNC, RCU_BH_SYNC }; 17 18 /* Structure to mediate between updaters and fastpath-using readers. */ 19 struct rcu_sync { 20 int gp_state; 21 int gp_count; 22 wait_queue_head_t gp_wait; 23 24 int cb_state; 25 struct rcu_head cb_head; 26 27 enum rcu_sync_type gp_type; 28 }; 29 30 extern void rcu_sync_lockdep_assert(struct rcu_sync *); 31 32 /** 33 * rcu_sync_is_idle() - Are readers permitted to use their fastpaths? 34 * @rsp: Pointer to rcu_sync structure to use for synchronization 35 * 36 * Returns true if readers are permitted to use their fastpaths. 37 * Must be invoked within an RCU read-side critical section whose 38 * flavor matches that of the rcu_sync struture. 39 */ 40 static inline bool rcu_sync_is_idle(struct rcu_sync *rsp) 41 { 42 #ifdef CONFIG_PROVE_RCU 43 rcu_sync_lockdep_assert(rsp); 44 #endif 45 return !rsp->gp_state; /* GP_IDLE */ 46 } 47 48 extern void rcu_sync_init(struct rcu_sync *, enum rcu_sync_type); 49 extern void rcu_sync_enter_start(struct rcu_sync *); 50 extern void rcu_sync_enter(struct rcu_sync *); 51 extern void rcu_sync_exit(struct rcu_sync *); 52 extern void rcu_sync_dtor(struct rcu_sync *); 53 54 #define __RCU_SYNC_INITIALIZER(name, type) { \ 55 .gp_state = 0, \ 56 .gp_count = 0, \ 57 .gp_wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.gp_wait), \ 58 .cb_state = 0, \ 59 .gp_type = type, \ 60 } 61 62 #define __DEFINE_RCU_SYNC(name, type) \ 63 struct rcu_sync_struct name = __RCU_SYNC_INITIALIZER(name, type) 64 65 #define DEFINE_RCU_SYNC(name) \ 66 __DEFINE_RCU_SYNC(name, RCU_SYNC) 67 68 #define DEFINE_RCU_SCHED_SYNC(name) \ 69 __DEFINE_RCU_SYNC(name, RCU_SCHED_SYNC) 70 71 #define DEFINE_RCU_BH_SYNC(name) \ 72 __DEFINE_RCU_SYNC(name, RCU_BH_SYNC) 73 74 #endif /* _LINUX_RCU_SYNC_H_ */ 75