[英]Is it safe to use rcu_dereference() inside local_bh_disable()/local_bh_enable()?
local_bh_disable
-function更改per-cpu(如果是x86和最近的內核) __preempt_count
或current_thread_info()->preempt_count
否則。
無論如何,這給了我們寬限期,所以我們可以假設在local_bh_disable()
執行rcu_read_lock()
是多余的。 確實: 在早期的內核中,我們可以看到 local_bh_disable()
用於RCU, rcu_dereference()
隨后在例如dev_queue_xmit
rcu_dereference()
中被dev_queue_xmit
。 后來local_bh_disable()
被替換為rcu_read_lock_bh()
,最終變得比調用local_bh_disable()
更復雜一些。 現在它看起來像這樣:
static inline void rcu_read_lock_bh(void)
{
local_bh_disable();
__acquire(RCU_BH);
rcu_lock_acquire(&rcu_bh_lock_map);
RCU_LOCKDEP_WARN(!rcu_is_watching(),"rcu_read_lock_bh() used illegally while idle");
}
此外,還有足夠的文章描述了RCU API。 在這里我們可以看到:
您是否需要處理NMI處理程序,hardirq處理程序和禁用搶占的代碼段(無論是通過preempt_disable(),local_irq_save(),local_bh_disable()還是其他一些機制),就像它們是顯式RCU讀取器一樣? 如果是這樣,RCU-sched是唯一適合您的選擇。
這告訴我們在這種情況下使用RCU Sched API ,因此rcu_dereference_sched()
應該有所幫助。 從這個全面的表中我們可以發現rcu_dereference()
只能在rcu_read_lock
/ rcu_read_unlock
-markers中使用。
但是,它還不夠清楚。 我可以在local_bh_disable
/ local_bh_enable
-markers中使用(在現代內核的情況下) rcu_dereference()
而不會出現任何錯誤嗎?
PS在我的情況下,我無法更改調用local_bh_disable
的代碼來調用例如rcu_read_lock_bh
,所以我的代碼運行已經禁用了bh。 還使用通常的RCU API。 因此,它充滿了嵌套在local_bh_disable
rcu_read_lock
。
您不應該混合使用API。 如果需要使用RCU-bh API,則需要使用rcu_dereference_bh
。
你可以看到,如果你在rcu_read_lock_bh
之后調用了rcu_dereference_check
,它會正確推測它不會在RCU讀取端關鍵部分調用 ; lock_is_held(&rcu_lock_map)
的調用與lock_is_held(&rcu_lock_map)
進行rcu_lock_acquire(&rcu_bh_lock_map);
在上面的代碼段中。
對於RCU內核文件在這里 (搜索的“rcu_dereference()”一節)給出了正確用法的一個明顯的例子; rcu_dereference*
只能在相應的rcu_read_lock*
函數完成后才能正確調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.