2014-08-31 42 views
3

任何人都可以解釋爲什麼Linux內核的ext2的功能 int ext2_statfs (struct dentry * dentry, struct kstatfs * buf)內存屏障()

問題smp_rmb()else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { 情況下smp_wmb()

這是在上游內核提交2235219b7721b8e74de6841e79240936561a2b63中添加的,它省略了對.statfs的不必要計算,但無法理解爲什麼添加了內存屏障。

+0

謝謝,添加到kernel.org的鏈接。 – qwerty 2014-08-31 09:52:25

回答

4

由於函數通過做用spin_lock開始(和結束時解鎖),

spin_lock(&sbi->s_lock); 

它被保護,以防止併發訪問。那麼,爲什麼smp_wmbsmp_rmb的需要...

至於寫操作,

sbi->s_overhead_last = overhead; 
    smp_wmb(); 
    sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); 

看來該smp_wmb將防止任何編譯器或處理器的優化(因爲在內存訪問方面,兩個寫入之間沒有依賴關係),這會改變兩個分配的順序。由於在ext2_statfs中沒有併發訪問,所以在可能具有類似行爲的另一個函數中可能會發生問題,並檢查是否存在塊計數更改,如果不存在,則使用sbi->s_overhead_last的開銷 - 如果另一個函數在這個時候,線程將在另一個函數中,在兩個寫入操作的中間以錯誤的順序。

這可能是一種預防措施作爲對SBI性質會用spin_lock它(具有相同的自旋鎖)預先任何類似的寫訪問。而且它增強了這兩個操作必須按此順序完成的事實。

至於讀訪問需要的是不太明顯的,需要進一步分析SBIES塊之間的依賴關係。

+0

很有意義。謝謝你的回答。 – qwerty 2014-08-31 12:05:22

+0

由於自旋鎖確實沒有併發性。然而,前一次執行相同函數(或修改相關數據的其他任何內容)的結果可能對當前的cpu尚不可見。障礙確保此函數始終能夠看到當前狀態(因鎖定而不能更改),並且在釋放鎖定之前結果已提交。 – Jester 2014-08-31 12:14:01

+0

對,你的答案/評論對我來說都很有意義,但是因爲自旋鎖(我相信)對MB有很大影響,所以不應該寫一個類似功能的人(如果檢查和更新)可能在未來只使用相同的原始自旋鎖(超級塊 - >鎖),而不是關心可能已被編譯器優化的排序? – qwerty 2014-08-31 12:43:53