1a66e0092SPaul E. McKenney /* SPDX-License-Identifier: GPL-2.0+ */ 2cc44ca84SOleg Nesterov /* 3cc44ca84SOleg Nesterov * RCU-based infrastructure for lightweight reader-writer locking 4cc44ca84SOleg Nesterov * 5cc44ca84SOleg Nesterov * Copyright (c) 2015, Red Hat, Inc. 6cc44ca84SOleg Nesterov * 7cc44ca84SOleg Nesterov * Author: Oleg Nesterov <oleg@redhat.com> 8cc44ca84SOleg Nesterov */ 9cc44ca84SOleg Nesterov 10cc44ca84SOleg Nesterov #ifndef _LINUX_RCU_SYNC_H_ 11cc44ca84SOleg Nesterov #define _LINUX_RCU_SYNC_H_ 12cc44ca84SOleg Nesterov 13cc44ca84SOleg Nesterov #include <linux/wait.h> 14cc44ca84SOleg Nesterov #include <linux/rcupdate.h> 15cc44ca84SOleg Nesterov 16cc44ca84SOleg Nesterov /* Structure to mediate between updaters and fastpath-using readers. */ 17cc44ca84SOleg Nesterov struct rcu_sync { 18cc44ca84SOleg Nesterov int gp_state; 19cc44ca84SOleg Nesterov int gp_count; 20cc44ca84SOleg Nesterov wait_queue_head_t gp_wait; 21cc44ca84SOleg Nesterov 22cc44ca84SOleg Nesterov struct rcu_head cb_head; 23cc44ca84SOleg Nesterov }; 24cc44ca84SOleg Nesterov 25cc44ca84SOleg Nesterov /** 26cc44ca84SOleg Nesterov * rcu_sync_is_idle() - Are readers permitted to use their fastpaths? 27cc44ca84SOleg Nesterov * @rsp: Pointer to rcu_sync structure to use for synchronization 28cc44ca84SOleg Nesterov * 2995bf33b5SOleg Nesterov * Returns true if readers are permitted to use their fastpaths. Must be 3095bf33b5SOleg Nesterov * invoked within some flavor of RCU read-side critical section. 31cc44ca84SOleg Nesterov */ rcu_sync_is_idle(struct rcu_sync * rsp)32cc44ca84SOleg Nesterovstatic inline bool rcu_sync_is_idle(struct rcu_sync *rsp) 33cc44ca84SOleg Nesterov { 34*fbab8d67SJoel Fernandes (Google) RCU_LOCKDEP_WARN(!rcu_read_lock_any_held(), 3595bf33b5SOleg Nesterov "suspicious rcu_sync_is_idle() usage"); 3689da3b94SOleg Nesterov return !READ_ONCE(rsp->gp_state); /* GP_IDLE */ 37cc44ca84SOleg Nesterov } 38cc44ca84SOleg Nesterov 3995bf33b5SOleg Nesterov extern void rcu_sync_init(struct rcu_sync *); 403942a9bdSPeter Zijlstra extern void rcu_sync_enter_start(struct rcu_sync *); 41cc44ca84SOleg Nesterov extern void rcu_sync_enter(struct rcu_sync *); 42cc44ca84SOleg Nesterov extern void rcu_sync_exit(struct rcu_sync *); 4307899a6eSOleg Nesterov extern void rcu_sync_dtor(struct rcu_sync *); 44cc44ca84SOleg Nesterov 4595bf33b5SOleg Nesterov #define __RCU_SYNC_INITIALIZER(name) { \ 4682e8c565SOleg Nesterov .gp_state = 0, \ 4782e8c565SOleg Nesterov .gp_count = 0, \ 4882e8c565SOleg Nesterov .gp_wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.gp_wait), \ 4982e8c565SOleg Nesterov } 5082e8c565SOleg Nesterov 5182e8c565SOleg Nesterov #define DEFINE_RCU_SYNC(name) \ 5295bf33b5SOleg Nesterov struct rcu_sync name = __RCU_SYNC_INITIALIZER(name) 5382e8c565SOleg Nesterov 54cc44ca84SOleg Nesterov #endif /* _LINUX_RCU_SYNC_H_ */ 55