diff options
Diffstat (limited to 'Documentation/RCU/rcuref.txt')
-rw-r--r-- | Documentation/RCU/rcuref.txt | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt index 3f60db41b2f0..451de2ad8329 100644 --- a/Documentation/RCU/rcuref.txt +++ b/Documentation/RCU/rcuref.txt | |||
@@ -1,7 +1,7 @@ | |||
1 | Refcounter design for elements of lists/arrays protected by RCU. | 1 | Reference-count design for elements of lists/arrays protected by RCU. |
2 | 2 | ||
3 | Refcounting on elements of lists which are protected by traditional | 3 | Reference counting on elements of lists which are protected by traditional |
4 | reader/writer spinlocks or semaphores are straight forward as in: | 4 | reader/writer spinlocks or semaphores are straightforward: |
5 | 5 | ||
6 | 1. 2. | 6 | 1. 2. |
7 | add() search_and_reference() | 7 | add() search_and_reference() |
@@ -28,12 +28,12 @@ release_referenced() delete() | |||
28 | ... | 28 | ... |
29 | } | 29 | } |
30 | 30 | ||
31 | If this list/array is made lock free using rcu as in changing the | 31 | If this list/array is made lock free using RCU as in changing the |
32 | write_lock in add() and delete() to spin_lock and changing read_lock | 32 | write_lock() in add() and delete() to spin_lock and changing read_lock |
33 | in search_and_reference to rcu_read_lock(), the atomic_get in | 33 | in search_and_reference to rcu_read_lock(), the atomic_get in |
34 | search_and_reference could potentially hold reference to an element which | 34 | search_and_reference could potentially hold reference to an element which |
35 | has already been deleted from the list/array. atomic_inc_not_zero takes | 35 | has already been deleted from the list/array. Use atomic_inc_not_zero() |
36 | care of this scenario. search_and_reference should look as; | 36 | in this scenario as follows: |
37 | 37 | ||
38 | 1. 2. | 38 | 1. 2. |
39 | add() search_and_reference() | 39 | add() search_and_reference() |
@@ -51,17 +51,16 @@ add() search_and_reference() | |||
51 | release_referenced() delete() | 51 | release_referenced() delete() |
52 | { { | 52 | { { |
53 | ... write_lock(&list_lock); | 53 | ... write_lock(&list_lock); |
54 | atomic_dec(&el->rc, relfunc) ... | 54 | if (atomic_dec_and_test(&el->rc)) ... |
55 | ... delete_element | 55 | call_rcu(&el->head, el_free); delete_element |
56 | } write_unlock(&list_lock); | 56 | ... write_unlock(&list_lock); |
57 | ... | 57 | } ... |
58 | if (atomic_dec_and_test(&el->rc)) | 58 | if (atomic_dec_and_test(&el->rc)) |
59 | call_rcu(&el->head, el_free); | 59 | call_rcu(&el->head, el_free); |
60 | ... | 60 | ... |
61 | } | 61 | } |
62 | 62 | ||
63 | Sometimes, reference to the element need to be obtained in the | 63 | 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 an | 64 | update (write) stream. In such cases, atomic_inc_not_zero() might be |
65 | overkill since the spinlock serialising list updates are held. atomic_inc | 65 | overkill, since we hold the update-side spinlock. One might instead |
66 | is to be used in such cases. | 66 | use atomic_inc() in such cases. |
67 | |||