1 /* 2 * RCU-based infrastructure for lightweight reader-writer locking 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, you can access it online at 16 * http://www.gnu.org/licenses/gpl-2.0.html. 17 * 18 * Copyright (c) 2015, Red Hat, Inc. 19 * 20 * Author: Oleg Nesterov <[email protected]> 21 */ 22 23 #ifndef _LINUX_RCU_SYNC_H_ 24 #define _LINUX_RCU_SYNC_H_ 25 26 #include <linux/wait.h> 27 #include <linux/rcupdate.h> 28 29 /* Structure to mediate between updaters and fastpath-using readers. */ 30 struct rcu_sync { 31 int gp_state; 32 int gp_count; 33 wait_queue_head_t gp_wait; 34 35 int cb_state; 36 struct rcu_head cb_head; 37 38 void (*sync)(void); 39 void (*call)(struct rcu_head *, void (*)(struct rcu_head *)); 40 }; 41 42 #define ___RCU_SYNC_INIT(name) \ 43 .gp_state = 0, \ 44 .gp_count = 0, \ 45 .gp_wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.gp_wait), \ 46 .cb_state = 0 47 48 #define __RCU_SCHED_SYNC_INIT(name) { \ 49 ___RCU_SYNC_INIT(name), \ 50 .sync = synchronize_sched, \ 51 .call = call_rcu_sched, \ 52 } 53 54 #define __RCU_BH_SYNC_INIT(name) { \ 55 ___RCU_SYNC_INIT(name), \ 56 .sync = synchronize_rcu_bh, \ 57 .call = call_rcu_bh, \ 58 } 59 60 #define __RCU_SYNC_INIT(name) { \ 61 ___RCU_SYNC_INIT(name), \ 62 .sync = synchronize_rcu, \ 63 .call = call_rcu, \ 64 } 65 66 #define DEFINE_RCU_SCHED_SYNC(name) \ 67 struct rcu_sync name = __RCU_SCHED_SYNC_INIT(name) 68 69 #define DEFINE_RCU_BH_SYNC(name) \ 70 struct rcu_sync name = __RCU_BH_SYNC_INIT(name) 71 72 #define DEFINE_RCU_SYNC(name) \ 73 struct rcu_sync name = __RCU_SYNC_INIT(name) 74 75 /** 76 * rcu_sync_is_idle() - Are readers permitted to use their fastpaths? 77 * @rsp: Pointer to rcu_sync structure to use for synchronization 78 * 79 * Returns true if readers are permitted to use their fastpaths. 80 * Must be invoked within an RCU read-side critical section whose 81 * flavor matches that of the rcu_sync struture. 82 */ 83 static inline bool rcu_sync_is_idle(struct rcu_sync *rsp) 84 { 85 return !rsp->gp_state; /* GP_IDLE */ 86 } 87 88 enum rcu_sync_type { RCU_SYNC, RCU_SCHED_SYNC, RCU_BH_SYNC }; 89 90 extern void rcu_sync_init(struct rcu_sync *, enum rcu_sync_type); 91 extern void rcu_sync_enter(struct rcu_sync *); 92 extern void rcu_sync_exit(struct rcu_sync *); 93 94 #endif /* _LINUX_RCU_SYNC_H_ */ 95