diff options
| -rw-r--r-- | Documentation/RCU/rcuref.txt | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/Documentation/RCU/rcuref.txt b/Documentation/RCU/rcuref.txt index 451de2ad8329..4202ad093130 100644 --- a/Documentation/RCU/rcuref.txt +++ b/Documentation/RCU/rcuref.txt | |||
| @@ -29,9 +29,9 @@ release_referenced() delete() | |||
| 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_inc() 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. Use atomic_inc_not_zero() | 35 | has already been deleted from the list/array. Use atomic_inc_not_zero() |
| 36 | in this scenario as follows: | 36 | in this scenario as follows: |
| 37 | 37 | ||
| @@ -40,20 +40,20 @@ add() search_and_reference() | |||
| 40 | { { | 40 | { { |
| 41 | alloc_object rcu_read_lock(); | 41 | alloc_object rcu_read_lock(); |
| 42 | ... search_for_element | 42 | ... search_for_element |
| 43 | atomic_set(&el->rc, 1); if (atomic_inc_not_zero(&el->rc)) { | 43 | atomic_set(&el->rc, 1); if (!atomic_inc_not_zero(&el->rc)) { |
| 44 | write_lock(&list_lock); rcu_read_unlock(); | 44 | spin_lock(&list_lock); rcu_read_unlock(); |
| 45 | return FAIL; | 45 | return FAIL; |
| 46 | add_element } | 46 | add_element } |
| 47 | ... ... | 47 | ... ... |
| 48 | write_unlock(&list_lock); rcu_read_unlock(); | 48 | spin_unlock(&list_lock); rcu_read_unlock(); |
| 49 | } } | 49 | } } |
| 50 | 3. 4. | 50 | 3. 4. |
| 51 | release_referenced() delete() | 51 | release_referenced() delete() |
| 52 | { { | 52 | { { |
| 53 | ... write_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); delete_element |
| 56 | ... write_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)) |
| 59 | call_rcu(&el->head, el_free); | 59 | call_rcu(&el->head, el_free); |
