使用者空間 MAD 訪問¶
裝置檔案¶
每個 InfiniBand 裝置的每個埠都有一個“umad”裝置和一個“issm”裝置連線。 例如,一個雙埠 HCA 將有兩個 umad 裝置和兩個 issm 裝置,而一個交換機將有每種型別的一個裝置(用於交換機埠 0)。
建立 MAD 代理¶
可以透過填寫一個 struct ib_user_mad_reg_req,然後在相應裝置檔案的檔案描述符上呼叫 IB_USER_MAD_REGISTER_AGENT ioctl 來建立 MAD 代理。 如果註冊請求成功,則將在結構中返回一個 32 位 id。 例如
struct ib_user_mad_reg_req req = { /* ... */ }; ret = ioctl(fd, IB_USER_MAD_REGISTER_AGENT, (char *) &req); if (!ret) my_agent = req.id; else perror("agent register");可以使用 IB_USER_MAD_UNREGISTER_AGENT ioctl 取消註冊代理。 此外,當檔案描述符關閉時,透過檔案描述符註冊的所有代理都將被取消註冊。
- 2014
現在提供了一個新的註冊 ioctl,允許在註冊期間提供額外的欄位。 使用此註冊呼叫的使用者正在隱式設定 pkey_index 的使用(請參見下文)。
接收 MAD¶
MAD 是使用 read() 接收的。 接收端現在支援 RMPP。 傳遞給 read() 的緩衝區必須至少為 struct ib_user_mad + 256 位元組。 例如
如果傳遞的緩衝區不夠大,無法容納接收到的 MAD (RMPP),則 errno 設定為 ENOSPC,並且所需緩衝區長度設定在 mad.length 中。
正常 MAD(非 RMPP)讀取的示例
struct ib_user_mad *mad; mad = malloc(sizeof *mad + 256); ret = read(fd, mad, sizeof *mad + 256); if (ret != sizeof mad + 256) { perror("read"); free(mad); }RMPP 讀取的示例
struct ib_user_mad *mad; mad = malloc(sizeof *mad + 256); ret = read(fd, mad, sizeof *mad + 256); if (ret == -ENOSPC)) { length = mad.length; free(mad); mad = malloc(sizeof *mad + length); ret = read(fd, mad, sizeof *mad + length); } if (ret < 0) { perror("read"); free(mad); }除了實際的 MAD 內容之外,其他的 struct ib_user_mad 欄位也將填充有關接收到的 MAD 的資訊。 例如,遠端 LID 將在 mad.lid 中。
如果傳送超時,將生成一個接收,並且 mad.status 設定為 ETIMEDOUT。 否則,當成功接收到 MAD 時,mad.status 將為 0。
poll()/select() 可用於等待直到可以讀取 MAD。
傳送 MAD¶
MAD 是使用 write() 傳送的。 傳送代理的 ID 應該填充到 MAD 的 id 欄位中,目標 LID 應該填充到 lid 欄位中,依此類推。 傳送端支援 RMPP,因此可以傳送任意長度的 MAD。 例如
struct ib_user_mad *mad; mad = malloc(sizeof *mad + mad_length); /* fill in mad->data */ mad->hdr.id = my_agent; /* req.id from agent registration */ mad->hdr.lid = my_dest; /* in network byte order... */ /* etc. */ ret = write(fd, &mad, sizeof *mad + mad_length); if (ret != sizeof *mad + mad_length) perror("write");
事務 ID¶
umad 裝置的使用者可以使用傳送到匹配請求/響應對的 MAD 中事務 ID 欄位的低 32 位(即網路位元組順序中欄位的最低有效一半)。 高 32 位保留供核心使用,並且在傳送 MAD 之前將被覆蓋。
P_Key 索引處理¶
舊的 ib_umad 介面不允許為傳送的 MAD 設定 P_Key 索引,也沒有提供獲取接收到的 MAD 的 P_Key 索引的方法。 已經定義了具有 pkey_index 成員的 struct ib_user_mad_hdr 的新佈局;但是,為了保持與舊應用程式的二進位制相容性,除非在檔案描述符用於其他任何用途之前呼叫了 IB_USER_MAD_ENABLE_PKEY 或 IB_USER_MAD_REGISTER_AGENT2 ioctl 之一,否則不會使用此新佈局。
在 2008 年 9 月,IB_USER_MAD_ABI_VERSION 將增加到 6,預設情況下將使用 struct ib_user_mad_hdr 的新佈局,並且 IB_USER_MAD_ENABLE_PKEY ioctl 將被刪除。
設定 IsSM 能力位¶
要為埠設定 IsSM 能力位,只需開啟相應的 issm 裝置檔案。 如果已經設定了 IsSM 位,則開啟呼叫將阻塞,直到該位被清除(或者如果將 O_NONBLOCK 標誌傳遞給 open(),則立即返回,並將 errno 設定為 EAGAIN)。 當 issm 檔案關閉時,IsSM 位將被清除。 不能在 issm 檔案上執行讀取、寫入或其他操作。
/dev 檔案¶
要使用 udev 自動建立相應的字元裝置檔案,可以使用如下規則
KERNEL=="umad*", NAME="infiniband/%k" KERNEL=="issm*", NAME="infiniband/%k"這將建立名為
/dev/infiniband/umad0 /dev/infiniband/issm0的裝置節點,用於第一個埠,依此類推。 與這些裝置關聯的 InfiniBand 裝置和埠可以從以下檔案確定
/sys/class/infiniband_mad/umad0/ibdev /sys/class/infiniband_mad/umad0/port和
/sys/class/infiniband_mad/issm0/ibdev /sys/class/infiniband_mad/issm0/port