標籤:選擇 http 分層 cee imp 調度 nod 相關 git diff
kernel中有兩個rcu的實現,一個是tiny rcu,另一個是tree rcu。這兩種rcu的前身都是classic rcu。
如果要閱讀classic rcu的實現代碼,必須找kernel 2.6.26,因為在kernel 2.6.27,classic rcu開始轉型為使用tree node的scalable classic rcu,是現在的tree rcu趨形。
那麼tiny rcu與classic rcu又是什麼關係呢,tiny如其名,就是緊湊的classic rcu,專門為單cpu(uniproceesor)的嵌入系統(記憶體十分有限)而設計的。換句話說,相當於classic rcu的刪減版。
classic rcu使用全域狀態rcu_ctrblk,提供兩個flaver的全域狀態rcu_sched_ctrblk和rcu_bh_ctrblk。
tiny rcu沿用這兩個全域狀態,並將SMP部分的內容刪減。
tree rcu則是將rcu_ctrblk演化成分層(hierarchical)結構,也就是樹形。全域狀態rcu_state,分層(樹型)節點rcu_node,cpu獨立狀態rcu_data,以及cpu空閑變頻狀態rcu_dynticks。將原本在rcu_ctrblk的cpumask,以分層的方式分置到rcu_node的qsmask。
現在tree rcu包含了許多特性,初涉者不容易在龐大的結構體成員和眾多特性功能的函數邏輯中分離出,與設計文檔描述相吻合的(純淨或原始的)路徑進行研究。
設計文檔中描述了classic rcu就是kernel 2.6.16為止的rcu實現,而tree rcu的趨形就是從kernel 2.6.17開始。如果你對現在的kernel中的rcu實現感到迷惑的話,可以選擇上面提到的兩個版本的kernel的rcu進行比較來研究。
或者你可以參考第一份scalable classic rcu提交的日誌文檔,在LWN網站。文檔以git diff的方式,更好地展現了classic rcu如何向tree rcu演化。
但是你不可能很好地從tiny rcu去研究classic rcu,雖然說tiny rcu是classic rcu的精簡,但是已經將SMP部分實現基本去除(比如qsmask),而tree rcu和classic rcu同是基於SMP的實現。
因此如果你將tiny rcu作為classic rcu去同tree rcu進行比較時,你會根本找不到SMP相關部分的影子,差異巨大而找不出演化的連接點(相關性),從而迷惑。
classic rcu的rcu_ctrblk中有我們熟知的rcu文檔描述的qsmask,用於維護(或感知)一個gp。而tree rcu則是將這個qsmask進行分層,tiny rcu卻是將這個qsmask丟棄。如果你不清楚這一點,當你比較tree rcu和tiny rcu時,中間就會有斷層,聯絡不上。
這是因為tiny rcu限定了單CPU(uniprocessor)的條件。在tiny rcu實現中並沒有任何per cpu變數。並且在cpu提交一次qs的同時,就會發起rcu softirq,換句話說,gp並沒有另外進行維護管理,只是簡單地將gp等同於每次qs的提交。
classic rcu和tree rcu同樣都使用nxtlist和nxttail來維護4段rcu callbacks的 batch處理。而tiny rcu將其精簡為rcucblist,以及donetail和curtail這樣形式的2段rcu batch,並且簡化當中的維護。
當使用者調用synchronize_sched或call_rcu時,同步(或者說是延後)的回調就會鏈到cur段。當調度器scheduler提交一次qs時,就會將cur段的回調納入done段,並發起rcu softirq。當核心kernel處理rcu softirq就會從done段將回調batch處理。
由此我們不容易發現tiny rcu在維護gp和qs。
tiny rcu和tree rcu是classic rcu不同方向的結果,tiny rcu為uniprocessor且資源有限的嵌入場合而去簡化(剦切)了classic rcu,另外tree rcu則是使classic rcu向前朝超級多cpu(在rcu文檔中,a few of hundren表示數百cpu還不值一提,起碼也要成千上萬,當時2008年)的場合,演化更高效更穩定。
kernel 2.6.27是分水嶺,classic rcu向tree rcu演化。tiny rcu和tree rcu同是2008年的產物。
在kconfig中,tree rcu是預設的rcu。如果需要preempt rcu的話,必須使用tree rcu。換句話說,tiny rcu不支援preempt rcu。
《scalable classic RCU implementation》kernel 2.6.27 第一份基於tree node分層的classic rcu代碼提交日誌文檔。
《Hierarchical RCU》
《RCU: The Bloatwatch Edition》tiny rcu的設計文檔。
《Simplifying RCU》kernel 3.11 移去CONFIG_PREEMPT_TINY,即移去preempt tiny rcu。
linux核心的tiny rcu, tree rcu