NTB 驅動

NTB(Non-Transparent Bridge,非透明橋)是一種 PCI-Express 橋接晶片,它將兩個或多個計算機的獨立記憶體系統連線到同一個 PCI-Express 結構。現有的 NTB 硬體支援一組通用功能:門鈴暫存器和記憶體轉換視窗,以及非通用功能,如暫存器和訊息暫存器。暫存器是可讀寫的暫存器,可以從裝置的任何一側訪問,以便對等方可以在固定地址交換少量資訊。訊息暫存器可以用於相同的目的。此外,它們還提供特殊的狀態位,以確保資訊不會被另一個對等方重寫。門鈴暫存器提供了一種對等方傳送中斷事件的方式。記憶體視窗允許對等記憶體進行轉換後的讀寫訪問。

NTB 核心驅動 (ntb)

NTB 核心驅動定義了一個 API,封裝了通用功能集,並允許對 NTB 功能感興趣的客戶端發現硬體驅動程式支援的 NTB 裝置。這裡的“客戶端”一詞是指利用 NTB API 的上層元件。“驅動程式”或“硬體驅動程式”一詞是指特定供應商和型號的 NTB 硬體的驅動程式。

NTB 客戶端驅動

NTB 客戶端驅動應向 NTB 核心驅動註冊。註冊後,客戶端的探測和刪除函式將在插入和刪除 ntb 硬體或硬體驅動程式時被適當呼叫。該註冊使用 Linux 裝置框架,因此對於編寫過 pci 驅動的任何人來說,都應該感到熟悉。

NTB 典型客戶端驅動實現

NTB 的主要目的是在至少兩個系統之間共享一些記憶體。因此,NTB 裝置的功能(如暫存器/訊息暫存器)主要用於執行正確的記憶體視窗初始化。通常,NTB API 支援兩種型別的記憶體視窗介面:本地 ntb 埠上配置的入站轉換和對等埠上對等方配置的出站轉換。第一種型別如下圖所示

Inbound translation:

Memory:              Local NTB Port:      Peer NTB Port:      Peer MMIO:
 ____________
| dma-mapped |-ntb_mw_set_trans(addr)  |
| memory     |        _v____________   |   ______________
| (addr)     |<======| MW xlat addr |<====| MW base addr |<== memory-mapped IO
|------------|       |--------------|  |  |--------------|

因此,第一種型別記憶體視窗初始化的典型場景是:1) 分配一個記憶體區域,2) 將轉換後的地址放入 NTB 配置,3) 以某種方式通知對等裝置已執行的初始化,4) 對等裝置對映相應的出站記憶體視窗,以便訪問共享記憶體區域。

第二種型別的介面,意味著共享視窗由對等裝置初始化,如下圖所示

Outbound translation:

Memory:        Local NTB Port:    Peer NTB Port:      Peer MMIO:
 ____________                      ______________
| dma-mapped |                |   | MW base addr |<== memory-mapped IO
| memory     |                |   |--------------|
| (addr)     |<===================| MW xlat addr |<-ntb_peer_mw_set_trans(addr)
|------------|                |   |--------------|

第二種型別介面初始化的典型場景是:1) 分配一個記憶體區域,2) 以某種方式將轉換後的地址傳遞給對等裝置,3) 對等方將轉換後的地址放入 NTB 配置,4) 對等裝置映射出站記憶體視窗,以便訪問共享記憶體區域。

可以看出,所描述的場景可以組合成一個可移植的演算法。

本地裝置
  1. 為共享視窗分配記憶體

  2. 透過分配區域的轉換地址初始化記憶體視窗(如果不支援本地記憶體視窗初始化,則可能會失敗)

  3. 將轉換後的地址和記憶體視窗索引發送給對等裝置

對等裝置
  1. 使用從另一個裝置(由其分配)的記憶體區域的檢索地址初始化記憶體視窗(如果不支援對等記憶體視窗初始化,則可能會失敗)

  2. 映射出站記憶體視窗

根據此場景,NTB 記憶體視窗 API 可以如下使用

