簡體   English   中英

在local_bh_disable()/ local_bh_enable()中使用rcu_dereference()是否安全?

[英]Is it safe to use rcu_dereference() inside local_bh_disable()/local_bh_enable()?

local_bh_disable -function更改per-cpu(如果是x86和最近的內核) __preempt_countcurrent_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM