1. 程式人生 > >模組復位的基本邏輯

模組復位的基本邏輯

basic logic of reset

-v0.1 2018.9.16 Sherlock init

裝置復位的功能,需要軟硬體一起聯合起來考慮。本文試圖梳理下要給一個linux裝置驅動 加上覆位功能需要考慮的基本邏輯。本文只從邏輯的層面給出我的認識,不涉及具體的 硬體和軟體驅動。

首先我們對這個裝置做出一些基本的假設。這個裝置是一個PCIe裝置,這個裝置有多個PF, 一個PF又有多個附帶的VF。每個function上又有很多可以獨立工作的部件,比如很多佇列。 這個裝置可以工作在核心態,也可以工作在使用者態, 也可以工作在虛擬機器的核心態。

復位可以是整個裝置的復位,我們稱之為全域性復位。全域性復位發生的時候,這個裝置上的 PF和VF都要被複位。復位也可以是function級別的,比如一個PF或者VF單獨復位,其他 function的功能不受到影響, 我們把這種復位叫function復位,因為我們討論的是PCIe 裝置,這裡也就是FLR。當然邏輯上,我們還有function裡獨立工作部件的復位,比如佇列 的復位。

我們現在對復位做更清楚的定義。一般, 復位是對裝置迴歸初始狀態的操作,但它迴歸到的 狀態不是剛剛上電的狀態。使用者在使用裝置的時候,一般會先做一些初始的配置,比如, enable幾個VF, 配置一些佇列的資源。這些配置在上下電或者驅動加解除安裝的時候要清除。 但是,在復位的時候,我們希望保留這些配置。一般需要復位的時候為系統發生了錯誤,無 法繼續執行,復位只是叫系統回覆之前可以執行的狀態,清除使用者之前的配置是不合適的。

所以,各種復位首先要考慮的問題是,是否需要保留使用者配置,怎麼保留,在復位完成後 怎麼恢復這些配置。

我們還需要考慮帶流量復位的問題,需要復位的時候,裝置上可能還有部件在工作。冒然 做復位可能導致異常出現。一般的做法是要先把工作的部件停下來,再進行復位操作。

考慮到了以上兩點,剩下的就是具體結合硬體提供的功能,寫程式碼完成功能了。下面我們 再近一步說明以上兩點。

一般,裝置的全域性配置儲存在裝置全域性暫存器或者是PF裡。所以,裝置全域性復位或者PF FLR 需要考慮配置儲存,恢復相關的東西。全域性復位中,如果硬體沒有復位PCIe SRIOV相關的配置, PCIe VF是一直保持的,裝置驅動需要保留恢復裝置業務相關的配置。但是PF的FLR,PCIe 協議規定VF要被disable,這也就意味著PF FLR會觸發VF消失。不過,裝置驅動並不需要在 復位完成後enable相應的VF,這是因為在PF FLR的流程裡,PCIe匯流排驅動會保留VF數目的 配置,在PF FLR後enable相關VF(不過,全盤考慮這個問題,如果PF FLR的時候,VF在虛擬機器 里正在使用,重新enable的VF在虛擬機器裡是否還可以繼續使用,這裡還不清楚)。

帶流量復位的問題,可能是復位裡最複雜的了。我們考慮全域性復位的情況,一般,全域性復位 的操作發生PF的驅動裡, 我們可以在復位的時候先檢查PF, 把PF的工作停下來再復位。但是, 我們怎麼才能停下來正在虛擬機器裡工作的VF?這就需要PF和VF之間有硬體上的通知機制, PF 要進行全域性復位的時候,先用相關的通知機制通知VF, VF收到通知後把它自己的工作停下 來,然後VF可以通知PF它已經停下工作,PF可以進行全域性復位了。這個是一個合理的帶流量 復位應該做的基本的軟硬體配合的考慮。

如果,硬體沒有PF/VF之間的通知機制,軟體上可以做些什麼來補救? 其實,補救的辦法也 是要依賴硬體的行為。比如,如果全域性復位的時候,VF不響應軟體的請求(寫入都丟棄,讀 到的都是全1), 我們就可以在軟體傳送請求的時候加定時器,如果超時還沒有完成,就猜測 發生了全域性復位。但是,這樣的補救一般運氣的成分大,一不留神就有給你驚喜的地方。 比如,VF讀到全1就有可能引起軟體的誤判, 超時之後VF怎麼了解到是發生了全域性復位,VF 又怎麼判斷全域性復位完成了…