diff options
39 files changed, 1493 insertions, 628 deletions
diff --git a/Documentation/RCU/RTFP.txt b/Documentation/RCU/RTFP.txt index 7c1dfb19fc40..7f40c72a9c51 100644 --- a/Documentation/RCU/RTFP.txt +++ b/Documentation/RCU/RTFP.txt | |||
| @@ -186,7 +186,7 @@ Bibtex Entries | |||
| 186 | 186 | ||
| 187 | @article{Kung80 | 187 | @article{Kung80 |
| 188 | ,author="H. T. Kung and Q. Lehman" | 188 | ,author="H. T. Kung and Q. Lehman" |
| 189 | ,title="Concurrent Maintenance of Binary Search Trees" | 189 | ,title="Concurrent Manipulation of Binary Search Trees" |
| 190 | ,Year="1980" | 190 | ,Year="1980" |
| 191 | ,Month="September" | 191 | ,Month="September" |
| 192 | ,journal="ACM Transactions on Database Systems" | 192 | ,journal="ACM Transactions on Database Systems" |
diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt index cdb20d41a44a..31ef8fe07f82 100644 --- a/Documentation/RCU/checklist.txt +++ b/Documentation/RCU/checklist.txt | |||
| @@ -271,15 +271,14 @@ over a rather long period of time, but improvements are always welcome! | |||
| 271 | The same cautions apply to call_rcu_bh() and call_rcu_sched(). | 271 | The same cautions apply to call_rcu_bh() and call_rcu_sched(). |
| 272 | 272 | ||
| 273 | 9. All RCU list-traversal primitives, which include | 273 | 9. All RCU list-traversal primitives, which include |
| 274 | rcu_dereference(), list_for_each_entry_rcu(), | 274 | rcu_dereference(), list_for_each_entry_rcu(), and |
| 275 | list_for_each_continue_rcu(), and list_for_each_safe_rcu(), | 275 | list_for_each_safe_rcu(), must be either within an RCU read-side |
| 276 | must be either within an RCU read-side critical section or | 276 | critical section or must be protected by appropriate update-side |
| 277 | must be protected by appropriate update-side locks. RCU | 277 | locks. RCU read-side critical sections are delimited by |
| 278 | read-side critical sections are delimited by rcu_read_lock() | 278 | rcu_read_lock() and rcu_read_unlock(), or by similar primitives |
| 279 | and rcu_read_unlock(), or by similar primitives such as | 279 | such as rcu_read_lock_bh() and rcu_read_unlock_bh(), in which |
| 280 | rcu_read_lock_bh() and rcu_read_unlock_bh(), in which case | 280 | case the matching rcu_dereference() primitive must be used in |
| 281 | the matching rcu_dereference() primitive must be used in order | 281 | order to keep lockdep happy, in this case, rcu_dereference_bh(). |
| 282 | to keep lockdep happy, in this case, rcu_dereference_bh(). | ||
| 283 | 282 | ||
| 284 | The reason that it is permissible to use RCU list-traversal | 283 | The reason that it is permissible to use RCU list-traversal |
| 285 | primitives when the update-side lock is held is that doing so | 284 | primitives when the update-side lock is held is that doing so |
diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt index 4349c1487e91..adb5a3782846 100644 --- a/Documentation/RCU/listRCU.txt +++ b/Documentation/RCU/listRCU.txt | |||
| @@ -205,7 +205,7 @@ RCU ("read-copy update") its name. The RCU code is as follows: | |||
| 205 | audit_copy_rule(&ne->rule, &e->rule); | 205 | audit_copy_rule(&ne->rule, &e->rule); |
| 206 | ne->rule.action = newaction; | 206 | ne->rule.action = newaction; |
| 207 | ne->rule.file_count = newfield_count; | 207 | ne->rule.file_count = newfield_count; |
| 208 | list_replace_rcu(e, ne); | 208 | list_replace_rcu(&e->list, &ne->list); |
| 209 | call_rcu(&e->rcu, audit_free_rule); | 209 | call_rcu(&e->rcu, audit_free_rule); |
| 210 | return 0; | 210 | return 0; |
| 211 | } | 211 | } |
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt index 4202ad093130..141d531aa14b 100644 --- a/Documentation/RCU/rcuref.txt +++ b/Documentation/RCU/rcuref.txt | |||
| @@ -20,7 +20,7 @@ release_referenced() delete() | |||
| 20 | { { | 20 | { { |
| 21 | ... write_lock(&list_lock); | 21 | ... write_lock(&list_lock); |
| 22 | atomic_dec(&el->rc, relfunc) ... | 22 | atomic_dec(&el->rc, relfunc) ... |
| 23 | ... delete_element | 23 | ... remove_element |
| 24 | } write_unlock(&list_lock); | 24 | } write_unlock(&list_lock); |
| 25 | ... | 25 | ... |
| 26 | if (atomic_dec_and_test(&el->rc)) | 26 | if (atomic_dec_and_test(&el->rc)) |
| @@ -52,7 +52,7 @@ release_referenced() delete() | |||
| 52 | { { | 52 | { { |
| 53 | ... spin_lock(&list_lock); | 53 | ... spin_lock(&list_lock); |
| 54 | if (atomic_dec_and_test(&el->rc)) ... | 54 | if (atomic_dec_and_test(&el->rc)) ... |
| 55 | call_rcu(&el->head, el_free); delete_element | 55 | call_rcu(&el->head, el_free); remove_element |
| 56 | ... spin_unlock(&list_lock); | 56 | ... spin_unlock(&list_lock); |
| 57 | } ... | 57 | } ... |
| 58 | if (atomic_dec_and_test(&el->rc)) | 58 | if (atomic_dec_and_test(&el->rc)) |
| @@ -64,3 +64,60 @@ Sometimes, a reference to the element needs to be obtained in the | |||
| 64 | update (write) stream. In such cases, atomic_inc_not_zero() might be | 64 | update (write) stream. In such cases, atomic_inc_not_zero() might be |
| 65 | overkill, since we hold the update-side spinlock. One might instead | 65 | overkill, since we hold the update-side spinlock. One might instead |
| 66 | use atomic_inc() in such cases. | 66 | use atomic_inc() in such cases. |
| 67 | |||
| 68 | It is not always convenient to deal with "FAIL" in the | ||
| 69 | search_and_reference() code path. In such cases, the | ||
| 70 | atomic_dec_and_test() may be moved from delete() to el_free() | ||
| 71 | as follows: | ||
| 72 | |||
| 73 | 1. 2. | ||
| 74 | add() search_and_reference() | ||
| 75 | { { | ||
| 76 | alloc_object rcu_read_lock(); | ||
| 77 | ... search_for_element | ||
| 78 | atomic_set(&el->rc, 1); atomic_inc(&el->rc); | ||
| 79 | spin_lock(&list_lock); ... | ||
| 80 | |||
| 81 | add_element rcu_read_unlock(); | ||
| 82 | ... } | ||
| 83 | spin_unlock(&list_lock); 4. | ||
| 84 | } delete() | ||
| 85 | 3. { | ||
| 86 | release_referenced() spin_lock(&list_lock); | ||
| 87 | { ... | ||
| 88 | ... remove_element | ||
| 89 | if (atomic_dec_and_test(&el->rc)) spin_unlock(&list_lock); | ||
| 90 | kfree(el); ... | ||
| 91 | ... call_rcu(&el->head, el_free); | ||
| 92 | } ... | ||
| 93 | 5. } | ||
| 94 | void el_free(struct rcu_head *rhp) | ||
| 95 | { | ||
| 96 | release_referenced(); | ||
| 97 | } | ||
| 98 | |||
| 99 | The key point is that the initial reference added by add() is not removed | ||
| 100 | until after a grace period has elapsed following removal. This means that | ||
| 101 | search_and_reference() cannot find this element, which means that the value | ||
| 102 | of el->rc cannot increase. Thus, once it reaches zero, there are no | ||
| 103 | readers that can or ever will be able to reference the element. The | ||
| 104 | element can therefore safely be freed. This in turn guarantees that if | ||
| 105 | any reader finds the element, that reader may safely acquire a reference | ||
| 106 | without checking the value of the reference counter. | ||
| 107 | |||
| 108 | In cases where delete() can sleep, synchronize_rcu() can be called from | ||
| 109 | delete(), so that el_free() can be subsumed into delete as follows: | ||
| 110 | |||
| 111 | 4. | ||
| 112 | delete() | ||
| 113 | { | ||
| 114 | spin_lock(&list_lock); | ||
