Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0+ */
0002 /*
0003  * Sleepable Read-Copy Update mechanism for mutual exclusion
0004  *
0005  * Copyright (C) IBM Corporation, 2006
0006  * Copyright (C) Fujitsu, 2012
0007  *
0008  * Author: Paul McKenney <paulmck@linux.ibm.com>
0009  *     Lai Jiangshan <laijs@cn.fujitsu.com>
0010  *
0011  * For detailed explanation of Read-Copy Update mechanism see -
0012  *      Documentation/RCU/ *.txt
0013  *
0014  */
0015 
0016 #ifndef _LINUX_SRCU_H
0017 #define _LINUX_SRCU_H
0018 
0019 #include <linux/mutex.h>
0020 #include <linux/rcupdate.h>
0021 #include <linux/workqueue.h>
0022 #include <linux/rcu_segcblist.h>
0023 
0024 struct srcu_struct;
0025 
0026 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0027 
0028 int __init_srcu_struct(struct srcu_struct *ssp, const char *name,
0029                struct lock_class_key *key);
0030 
0031 #define init_srcu_struct(ssp) \
0032 ({ \
0033     static struct lock_class_key __srcu_key; \
0034     \
0035     __init_srcu_struct((ssp), #ssp, &__srcu_key); \
0036 })
0037 
0038 #define __SRCU_DEP_MAP_INIT(srcu_name)  .dep_map = { .name = #srcu_name },
0039 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
0040 
0041 int init_srcu_struct(struct srcu_struct *ssp);
0042 
0043 #define __SRCU_DEP_MAP_INIT(srcu_name)
0044 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
0045 
0046 #ifdef CONFIG_TINY_SRCU
0047 #include <linux/srcutiny.h>
0048 #elif defined(CONFIG_TREE_SRCU)
0049 #include <linux/srcutree.h>
0050 #elif defined(CONFIG_SRCU)
0051 #error "Unknown SRCU implementation specified to kernel configuration"
0052 #else
0053 /* Dummy definition for things like notifiers.  Actual use gets link error. */
0054 struct srcu_struct { };
0055 #endif
0056 
0057 void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
0058         void (*func)(struct rcu_head *head));
0059 void cleanup_srcu_struct(struct srcu_struct *ssp);
0060 int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp);
0061 void __srcu_read_unlock(struct srcu_struct *ssp, int idx) __releases(ssp);
0062 void synchronize_srcu(struct srcu_struct *ssp);
0063 unsigned long get_state_synchronize_srcu(struct srcu_struct *ssp);
0064 unsigned long start_poll_synchronize_srcu(struct srcu_struct *ssp);
0065 bool poll_state_synchronize_srcu(struct srcu_struct *ssp, unsigned long cookie);
0066 
0067 #ifdef CONFIG_SRCU
0068 void srcu_init(void);
0069 #else /* #ifdef CONFIG_SRCU */
0070 static inline void srcu_init(void) { }
0071 #endif /* #else #ifdef CONFIG_SRCU */
0072 
0073 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0074 
0075 /**
0076  * srcu_read_lock_held - might we be in SRCU read-side critical section?
0077  * @ssp: The srcu_struct structure to check
0078  *
0079  * If CONFIG_DEBUG_LOCK_ALLOC is selected, returns nonzero iff in an SRCU
0080  * read-side critical section.  In absence of CONFIG_DEBUG_LOCK_ALLOC,
0081  * this assumes we are in an SRCU read-side critical section unless it can
0082  * prove otherwise.
0083  *
0084  * Checks debug_lockdep_rcu_enabled() to prevent false positives during boot
0085  * and while lockdep is disabled.
0086  *
0087  * Note that SRCU is based on its own statemachine and it doesn't
0088  * relies on normal RCU, it can be called from the CPU which
0089  * is in the idle loop from an RCU point of view or offline.
0090  */
0091 static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
0092 {
0093     if (!debug_lockdep_rcu_enabled())
0094         return 1;
0095     return lock_is_held(&ssp->dep_map);
0096 }
0097 
0098 #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
0099 
0100 static inline int srcu_read_lock_held(const struct srcu_struct *ssp)
0101 {
0102     return 1;
0103 }
0104 
0105 #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
0106 
0107 /**
0108  * srcu_dereference_check - fetch SRCU-protected pointer for later dereferencing
0109  * @p: the pointer to fetch and protect for later dereferencing
0110  * @ssp: pointer to the srcu_struct, which is used to check that we
0111  *  really are in an SRCU read-side critical section.
0112  * @c: condition to check for update-side use
0113  *
0114  * If PROVE_RCU is enabled, invoking this outside of an RCU read-side
0115  * critical section will result in an RCU-lockdep splat, unless @c evaluates
0116  * to 1.  The @c argument will normally be a logical expression containing
0117  * lockdep_is_held() calls.
0118  */
0119 #define srcu_dereference_check(p, ssp, c) \
0120     __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
0121                 (c) || srcu_read_lock_held(ssp), __rcu)
0122 
0123 /**
0124  * srcu_dereference - fetch SRCU-protected pointer for later dereferencing
0125  * @p: the pointer to fetch and protect for later dereferencing
0126  * @ssp: pointer to the srcu_struct, which is used to check that we
0127  *  really are in an SRCU read-side critical section.
0128  *
0129  * Makes rcu_dereference_check() do the dirty work.  If PROVE_RCU
0130  * is enabled, invoking this outside of an RCU read-side critical
0131  * section will result in an RCU-lockdep splat.
0132  */
0133 #define srcu_dereference(p, ssp) srcu_dereference_check((p), (ssp), 0)
0134 
0135 /**
0136  * srcu_dereference_notrace - no tracing and no lockdep calls from here
0137  * @p: the pointer to fetch and protect for later dereferencing
0138  * @ssp: pointer to the srcu_struct, which is used to check that we
0139  *  really are in an SRCU read-side critical section.
0140  */
0141 #define srcu_dereference_notrace(p, ssp) srcu_dereference_check((p), (ssp), 1)
0142 
0143 /**
0144  * srcu_read_lock - register a new reader for an SRCU-protected structure.
0145  * @ssp: srcu_struct in which to register the new reader.
0146  *
0147  * Enter an SRCU read-side critical section.  Note that SRCU read-side
0148  * critical sections may be nested.  However, it is illegal to
0149  * call anything that waits on an SRCU grace period for the same
0150  * srcu_struct, whether directly or indirectly.  Please note that
0151  * one way to indirectly wait on an SRCU grace period is to acquire
0152  * a mutex that is held elsewhere while calling synchronize_srcu() or
0153  * synchronize_srcu_expedited().
0154  *
0155  * Note that srcu_read_lock() and the matching srcu_read_unlock() must
0156  * occur in the same context, for example, it is illegal to invoke
0157  * srcu_read_unlock() in an irq handler if the matching srcu_read_lock()
0158  * was invoked in process context.
0159  */
0160 static inline int srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp)
0161 {
0162     int retval;
0163 
0164     retval = __srcu_read_lock(ssp);
0165     rcu_lock_acquire(&(ssp)->dep_map);
0166     return retval;
0167 }
0168 
0169 /* Used by tracing, cannot be traced and cannot invoke lockdep. */
0170 static inline notrace int
0171 srcu_read_lock_notrace(struct srcu_struct *ssp) __acquires(ssp)
0172 {
0173     int retval;
0174 
0175     retval = __srcu_read_lock(ssp);
0176     return retval;
0177 }
0178 
0179 /**
0180  * srcu_read_unlock - unregister a old reader from an SRCU-protected structure.
0181  * @ssp: srcu_struct in which to unregister the old reader.
0182  * @idx: return value from corresponding srcu_read_lock().
0183  *
0184  * Exit an SRCU read-side critical section.
0185  */
0186 static inline void srcu_read_unlock(struct srcu_struct *ssp, int idx)
0187     __releases(ssp)
0188 {
0189     WARN_ON_ONCE(idx & ~0x1);
0190     rcu_lock_release(&(ssp)->dep_map);
0191     __srcu_read_unlock(ssp, idx);
0192 }
0193 
0194 /* Used by tracing, cannot be traced and cannot call lockdep. */
0195 static inline notrace void
0196 srcu_read_unlock_notrace(struct srcu_struct *ssp, int idx) __releases(ssp)
0197 {
0198     __srcu_read_unlock(ssp, idx);
0199 }
0200 
0201 /**
0202  * smp_mb__after_srcu_read_unlock - ensure full ordering after srcu_read_unlock
0203  *
0204  * Converts the preceding srcu_read_unlock into a two-way memory barrier.
0205  *
0206  * Call this after srcu_read_unlock, to guarantee that all memory operations
0207  * that occur after smp_mb__after_srcu_read_unlock will appear to happen after
0208  * the preceding srcu_read_unlock.
0209  */
0210 static inline void smp_mb__after_srcu_read_unlock(void)
0211 {
0212     /* __srcu_read_unlock has smp_mb() internally so nothing to do here. */
0213 }
0214 
0215 #endif