aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@us.ibm.com>2006-10-04 05:17:02 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:30 -0400
commit621934ee7ed5b073c7fd638b347e632c53572761 (patch)
tree5722f9cda22c099ad60545f963410dcbc762ee65 /Documentation
parent95d77884c77beed676036d2f74d10b470a483c63 (diff)
[PATCH] srcu-3: RCU variant permitting read-side blocking
Updated patch adding a variant of RCU that permits sleeping in read-side critical sections. SRCU is as follows: o Each use of SRCU creates its own srcu_struct, and each srcu_struct has its own set of grace periods. This is critical, as it prevents one subsystem with a blocking reader from holding up SRCU grace periods for other subsystems. o The SRCU primitives (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu()) all take a pointer to a srcu_struct. o The SRCU primitives must be called from process context. o srcu_read_lock() returns an int that must be passed to the matching srcu_read_unlock(). Realtime RCU avoids the need for this by storing the state in the task struct, but SRCU needs to allow a given code path to pass through multiple SRCU domains -- storing state in the task struct would therefore require either arbitrary space in the task struct or arbitrary limits on SRCU nesting. So I kicked the state-storage problem up to the caller. Of course, it is not permitted to call synchronize_srcu() while in an SRCU read-side critical section. o There is no call_srcu(). It would not be hard to implement one, but it seems like too easy a way to OOM the system. (Hey, we have enough trouble with call_rcu(), which does -not- permit readers to sleep!!!) So, if you want it, please tell me why... [josht@us.ibm.com: sparse notation] Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> Signed-off-by: Josh Triplett <josh@freedesktop.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/RCU/checklist.txt38
-rw-r--r--Documentation/RCU/rcu.txt3
-rw-r--r--Documentation/RCU/whatisRCU.txt3
3 files changed, 43 insertions, 1 deletions
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
index 1d50cf0c905e..f4dffadbcb00 100644
--- a/Documentation/RCU/checklist.txt
+++ b/Documentation/RCU/checklist.txt
@@ -221,3 +221,41 @@ over a rather long period of time, but improvements are always welcome!
221 disable irq on a given acquisition of that lock will result in 221 disable irq on a given acquisition of that lock will result in
222 deadlock as soon as the RCU callback happens to interrupt that 222 deadlock as soon as the RCU callback happens to interrupt that
223 acquisition's critical section. 223 acquisition's critical section.
224
22513. SRCU (srcu_read_lock(), srcu_read_unlock(), and synchronize_srcu())
226 may only be invoked from process context. Unlike other forms of
227 RCU, it -is- permissible to block in an SRCU read-side critical
228 section (demarked by srcu_read_lock() and srcu_read_unlock()),
229 hence the "SRCU": "sleepable RCU". Please note that if you
230 don't need to sleep in read-side critical sections, you should
231 be using RCU rather than SRCU, because RCU is almost always
232 faster and easier to use than is SRCU.
233
234 Also unlike other forms of RCU, explicit initialization
235 and cleanup is required via init_srcu_struct() and
236 cleanup_srcu_struct(). These are passed a "struct srcu_struct"
237 that defines the scope of a given SRCU domain. Once initialized,
238 the srcu_struct is passed to srcu_read_lock(), srcu_read_unlock()
239 and synchronize_srcu(). A given synchronize_srcu() waits only
240 for SRCU read-side critical sections governed by srcu_read_lock()
241 and srcu_read_unlock() calls that have been passd the same
242 srcu_struct. This property is what makes sleeping read-side
243 critical sections tolerable -- a given subsystem delays only
244 its own updates, not those of other subsystems using SRCU.
245 Therefore, SRCU is less prone to OOM the system than RCU would
246 be if RCU's read-side critical sections were permitted to
247 sleep.
248
249 The ability to sleep in read-side critical sections does not
250 come for free. First, corresponding srcu_read_lock() and
251 srcu_read_unlock() calls must be passed the same srcu_struct.
252 Second, grace-period-detection overhead is amortized only
253 over those updates sharing a given srcu_struct, rather than
254 being globally amortized as they are for other forms of RCU.
255 Therefore, SRCU should be used in preference to rw_semaphore
256 only in extremely read-intensive situations, or in situations
257 requiring SRCU's read-side deadlock immunity or low read-side
258 realtime latency.
259
260 Note that, rcu_assign_pointer() and rcu_dereference() relate to
261 SRCU just as they do to other forms of RCU.
diff --git a/Documentation/RCU/rcu.txt b/Documentation/RCU/rcu.txt
index 02e27bf1d365..f84407cba816 100644
--- a/Documentation/RCU/rcu.txt
+++ b/Documentation/RCU/rcu.txt
@@ -45,7 +45,8 @@ o How can I see where RCU is currently used in the Linux kernel?
45 45
46 Search for "rcu_read_lock", "rcu_read_unlock", "call_rcu", 46 Search for "rcu_read_lock", "rcu_read_unlock", "call_rcu",
47 "rcu_read_lock_bh", "rcu_read_unlock_bh", "call_rcu_bh", 47 "rcu_read_lock_bh", "rcu_read_unlock_bh", "call_rcu_bh",
48 "synchronize_rcu", and "synchronize_net". 48 "srcu_read_lock", "srcu_read_unlock", "synchronize_rcu",
49 "synchronize_net", and "synchronize_srcu".
49 50
50o What guidelines should I follow when writing code that uses RCU? 51o What guidelines should I follow when writing code that uses RCU?
51 52
diff --git a/Documentation/RCU/whatisRCU.txt b/Documentation/RCU/whatisRCU.txt
index 820fee236967..e0d6d99b8f9b 100644
--- a/Documentation/RCU/whatisRCU.txt
+++ b/Documentation/RCU/whatisRCU.txt
@@ -778,6 +778,8 @@ Markers for RCU read-side critical sections:
778 rcu_read_unlock 778 rcu_read_unlock
779 rcu_read_lock_bh 779 rcu_read_lock_bh
780 rcu_read_unlock_bh 780 rcu_read_unlock_bh
781 srcu_read_lock
782 srcu_read_unlock
781 783
782RCU pointer/list traversal: 784RCU pointer/list traversal:
783 785
@@ -804,6 +806,7 @@ RCU grace period:
804 synchronize_net 806 synchronize_net
805 synchronize_sched 807 synchronize_sched
806 synchronize_rcu 808 synchronize_rcu
809 synchronize_srcu
807 call_rcu 810 call_rcu
808 call_rcu_bh 811 call_rcu_bh
809 812