linux/Documentation/RCU/rcuref.txt
<<
ptio 23/spa 23/form 23a ptio 2 href="../linux+v3e="7/Documenta4" /RCU/rcuref.txt">ptio 23img src="../.sta4"c/gfx/right.png" alt=">>">pt3/spa pt3spa class="lxr_search">ptioptio 23input typtiohidden" namtionavtarget" ptio 23input typtiotext" namtiosearch" idiosearch">ptio 23butt412typtiosubmit">Searchptio 2Prefs 23/a>pt3/spa io 2 23/div io 2 23form ac4" ="ajax+*" method="post" onsubmit="return false;">pt3input typtiohidden" namtioajax_lookup" idioajax_lookup" pio 2 23/form pio 2 23div class="headingbott4m">
2 213/a>Reference-count design for elements of lists/arrays protected by RCU. 2 223/a>p2 233/a>Reference counting on elements of lists which are protected by tradi4" alp2 243/a>reader/writer spinlocks or semaphores are straightforward:p2 253/a>p2 263/a>1. 2. 2 273/a>add() search_and_reference() 2 283/a>{ { 2 293/a> alloc_object read_lock(&list_lock); 2 274.a> ... search_for_element 2 113/a> at4mic_set(&el->rc, 1); at4mic_inc(&el->rc); 2 123/a> write_lock(&list_lock); ... 2 133/a> add_element read_unlock(&list_lock); 2 144.a> ... ... 2 153/a> write_unlock(&list_lock); } 2 163/a>} 2 173/a>p2 183/a>3. 4. 2 193/a>release_referenced() delete() 2 203/a>{ { 2 214.a> ... write_lock(&list_lock); 2 223/a> at4mic_dec(&el->rc, relfunc) ... 2 234.a> ... delete_element 2 244.a>} write_unlock(&list_lock); 2 253/a> ... 2 263/a> if (at4mic_dec_and_test(&el->rc)) 2 273/a> kfree(el); 2 283/a> ... 2 293/a> } 2 303/a>p2 314.a>If this list/array is made lock free using RCU as in changing thep2 323/a>write_lock() in add() and delete() to spin_lock() and changing read_lock() 2 334.a>in search_and_reference() to rcu_read_lock(), the at4mic_inc() in 2 344.a>search_and_reference() could potentially hold reference to an element which 2 353/a>has already been deleted from the list/array. Use at4mic_inc_not_zero() 2 364.a>in this scenario as follows:p2 373/a>p2 383/a>1. 2. 2 393/a>add() search_and_reference() 2 403/a>{ { 2 413/a> alloc_object rcu_read_lock(); 2 424.a> ... search_for_element 2 433/a> at4mic_set(&el->rc, 1); if (!at4mic_inc_not_zero(&el->rc)) { 2 444.a> spin_lock(&list_lock); rcu_read_unlock(); 2 453/a> return FAIL; 2 463/a> add_element } 2 474.a> ... ... 2 484.a> spin_unlock(&list_lock); rcu_read_unlock(); 2 494.a>} } 2 503/a>3. 4. 2 513/a>release_referenced() delete() 2 523/a>{ { 2 534.a> ... spin_lock(&list_lock); 2 544.a> if (at4mic_dec_and_test(&el->rc)) ... 2 553/a> call_rcu(&el->head, el_free); delete_element 2 564.a> ... spin_unlock(&list_lock); 2 574.a>} ... 2 583/a> if (at4mic_dec_and_test(&el->rc)) 2 593/a> call_rcu(&el->head, el_free);p2 603/a> ... 2 613/a> } 2 623/a>p2 634.a>Sometimes, a reference to the element needs to be obtained in thep2 644.a>update (write) stream. In such cases, at4mic_inc_not_zero() might bep2 653/a>overkill, since we hold the update-side spinlock. One might insteadp2 664.a>use at4mic_inc() in such cases. 2 674.a>
The original LXR software by the LXR community4.a>, this experimental vers2412by lxr@linux.no4.a>. 3/div 3div class="subfooter"> lxr.linux.no kindly hosted by Redpill Linpro AS4.a>, provider of Linux consulting and opera4" s services since 1995. 3/div 3/body 3/html