aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/RCU/listRCU.txt
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@us.ibm.com>2005-05-01 11:59:05 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-01 11:59:05 -0400
commita83f1fe27f7252a2b73b4f22066e92bf99bd595b (patch)
treeb6c4dd485fff268f86f396a85aad88cf29783dcd /Documentation/RCU/listRCU.txt
parentfbd568a3e61a7decb8a754ad952aaa5b5c82e9e5 (diff)
[PATCH] Update RCU documentation
Update the RCU documentation to allow for the new synchronize_rcu() and synchronize_sched() primitives. Fix a few other nits as well. Signed-off-by: Paul E. McKenney <paulmck@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'Documentation/RCU/listRCU.txt')
-rw-r--r--Documentation/RCU/listRCU.txt13
1 files changed, 9 insertions, 4 deletions
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt
index bda6ead69bd0..f8a54fa0d8ab 100644
--- a/Documentation/RCU/listRCU.txt
+++ b/Documentation/RCU/listRCU.txt
@@ -32,6 +32,7 @@ implementation of audit_filter_task() might be as follows:
32 enum audit_state state; 32 enum audit_state state;
33 33
34 read_lock(&auditsc_lock); 34 read_lock(&auditsc_lock);
35 /* Note: audit_netlink_sem held by caller. */
35 list_for_each_entry(e, &audit_tsklist, list) { 36 list_for_each_entry(e, &audit_tsklist, list) {
36 if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { 37 if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
37 read_unlock(&auditsc_lock); 38 read_unlock(&auditsc_lock);
@@ -55,6 +56,7 @@ This means that RCU can be easily applied to the read side, as follows:
55 enum audit_state state; 56 enum audit_state state;
56 57
57 rcu_read_lock(); 58 rcu_read_lock();
59 /* Note: audit_netlink_sem held by caller. */
58 list_for_each_entry_rcu(e, &audit_tsklist, list) { 60 list_for_each_entry_rcu(e, &audit_tsklist, list) {
59 if (audit_filter_rules(tsk, &e->rule, NULL, &state)) { 61 if (audit_filter_rules(tsk, &e->rule, NULL, &state)) {
60 rcu_read_unlock(); 62 rcu_read_unlock();
@@ -139,12 +141,15 @@ Normally, the write_lock() and write_unlock() would be replaced by
139a spin_lock() and a spin_unlock(), but in this case, all callers hold 141a spin_lock() and a spin_unlock(), but in this case, all callers hold
140audit_netlink_sem, so no additional locking is required. The auditsc_lock 142audit_netlink_sem, so no additional locking is required. The auditsc_lock
141can therefore be eliminated, since use of RCU eliminates the need for 143can therefore be eliminated, since use of RCU eliminates the need for
142writers to exclude readers. 144writers to exclude readers. Normally, the write_lock() calls would
145be converted into spin_lock() calls.
143 146
144The list_del(), list_add(), and list_add_tail() primitives have been 147The list_del(), list_add(), and list_add_tail() primitives have been
145replaced by list_del_rcu(), list_add_rcu(), and list_add_tail_rcu(). 148replaced by list_del_rcu(), list_add_rcu(), and list_add_tail_rcu().
146The _rcu() list-manipulation primitives add memory barriers that are 149The _rcu() list-manipulation primitives add memory barriers that are
147needed on weakly ordered CPUs (most of them!). 150needed on weakly ordered CPUs (most of them!). The list_del_rcu()
151primitive omits the pointer poisoning debug-assist code that would
152otherwise cause concurrent readers to fail spectacularly.
148 153
149So, when readers can tolerate stale data and when entries are either added 154So, when readers can tolerate stale data and when entries are either added
150or deleted, without in-place modification, it is very easy to use RCU! 155or deleted, without in-place modification, it is very easy to use RCU!
@@ -166,6 +171,7 @@ otherwise, the added fields would need to be filled in):
166 struct audit_newentry *ne; 171 struct audit_newentry *ne;
167 172
168 write_lock(&auditsc_lock); 173 write_lock(&auditsc_lock);
174 /* Note: audit_netlink_sem held by caller. */
169 list_for_each_entry(e, list, list) { 175 list_for_each_entry(e, list, list) {
170 if (!audit_compare_rule(rule, &e->rule)) { 176 if (!audit_compare_rule(rule, &e->rule)) {
171 e->rule.action = newaction; 177 e->rule.action = newaction;
@@ -199,8 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows:
199 audit_copy_rule(&ne->rule, &e->rule); 205 audit_copy_rule(&ne->rule, &e->rule);
200 ne->rule.action = newaction; 206 ne->rule.action = newaction;
201 ne->rule.file_count = newfield_count; 207 ne->rule.file_count = newfield_count;
202 list_add_rcu(ne, e); 208 list_replace_rcu(e, ne);
203 list_del(e);
204 call_rcu(&e->rcu, audit_free_rule, e); 209 call_rcu(&e->rcu, audit_free_rule, e);
205 return 0; 210 return 0;
206 } 211 }