簡體   English   中英

rcu_read_lock和x86-64內存順序

[英]rcu_read_lock and x86-64 memory ordering

在可搶占式SMP內核上, rcu_read_lock編譯以下內容:

current->rcu_read_lock_nesting++;
barrier();

barrier是一個編譯器指令,可編譯為空。

因此,根據英特爾的X86-64內存訂購白皮書:

可能會將舊商店的貨物重新排序到其他位置

為什么實施實際上可以?

請考慮以下情況:

rcu_read_lock();
read_non_atomic_stuff();
rcu_read_unlock();

是什么阻止read_non_atomic_stuff從“ rcu_read_lock ”向前“泄漏”,導致它與在另一個線程中運行的回收代碼同時運行?

對於其他CPU上的觀察者,沒有什么可以阻止這一點。 沒錯, ++商店部分的StoreLoad重新排序可以使它在某些加載后在全局可見。

因此,我們可以得出結論,只有當前在此內核上運行的代碼才會觀察到current->rcu_read_lock_nesting或者通過在此處調度而遠程觸發了該內核上的內存屏障,或者使用了一種專用機制來使所有內核在該內核中執行屏障。處理器間中斷(IPI)的處理程序。 例如,類似於membarrier()用戶空間系統調用。


如果此核心開始運行另一個任務,則可以確保該任務按程序順序查看此任務的操作。 (因為它在同一個內核上,並且一個內核總是按順序查看其自身的操作。)而且,上下文切換可能涉及完整的內存屏障,因此可以在不破壞單線程邏輯的情況下在另一個內核上恢復任務。 (這可以使任何內核在此任務/線程不在任何地方運行時安全地查看rcu_read_lock_nesting 。)

請注意,內核在您的計算機的每個內核上啟動一個RCU任務 例如, ps輸出在我的4c8t四核上顯示[rcuc/0][rcuc/1] ,..., [rcu/7] 大概它們是該設計的重要組成部分,它使讀者可以毫無障礙地等待。

我還沒有研究RCU的全部細節,但是https://www.kernel.org/doc/Documentation/RCU/whatisRCU.txt中的“玩具”示例之一是實現了synchronize_rcu() “經典RCU” for_each_possible_cpu(cpu) run_on(cpu); ,以使回收器在可能已執行RCU操作的每個內核(即每個內核)上執行。 完成此操作后,我們知道在切換過程中某個地方一定已經發生了內存不足的情況。

因此,是的,RCU並沒有遵循經典的方法,在這種方法中,您需要一個完整的內存屏障(包括StoreLoad)來使核心等待直到第一個存儲區可見之后才能進行任何讀取。 RCU避免了讀取路徑中完整內存屏障的開銷。 除了避免爭用外,這是它的主要吸引力之一。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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