RCU 概念¶
RCU(讀取-複製更新)背後的基本思想是將破壞性操作分為兩部分:一部分阻止任何人看到正在被破壞的資料項,另一部分實際執行破壞。這兩部分之間必須經過一個“寬限期”,並且這個寬限期必須足夠長,以確保訪問被刪除項的任何讀取者都已經放棄了他們的引用。 例如,從連結列表中受 RCU 保護的刪除將首先從列表中刪除該項,等待寬限期過去,然後釋放該元素。 有關將 RCU 與連結列表一起使用的更多資訊,請參見 使用 RCU 保護主要為讀取操作的連結列表。
常見問題解答¶
為什麼有人想使用 RCU?
RCU 的兩部分方法的優點是,RCU 讀取者無需獲取任何鎖,執行任何原子指令,寫入共享記憶體,或者(在 Alpha 以外的 CPU 上)執行任何記憶體屏障。 事實上,這些操作在現代 CPU 上非常昂貴,這正是 RCU 在主要為讀取操作的情況下具有效能優勢的原因。 RCU 讀取者無需獲取鎖的事實還可以大大簡化避免死鎖的程式碼。
如果 RCU 讀取者沒有指示他們何時完成,那麼更新者如何知道寬限期何時完成?
與自旋鎖一樣,RCU 讀取者不允許阻塞、切換到使用者模式執行或進入空閒迴圈。 因此,一旦看到 CPU 正在經歷這三種狀態中的任何一種,我們就知道該 CPU 已經退出了任何先前的 RCU 讀取端關鍵區域。 因此,如果我們從連結列表中刪除一個專案,然後等待所有 CPU 切換上下文、在使用者模式下執行或在空閒迴圈中執行,我們可以安全地釋放該專案。
RCU 的可搶佔變體 (CONFIG_PREEMPT_RCU) 具有相同的效果,但要求讀取者操作 CPU 本地計數器。 這些計數器允許在 RCU 讀取端關鍵區域內進行有限型別的阻塞。 SRCU 也使用 CPU 本地計數器,並允許在 RCU 讀取端關鍵區域內進行一般阻塞。 RCU 的這些變體透過取樣這些計數器來檢測寬限期。
如果我在單處理器核心上執行,它一次只能做一件事,為什麼我應該等待寬限期?
有關更多資訊,請參見 單處理器系統上的 RCU。
我如何檢視 RCU 當前在 Linux 核心中的使用位置?
搜尋“rcu_read_lock”、“rcu_read_unlock”、“call_rcu”、“rcu_read_lock_bh”、“rcu_read_unlock_bh”、“srcu_read_lock”、“srcu_read_unlock”、“synchronize_rcu”、“synchronize_net”、“synchronize_srcu”和其他 RCU 原語。 或者從以下位置獲取 cscope 資料庫之一
(http://www.rdrop.com/users/paulmck/RCU/linuxusage/rculocktab.html)。
編寫使用 RCU 的程式碼時,我應該遵循哪些準則?
參見 RCU 補丁的審查清單。
為什麼命名為“RCU”?
“RCU”代表“讀取-複製更新”。 使用 RCU 保護主要為讀取操作的連結列表 有關此名稱來源的更多資訊,搜尋“read-copy update”即可找到。
我聽說 RCU 有專利? 那是什麼情況?
是的,它是。 有幾個與 RCU 相關的已知專利,請在 Documentation/RCU/RTFP.txt 中搜索字串“Patent”以找到它們。 其中,一項已被受讓人放棄,其他已被貢獻給 GPL 下的 Linux 核心。 許多(但不是全部)早已過期。 現在還有使用者級 RCU 的 LGPL 實現可用 (https://liburcu.org/)。
我聽說 RCU 需要進行一些工作才能支援即時核心?
透過 CONFIG_PREEMPTION 核心配置引數啟用對即時友好的 RCU。
在哪裡可以找到有關 RCU 的更多資訊?
參見 Documentation/RCU/RTFP.txt 檔案。 或者將您的瀏覽器指向 (https://docs.google.com/document/d/1X0lThx8OK0ZgLMqVoXiR4ZrGURHrXK6NyLRbeXe3Xac/edit) 或 (https://docs.google.com/document/d/1GCdQC8SDbb54W1shjEXqGZ0Rq8a6kIeYutdSIajfpLA/edit?usp=sharing)。