aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/srcu.h
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-10-09 18:13:11 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2011-12-11 13:31:40 -0500
commit0c53dd8b31404c1d7fd15be8f065ebaec615a562 (patch)
treea12d5ced107fed7a6cdc3a82525d328de9b9d9f3 /include/linux/srcu.h
parenta7b152d5342c06e81ab0cf7d18345f69fa7e56b5 (diff)
rcu: Introduce raw SRCU read-side primitives
The RCU implementations, including SRCU, are designed to be used in a lock-like fashion, so that the read-side lock and unlock primitives must execute in the same context for any given read-side critical section. This constraint is enforced by lockdep-RCU. However, there is a need to enter an SRCU read-side critical section within the context of an exception and then exit in the context of the task that encountered the exception. The cost of this capability is that the read-side operations incur the overhead of disabling interrupts. Note that although the current implementation allows a given read-side critical section to be entered by one task and then exited by another, all known possible implementations that allow this have scalability problems. Therefore, a given read-side critical section must be exited by the same task that entered it, though perhaps from an interrupt or exception handler running within that task's context. But if you are thinking in terms of interrupt handlers, make sure that you have considered the possibility of threaded interrupt handlers. Credit goes to Peter Zijlstra for suggesting use of the existing _raw suffix to indicate disabling lockdep over the earlier "bulkref" names. Requested-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Tested-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Diffstat (limited to 'include/linux/srcu.h')
-rw-r--r--include/linux/srcu.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index d4b12443b2ef..1eb520cd1680 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -181,4 +181,47 @@ static inline void srcu_read_unlock(struct srcu_struct *sp, int idx)
181 __srcu_read_unlock(sp, idx); 181 __srcu_read_unlock(sp, idx);
182} 182}
183 183
184/**
185 * srcu_read_lock_raw - register a new reader for an SRCU-protected structure.
186 * @sp: srcu_struct in which to register the new reader.
187 *
188 * Enter an SRCU read-side critical section. Similar to srcu_read_lock(),
189 * but avoids the RCU-lockdep checking. This means that it is legal to
190 * use srcu_read_lock_raw() in one context, for example, in an exception
191 * handler, and then have the matching srcu_read_unlock_raw() in another
192 * context, for example in the task that took the exception.
193 *
194 * However, the entire SRCU read-side critical section must reside within a
195 * single task. For example, beware of using srcu_read_lock_raw() in
196 * a device interrupt handler and srcu_read_unlock() in the interrupted
197 * task: This will not work if interrupts are threaded.
198 */
199static inline int srcu_read_lock_raw(struct srcu_struct *sp)
200{
201 unsigned long flags;
202 int ret;
203
204 local_irq_save(flags);
205 ret = __srcu_read_lock(sp);
206 local_irq_restore(flags);
207 return ret;
208}
209
210/**
211 * srcu_read_unlock_raw - unregister reader from an SRCU-protected structure.
212 * @sp: srcu_struct in which to unregister the old reader.
213 * @idx: return value from corresponding srcu_read_lock_raw().
214 *
215 * Exit an SRCU read-side critical section without lockdep-RCU checking.
216 * See srcu_read_lock_raw() for more details.
217 */
218static inline void srcu_read_unlock_raw(struct srcu_struct *sp, int idx)
219{
220 unsigned long flags;
221
222 local_irq_save(flags);
223 __srcu_read_unlock(sp, idx);
224 local_irq_restore(flags);
225}
226
184#endif 227#endif