From ba597a286028ecbbbafa0236f7598fb7a34d7002 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Wed, 10 Sep 2008 11:01:07 +0800 Subject: [PATCH] --- yaml --- r: 110781 b: refs/heads/master c: e8aed68614c81f24d8c4cbcb4923f848ece846e1 h: refs/heads/master i: 110779: ff3acc4bf0785573626ad94bdc34f4d45eb9acd2 v: v3 --- [refs] | 2 +- trunk/Documentation/RCU/rcuref.txt | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 73b42895200a..5cf3d9e47e96 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 429b022af41108f6942d72547592b1d30e9a51f0 +refs/heads/master: e8aed68614c81f24d8c4cbcb4923f848ece846e1 diff --git a/trunk/Documentation/RCU/rcuref.txt b/trunk/Documentation/RCU/rcuref.txt index 451de2ad8329..4202ad093130 100644 --- a/trunk/Documentation/RCU/rcuref.txt +++ b/trunk/Documentation/RCU/rcuref.txt @@ -29,9 +29,9 @@ release_referenced() delete() } If this list/array is made lock free using RCU as in changing the -write_lock() in add() and delete() to spin_lock and changing read_lock -in search_and_reference to rcu_read_lock(), the atomic_get in -search_and_reference could potentially hold reference to an element which +write_lock() in add() and delete() to spin_lock() and changing read_lock() +in search_and_reference() to rcu_read_lock(), the atomic_inc() in +search_and_reference() could potentially hold reference to an element which has already been deleted from the list/array. Use atomic_inc_not_zero() in this scenario as follows: @@ -40,20 +40,20 @@ add() search_and_reference() { { alloc_object rcu_read_lock(); ... search_for_element - atomic_set(&el->rc, 1); if (atomic_inc_not_zero(&el->rc)) { - write_lock(&list_lock); rcu_read_unlock(); + atomic_set(&el->rc, 1); if (!atomic_inc_not_zero(&el->rc)) { + spin_lock(&list_lock); rcu_read_unlock(); return FAIL; add_element } ... ... - write_unlock(&list_lock); rcu_read_unlock(); + spin_unlock(&list_lock); rcu_read_unlock(); } } 3. 4. release_referenced() delete() { { - ... write_lock(&list_lock); + ... spin_lock(&list_lock); if (atomic_dec_and_test(&el->rc)) ... call_rcu(&el->head, el_free); delete_element - ... write_unlock(&list_lock); + ... spin_unlock(&list_lock); } ... if (atomic_dec_and_test(&el->rc)) call_rcu(&el->head, el_free);