LNet程式碼分析

一罪發表於2019-07-07

原始碼版本:lustre-release 2.15.55

介紹

LNet是Lustre的網路模組,程式碼目錄分為了lnet和lnd

  • lnet提供了統一的介面
  • lnd封裝了底層驅動,有socklnd(TCP/IP),iblnd(RDMA)

分析程式碼的主要目的是為了研究其如何實現RDMA大規模組網(5萬+客戶端)。RDMA大規模組網的瓶頸在於伺服器的記憶體,如BeeGFS需要為每個連線分配1M的傳送快取(實體記憶體)和1M的接收快取,並對映到dma,這樣一算支援1萬客戶端就需要佔用超過20G的記憶體。

先寫結論
LNet通過兩階段收發資料的方式避免了為每個連線預申請記憶體,以傳送資料為例

  • 第一階段:傳送端將待傳送的資料對映到dma,並通過預對映的記憶體通過RDMA告知接收端待傳送的資料資訊(長度、型別等),接收端申請記憶體並對映到dma,並告知傳送端對映後的資訊(address、key)
  • 第二階段:傳送端將資料通過RDMA傳送給接收端

雖然兩階段傳送增加了通訊成本,但使得記憶體不會成為大規模組網的瓶頸。

初始化

iblnd初始化函式kiblnd_startup(),主要的是建立pool set。pool set分為fmr pool set和tx pool set。至少會建立cpt個pool set,每個pool set初始包含一個pool,一個pool最多包含256個fmr/tx,每個mr可對映256個page,每個tx可儲存256個page地址,每個tx會預對映一個page到dma,為rdma通訊所用。

cpt含義是cpu partition,值與cpu核數以及numa的節點個數有關。

傳輸資料時,需要

  • 從tx pool set獲取一個tx,填寫訊息資訊(長度、型別等),以預對映的page與接收端通訊
  • 從fmr pool set從獲取一個mr,將待傳送資料的記憶體對映到這塊mr中

當沒有tx或mr可用時,會建立新的pool。每個pool都有一個deadline,當歸還tx時,如果該pool空閒且已經到deadline,則會回收該pool。

建立連線

建立連線在傳送資料的流程中觸發,其過程與常規rdma建立流程無異,需要注意的是iblnd中建立流程通過rdma的事件回撥觸發下一階段,可能有些費解。建立連線時會預先申請18個page,並對映到dma,作為RQE(receive queue entry)。18是根據連線的佇列深度和協議版本確定的。每個連線固定佔用的記憶體資源很少。

收發資料

因為tx預對映了一個page,所以當傳送的資料小於4K時,則可以立即傳送。當傳送的資料大於4K時,則需要走兩階段傳送。當接收端收到第一階段的訊息後,會申請記憶體準備接收資料。這些記憶體是上層服務在註冊時申請的,可以複用於多個連線。第二階段時,一旦接收端收到全部資料後,就會通過事件回撥的方式通知上層。傳送端也是如此,一旦全部傳送成功後,會通過事件回撥的方式通知上層。

家裡竟然下不了原始碼,只能簡單寫寫了。

相關文章