Linux核心中的RCU機制
RCU的設計思想比較明確,通過新老指標替換的方式來實現免鎖方式的共享保護。但是具體到程式碼的層面,理解起來多少還是會有些困難。下面小編準備了關於Linux核心中的RCU機制的文章,提供給大家參考!
RCU讀取側進入臨界區的標誌是呼叫rcu_read_lock,這個函式的程式碼是:
static inline void rcu_read_lock(void)
{
__rcu_read_lock();
__acquire(RCU);
rcu_read_acquire();
}
該實現裡面貌似有三個函式呼叫,但實質性的工作由第一個函式__rcu_read_lock()來完成,__rcu_read_lock()通過呼叫 preempt_disable()關閉核心可搶佔性。但是中斷是允許的,假設讀取者正處於rcu臨界區中且剛讀取了一個共享資料區的指標p(但是還沒有訪問p中的資料成員),發生了一箇中斷,而該中斷處理例程ISR恰好需要修改p所指向的資料區,按照RCU的設計原則,ISR會新分配一個同樣大小的資料區new_p,再把老資料區p中的資料拷貝到新資料區,接著是在new_p的基礎上做資料修改的工作(因為是在new_p空間中修改,所以不存在對p的併發訪問,因此說RCU是一種免鎖機制,原因就在這裡),ISR在把資料更新的工作完成後,將new_p賦值給p(p=new_p),最後它會再註冊一個回撥函式用以在適當的時候釋放老指標p。因此,只要對老指標p上的所有引用都結束了,釋放p就不會有問題。當中斷處理例程做完這些工作返回後,被中斷的程序將依然訪問到p空間上的資料,也就是老資料,這樣的結果是RCU機制所允許的。RCU規則對讀取者與寫入者之間因指標切換所造成的短暫的資源檢視不一致問題是允許的。
接下來關於RCU一個有趣的問題是:何時才能釋放老指標。我見過很多書中對此的回答是:當系統中所有處理器上都發生了一次程序切換。這種程式化的回答常常讓剛接觸RCU機制的讀者感到一頭霧水,為什麼非要等所有處理器上都發生一次程序切換才可以呼叫回撥函式釋放老指標呢?這其實是RCU的設計規則決定的: 所有對老指標的引用只可能發生在rcu_read_lock與rcu_read_unlock所包括的臨界區中,而在這個臨界區中不可能發生程序切換,而一旦出了該臨界區就不應該再有任何形式的對老指標p的引用。很明顯,這個規則要求讀取者在臨界區中不能發生程序切換,因為一旦有程序切換,釋放老指標的回撥函式就有可能被呼叫,從而導致老指標被釋放掉,當被切換掉的程序被重新排程執行時它就有可能引用到一個被釋放掉的記憶體空間。
現在我們看到為什麼rcu_read_lock只需要關閉核心可搶佔性就可以了,因為它使得即便在臨界區中發生了中斷,當前程序也不可能被切換除去。 核心開發者,確切地說,RCU的設計者所能做的只能到這個程度。接下來就是使用者的責任了,如果在rcu的臨界區中呼叫了一個函式,該函式可能睡眠,那麼RCU的設計規則就遭到了破壞,系統將進入一種不穩定的狀態。
這再次說明,如果想使用一個東西,一定要搞清楚其內在的機制,象上面剛提到的那個例子,即便現在程式不出現問題,但是系統中留下的隱患如同一個定時炸彈, 隨時可能被引爆,尤其是過了很長時間問題才突然爆發出來。絕大多數情形下,找到問題所花費的時間可能要遠遠大於靜下心來仔細搞懂RCU的原理要多得多。
RCU中的讀取者相對rwlock的讀取者而言,自由度更高。因為RCU的讀取者在訪問一個共享資源時,不需要考慮寫入者的感受,這不同於rwlock的寫入者,rwlock reader在讀取共享資源時需要確保沒有寫入者在操作該資源。兩者之間的差異化源自RCU對共享資源在讀取者與寫入者之間進行了分離,而rwlock的 讀取者和寫入者則至始至終只使用共享資源的一份拷貝。這也意味著RCU中的.寫入者要承擔更多的責任,而且對同一共享資源進行更新的多個寫入者之間必須引入某種互斥機制,所以RCU屬於一種"免鎖機制"的說法僅限於讀取者與寫入者之間。所以我們看到:RCU機制應該用在有大量的讀取操作,而更新操作相對較少的情形下。此時RCU可以大大提升系統系能,因為RCU的讀取操作相對其他一些有鎖機制而言,在鎖上的開銷幾乎沒有。
實際使用中,共享的資源常常以連結串列的形式存在,核心為RCU模式下的連結串列操作實現了幾個介面函式,讀取者和使用者應該使用這些核心函式,比如 list_add_tail_rcu, list_add_rcu,hlist_replace_rcu等等,具體的使用可以參考某些核心程式設計或者裝置驅動程式方面的資料。
在釋放老指標方面,Linux核心提供兩種方法供使用者使用,一個是呼叫call_rcu,另一個是呼叫synchronize_rcu。前者是一種非同步 方式,call_rcu會將釋放老指標的回撥函式放入一個結點中,然後將該結點加入到當前正在執行call_rcu的處理器的本地連結串列中,在時鐘中斷的 softirq部分(RCU_SOFTIRQ), rcu軟中斷處理函式rcu_process_callbacks會檢查當前處理器是否經歷了一個休眠期(quiescent,此處涉及核心程序排程等方面的內容),rcu的核心程式碼實現在確定系統中所有的處理器都經歷過了一個休眠期之後(意味著所有處理器上都發生了一次程序切換,因此老指標此時可以被安全釋放掉了),將呼叫call_rcu提供的回撥函式。
synchronize_rcu的實現則利用了等待佇列,在它的實現過程中也會向call_rcu那樣向當前處理器的本地連結串列中加入一個結點,與 call_rcu不同之處在於該結點中的回撥函式是wakeme_after_rcu,然後synchronize_rcu將在一個等待佇列中睡眠,直到系統中所有處理器都發生了一次程序切換,因而wakeme_after_rcu被rcu_process_callbacks所呼叫以喚醒睡眠的 synchronize_rcu,被喚醒之後,synchronize_rcu知道它現在可以釋放老指標了。
所以我們看到,call_rcu返回後其註冊的回撥函式可能還沒被呼叫,因而也就意味著老指標還未被釋放,而synchronize_rcu返回後老指標肯定被釋放了。所以,是呼叫call_rcu還是synchronize_rcu,要視特定需求與當前上下文而定,比如中斷處理的上下文肯定不能使用 synchronize_rcu函數了。
相關文章
-
Linux中source命令的用法
一張很舊的翻拍照片,按照照片原型創作的人偶組合主要材料:超輕粘土樹脂黏土所需工具:工具套製作步驟:第1步:先來張原圖第2步:男主腦袋第3步:女主腦袋第4步:男主和女主第5步:男身體第6步:女身體第7步:女身體繼續第8步:裙子第9步:組 -
託福英語寫作範文:Examinations exert a pernicious influence on educat
We might marvel at the progress made in every field of study, but the methods of testing a person’s knowledge and ability remain as primitive as ever they were. It really is extraordinary that after -
安裝和使用Linux CURL的方法
蛋卷頭髮型緊緻的髮捲在女生的兩側肩頭堆積,營造出十足的造型感。蓬鬆外擴的髮型線條反襯出精緻小巧的臉型,秀美可人的氣質被凸現出來。厚厚的齊劉海覆蓋雙眉,整個人顯得乖巧可人,再加上藍色髮箍的點綴,時尚又清麗的一款發 -
linux中php如何安裝CURL
如果php已經在系統編譯好,後來又需要新增新的擴充套件。一種方式就是重新完全編譯php,另一種方式就是單獨編譯擴充套件庫,以extension的形式擴充套件。下面以安裝curl擴充套件為例:1、下載curl安裝包。./configuremakephp要求curl的目錄要 -
最新的美文欣賞:Why American Culture is Unique
American culture is unique because it is nurtured, formed and developed under certain conditions, which are characteristically(特性)American. The major factors contributing to the making of this new n -
英語的美文:Why American Culture is Unique
American culture is unique because it is nurtured, formed and developed under certain conditions, which are characteristically(特性)American. The major factors contributing to the making of this new n -
Ubuntu Linux系統下設定Static IP的方法
斜劉海精緻盤發精緻而光滑的盤發,利落的劉海,將自己完美的臉型展現在人們的視線,以最簡單的方法打造出職業女性的特有氣質。給人一種幹練,穩重又不失柔美的獨特魅力。棕色斜劉海大波捲髮棕色給人以成熟的感覺,大波捲髮給人 -
快速修復一個panic的Linux核心的技巧
我做的櫻花主要材料:彩紙 1所需工具:剪刀製作步驟:第1步:第2步:第3步:第4步:第5步:第6步:第7步:第8步:第9步:第10步:第11步:第12步:第13步:第14步:第15步:第16步:第17步:第18步:第19步:第20步:第21步:第22步:第23步:第24步:第25步:第26步:第27步: -
Linux如何禁止系統核心Kernel自動升級
Keel是系統核心,Linux系統在進行升級的時候核心也會跟著更新,有時為了避免不必要的麻煩,不少使用者會選擇不升級Linux核心,那麼要如何禁止Keel升級呢?不過在更新其他軟體包時,如果依賴最新的核心,那麼該軟體包是沒法更新成功 -
文化遺蹟Unit1 Cultural relics英語作文
假如你是李華,最近,你的美國筆友莎莉(Sally)發郵件說想到你居住的'城市北京來旅遊,希望你給她簡單介紹一下這座城市。請根據以下要點提示,給她回一封電子郵件。1. 歷史悠久;2. 名勝古蹟眾多(places of interest) ;3. 可以品