最近發現由於pci資料傳輸錯誤導致io request得到的資料不正確,這種現象讓我們思考,為什麼系統都已經發現了pci錯誤,io request還能正確結束呢?按照慣例思考,pci傳輸出錯,io request就應該fail掉,但是,事實不是這樣。難道這個問題和pci的中斷非同步有關係?因此,這裡詳細討論一下pci的中斷非同步問題及pci解決辦法。
pci擁有多種資料傳輸模式,post、non-post、delayed以及split方式,為了提高傳輸效率,充分利用匯流排頻寬資源,pci在memory write的時候通常採用post方式。即pci裝置通過dma控制器在向memory寫資料的時候,先將資料提交給bridge的fifo中,然後馬上釋放本級匯流排資源,完成memory寫操作。但實際上此時資料還沒有抵達memory,這是一種典型的非同步寫操作行為。
如上圖所示,裝置2通過dma控制器向記憶體寫資料,當dma將資料post到橋2之後,隨即釋放bus1,完成dma操作,並且向處理器提交dma完成中斷請求。位於處理器端的驅動程式在接收到中斷請求之後呼叫中斷服務程式,但是,此時裝置2寫入的資料可能還沒有抵達記憶體,這就是pci匯流排的「中斷非同步」問題。
計算機系統是如何解決這個中斷非同步問題的呢?其關鍵就在於pci協議規範中定義的「執行序」。對於傳統pci匯流排而言,需要嚴格遵守pci請求的執行順序。在上述問題中,進入驅動程式之後,需要獲取對應裝置的中斷狀態暫存器內容,這是乙個讀操作,這個讀操作會將post在橋2、主橋中的資料最終寫入記憶體。這就是pci匯流排規範遵守的資料一致性原則。
如上圖所示,進入位於處理器的驅動程式之後,裝置驅動會向裝置2傳送中斷狀態暫存器讀request。在pci中,讀操作不能採用post的方式,只能採用non-post、delayed或者split方式。讀request到達主橋或者橋2時,如果存在post到裝置2的資料,那麼主橋或者橋2會將這些post的資料最終重新整理到裝置2,這樣保證後繼讀請求資料的一致性。在資料返回時(藍線路徑),橋2和主橋同樣需要首先將post在那裡的資料寫入記憶體,然後再返回request請求的資料,這樣才能保證資料的一致性。但是,分析到這裡,我們遇到了乙個匯流排互鎖的問題:由於讀請求有可能採用non-post的方式,紅色路徑將無法獲取匯流排控制權,也就無法將資料寫入記憶體;而藍色路徑卻要等待紅色路徑完成之後才能繼續執行,這是典型的匯流排互鎖問題。pci匯流排如何處理上述問題呢?
在pci協議規範中,post寫匯流排事務可以穿越non-post的匯流排事務。例如,主橋在等待non-post匯流排事務,此時橋2仍然可以將資料post寫入到主橋。這種處理方法就可以避免上述匯流排互鎖問題。
通過分析,我們可以知道通過中斷服務程式的讀操作將post到bridge中的資料重新整理到了記憶體方向,等驅動程式訪問dma記憶體時,資料一定已經抵達記憶體了。pci匯流排執行序保證了資料的一致性。
在這裡我們假設橋2或者主橋在將post的資料寫入記憶體時,pci傳輸出現了問題,而產生的這種錯誤會以中斷的形式傳送給處理器。如果系統不對這個中斷進行處理,那麼,從dma記憶體中獲取的資料將會存在data corruption問題,並且上層軟體無法知曉。
本文出自 「儲存之道」 部落格,請務必保留此出處
記錄乙個軟中斷問題
前些天發現xen虛擬機器上的nginx伺服器存在乙個問題 軟中斷過高,而且大部分都集中在同乙個cpu,一旦系統繁忙,此cpu就會成為木桶的短板。在問題伺服器上執行 top 命令可以很明顯看到 si 存在異樣,大部分軟中斷都集中在 1 號cpu上,其它的cpu完全使不上勁兒 shell top cpu...
記錄乙個軟中斷問題
前些天發現xen虛擬機器上的nginx伺服器存在乙個問題 軟中斷過高,而且大部分都集中在同乙個cpu,一旦系統繁忙,此cpu就會成為木桶的短板。在問題伺服器上執行 top 命令可以很明顯看到 si 存在異樣,大部分軟中斷都集中在 1 號cpu上,其它的cpu完全使不上勁兒 shell top cpu...
乙個特殊的中斷 SVCall
簡述 一種由程式進行觸發的中斷,預設開啟 起源 svc 系統服務呼叫,亦簡稱系統呼叫 多用於在作業系統之上的軟體開發中。svc 用於產生系統函式的呼叫請求。例如,作業系統不讓使用者程式直接訪問硬體,而是通過提供一些系統服務函式,使用者程式使用 svc 發出對系統服務函式的呼叫請求,以這種方法呼叫它們...