aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/RCU/rcuref.txt
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/RCU/rcuref.txt')
-rw-r--r--Documentation/RCU/rcuref.txt31
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 @@
1Refcounter design for elements of lists/arrays protected by RCU. 1Reference-count design for elements of lists/arrays protected by RCU.
2 2
3Refcounting on elements of lists which are protected by traditional 3Reference counting on elements of lists which are protected by traditional
4reader/writer spinlocks or semaphores are straight forward as in: 4reader/writer spinlocks or semaphores are straightforward:
5 5
61. 2. 61. 2.
7add() search_and_reference() 7add() search_and_reference()
@@ -28,12 +28,12 @@ release_referenced() delete()
28 ... 28 ...
29 } 29 }
30 30
31If this list/array is made lock free using rcu as in changing the 31If this list/array is made lock free using RCU as in changing the
32write_lock in add() and delete() to spin_lock and changing read_lock 32write_lock() in add() and delete() to spin_lock and changing read_lock
33in search_and_reference to rcu_read_lock(), the atomic_get in 33in search_and_reference to rcu_read_lock(), the atomic_get in
34search_and_reference could potentially hold reference to an element which 34search_and_reference could potentially hold reference to an element which
35has already been deleted from the list/array. atomic_inc_not_zero takes 35has already been deleted from the list/array. Use atomic_inc_not_zero()
36care of this scenario. search_and_reference should look as; 36in this scenario as follows:
37 37
381. 2. 381. 2.
39add() search_and_reference() 39add() search_and_reference()
@@ -51,17 +51,16 @@ add() search_and_reference()
51release_referenced() delete() 51release_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
63Sometimes, reference to the element need to be obtained in the 63Sometimes, a reference to the element needs to be obtained in the
64update (write) stream. In such cases, atomic_inc_not_zero might be an 64update (write) stream. In such cases, atomic_inc_not_zero() might be
65overkill since the spinlock serialising list updates are held. atomic_inc 65overkill, since we hold the update-side spinlock. One might instead
66is to be used in such cases. 66use atomic_inc() in such cases.
67