本地裝置
  1. ntb_mw_count(pidx) - 檢索記憶體範圍的數量,這些記憶體範圍可以分配給本地裝置和指定索引的埠的對等裝置之間的記憶體視窗。

  2. ntb_get_align(pidx, midx) - 檢索限制共享記憶體區域對齊和大小的引數。然後可以正確分配記憶體。

  3. 根據 2) 中檢索到的限制,分配物理上連續的記憶體區域。

  4. ntb_mw_set_trans(pidx, midx) - 嘗試為定義的對等裝置設定具有指定索引的記憶體視窗的轉換地址(如果不支援本地轉換地址設定,則可能會失敗)

  5. 使用暫存器或訊息暫存器等,將轉換後的基地址(通常與記憶體視窗號一起)傳送到對等裝置。

對等裝置
  1. ntb_peer_mw_set_trans(pidx, midx) - 嘗試為指定的記憶體視窗設定從其他裝置(與 pidx 相關)接收到的轉換地址。如果檢索到的地址超過最大可能地址或未正確對齊,則可能會失敗。

  2. ntb_peer_mw_get_addr(widx) - 檢索 MMIO 地址以對映記憶體視窗,以便訪問共享記憶體。

此外,值得注意的是,方法 ntb_mw_count(pidx) 應該返回與具有埠索引 - pidx 的對等方上的 ntb_peer_mw_count() 相同的值。

NTB 傳輸客戶端 (ntb_transport) 和 NTB Netdev (ntb_netdev)

NTB 的主要客戶端是傳輸客戶端,與 NTB Netdev 結合使用。這些驅動程式協同工作以建立到對等方的邏輯連結,跨越 ntb,以交換網路資料包。傳輸客戶端建立到對等方的邏輯連結,並建立佇列對以交換訊息和資料。然後,NTB Netdev 使用傳輸佇列對建立一個乙太網裝置。網路資料在套接字緩衝區和傳輸佇列對緩衝區之間複製。傳輸客戶端可以用於除 Netdev 之外的其他用途,但是尚未編寫其他應用程式。

NTB Ping Pong 測試客戶端 (ntb_pingpong)

Ping Pong 測試客戶端用作演示,用於練習 NTB 硬體的門鈴和暫存器,並作為一個簡單的 NTB 客戶端示例。Ping Pong 啟用連結後,等待 NTB 連結啟動,然後繼續讀取和寫入 NTB 的門鈴暫存器。對等方使用門鈴位的位掩碼相互中斷,該位掩碼在每一輪中都移動一位,以測試多個門鈴位和中斷向量的行為。Ping Pong 驅動程式還在寫入對等方門鈴暫存器之前,讀取第一個本地暫存器,並將該值加 1 寫入第一個對等方暫存器。

模組引數

  • unsafe - 某些硬體在暫存器和門鈴方面存在已知問題

    暫存器。預設情況下,Ping Pong 不會嘗試練習此類硬體。您可以透過設定 unsafe=1 以您自己的風險覆蓋此行為。

  • delay_ms - 指定接收門鈴之間的延遲

    中斷事件和為下一輪設定對等方門鈴暫存器之間的時間。

  • init_db - 指定啟動新系列輪次的門鈴位。一個新的

    一旦所有門鈴位都已移出範圍,該系列就會開始。

  • dyndbg - 建議在載入此模組時指定 dyndbg=+p,並且

    然後在控制檯上觀察除錯輸出。

NTB 工具測試客戶端 (ntb_tool)

工具測試客戶端主要用於除錯 ntb 硬體和驅動程式。該工具透過 debugfs 提供訪問許可權,用於讀取、設定和清除 NTB 門鈴,以及讀取和寫入暫存器。

該工具當前沒有任何模組引數。

Debugfs 檔案

  • debugfs/ntb_tool/hw/

    將為該工具探測的每個 NTB 裝置在 debugfs 中建立一個目錄。此目錄在下面縮短為 *hw*。

  • hw/db

    此檔案用於讀取、設定和清除本地門鈴。並非所有操作都可能受所有硬體的支援。要讀取門鈴,請讀取該檔案。要設定門鈴,請寫入 s,後跟要設定的位(例如:echo 's 0x0101' > db)。要清除門鈴,請寫入 c,後跟要清除的位。

  • hw/mask

    此檔案用於讀取、設定和清除本地門鈴掩碼。有關詳細資訊,請參見 *db*。

  • hw/peer_db

    此檔案用於讀取、設定和清除對等方門鈴。有關詳細資訊,請參見 *db*。

  • hw/peer_mask

    此檔案用於讀取、設定和清除對等方門鈴掩碼。有關詳細資訊,請參見 *db*。

  • hw/spad

    此檔案用於讀取和寫入本地暫存器。要讀取所有暫存器的值,請讀取該檔案。要寫入值,請寫入一系列暫存器號和值的對(例如:echo '4 0x123 7 0xabc' > spad # 將暫存器 47 分別設定為 0x1230xabc)。

  • hw/peer_spad

    此檔案用於讀取和寫入對等方暫存器。有關詳細資訊,請參見 *spad*。

NTB MSI 測試客戶端 (ntb_msi_test)

MSI 測試客戶端用於測試和除錯 MSI 庫,該庫允許透過 NTB 記憶體視窗傳遞 MSI 中斷。測試客戶端透過 debugfs 檔案系統進行互動

  • debugfs/ntb_msi_test/hw/

    將為 msi 測試探測的每個 NTB 裝置在 debugfs 中建立一個目錄。此目錄在下面縮短為 *hw*。

  • hw/port

    此檔案描述了本地埠號

  • hw/irq*_occurrences

    每個中斷都存在一個 occurrences 檔案,讀取該檔案時,會返回中斷被觸發的次數。

  • hw/peer*/port

    此檔案描述了每個對等方的埠號

  • hw/peer*/count

    此檔案描述了可以在每個對等方上觸發的中斷數

  • hw/peer*/trigger

    寫入一箇中斷號(任何小於計數中指定的值的數字)將觸發指定對等方上的中斷。該對等方的中斷的 occurrence 檔案應增加。

NTB 硬體驅動

NTB 硬體驅動應向 NTB 核心驅動註冊裝置。註冊後,將呼叫客戶端探測和刪除函式。

NTB Intel 硬體驅動 (ntb_hw_intel)

Intel 硬體驅動支援 Xeon 和 Atom CPU 上的 NTB。

模組引數

  • b2b_mw_idx

    如果要透過記憶體視窗訪問對等方 ntb,則使用此記憶體視窗訪問對等方 ntb。零或正值從第一個 mw idx 開始,負值從最後一個 mw idx 開始。雙方都必須在此處設定相同的值!預設值為 -1

  • b2b_mw_share

    如果要透過記憶體視窗訪問對等方 ntb,並且如果記憶體視窗足夠大,仍然允許客戶端使用記憶體視窗的後半部分進行地址轉換到對等方。

  • xeon_b2b_usd_bar2_addr64

    如果在 Xeon 硬體上使用 B2B 拓撲,則在 NTB 裝置之間的總線上使用此 64 位地址作為 BAR2 的視窗,位於連結的上游側。

  • xeon_b2b_usd_bar4_addr64 - 參見 *xeon_b2b_bar2_addr64*。

  • xeon_b2b_usd_bar4_addr32 - 參見 *xeon_b2b_bar2_addr64*。

  • xeon_b2b_usd_bar5_addr32 - 參見 *xeon_b2b_bar2_addr64*。

  • xeon_b2b_dsd_bar2_addr64 - 參見 *xeon_b2b_bar2_addr64*。

  • xeon_b2b_dsd_bar4_addr64 - 參見 *xeon_b2b_bar2_addr64*。

  • xeon_b2b_dsd_bar4_addr32 - 參見 *xeon_b2b_bar2_addr64*。

  • xeon_b2b_dsd_bar5_addr32 - 參見 *xeon_b2b_bar2_addr64*。