mellanox RDMA RoCE


一:首先根據系統發行版本下載對應的驅動,下載地址如下:

http://www.mellanox.com/page/products_dyn?product_family=26&mtag=linux_sw_drivers

本次下載的驅動版本為:MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64.tgz

 

二:添加針對當前內核的IB驅動

1.把下載好的mellanox驅動解壓縮

linux:~ # tar xzvf MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64.tgz

linux:~ # cd MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64/

linux:~/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64# ll

total 228

-rw-r--r-- 1 root root            7 May  1  2013.arch

-rw-r--r-- 1 root root           13 May  1  2013.mlnx

-rw-r--r-- 1 root root           72 May  1  2013.supported_kernels

drwxr-xr-x 2 root root        12288 May  1  2013RPMS

drwxr-xr-x 8 root root         4096 May  1  2013docs

drwxr-xr-x 5 2666 messagebus   4096 Apr 17 2013 firmware

-rwxr-xr-x 1 root root        11234 May  1  2013mlnx_add_kernel_support.sh

-rwxr-xr-x 1 root root       161517 May  1  2013mlnxofedinstall

drwxr-xr-x 2 root root         4096 May  1  2013repodata

drwxr-xr-x 2 root root         4096 May  1  2013src

-rwxr-xr-x 1 root root         9790 May  1  2013uninstall.sh

 

2.查看當前驅動所支持的內核版本

linux:~/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64# cat .supported_kernels

2.6.27.19-5-debug

2.6.27.19-5-default

2.6.27.19-5-trace

2.6.27.19-5-xen

 

3.查看當前系統內核版本

linux:~/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64# uname -r

2.6.32.12-0.7-default

 

注:由以上可知下載的默認驅動不支持當前的內核版本

 

4.添加針對當前內核版本的IB驅動

 

◆在編譯之前首先安裝gcc編譯環境和kernel開發包

linux:~/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64# zypper install gcc gcc-c++

libstdc++-devel kernel-default-devel

◆添加針對當前內核版本的驅動

linux:~/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64#./mlnx_add_kernel_support.sh -m /root/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64 -v

 

注:完成后生成的驅動文件在/tmp目錄下

 

linux:~/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11-x86_64# ls -l /tmp/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11sp1-x86_64.tgz

-rw-r--r-- 1 rootroot 238440971 Dec 17 04:43/tmp/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11sp1-x86_64.tgz

 

◆安裝驅動

linux:/tmp # pwd

/tmp

linux:/tmp # tar xzvf MLNX_OFED_LINUX-1.5.3-4.0.42-sles11sp1-x86_64.tgz

linux:/tmp # cd MLNX_OFED_LINUX-1.5.3-4.0.42-sles11sp1-x86_64/

linux:/tmp/MLNX_OFED_LINUX-1.5.3-4.0.42-sles11sp1-x86_64# ./mlnxofedinstall

 

注:如果系統缺少libgfortran43,在安裝的時候會提示以下信息(最好是安裝,不安裝也行,只是不能運行openshmem和openmpi_gcc)

 

Warning: libgfortran43 rpm is required to runopenshmem

libgfortran43 is available on SLES11 SDK DVD

Warning: libgfortran43 rpm is required to run openmpi_gcc

libgfortran43 is available on SLES11 SDK DVD

 

◆最后啟動openibd服務

linux:~ #/etc/init.d/openibd start

linux:~ #chkconfig openibd on

 

Mellanox的RDMA是基於ROCE協議的,因此需要物理層保證可靠傳輸,不能丟包。為此交換機需要支持DCB, PFC等流控技術。這樣子系統一下子就復雜了,為了簡化系統,決定不使用交換機,把服務器之間用光纖直連。好在我只有3台服務器,剛好可以連起來,1台對2台即可。

ubuntu14.04系統居然自帶了mellanox XC3的驅動,這讓我很驚奇,作為普通網卡用這已經可以工作了。但我要用的是RDMA,因此決定還是重新裝一下驅動。

  • 步驟1:去mellanox官網上找驅動 
    這個過程可以用兩個詞形容,大海撈針,中彩票。 網站上內容很多,各種文章也很多,但是沒有哪個是教你step by step就能工作的,能下載的軟件也很多,也不知道哪個驅動是給那種卡用的,關鍵是,下錯了你也能裝上,只是運行是不正常而已。比如,我就先下載到了mlnx-en-3.3-1.0.0.0.tgz, 裝上后TCP正常工作沒問題,RDMA不能用。然后從各種官網的網頁里面的各種方法亂試,又找到一個MLNX_OFED_LINUX-3.3-1.0.4.0-ubuntu14.04-x86_64.tgz, 這個才對了。

大概mellanox的人都很清楚這些區別,但對我一個新手,這太不友好了。

  • 步驟2: rping, ib_xxxx_lat/bw測試 
    這一步其實是和第1步合並執行的,裝完了驅動總要試試能不能工作。能工作才說明裝對了。

  • 步驟3:測試我自己的rdma程序 
    我的程序工作原理是這樣的:

    1. server啟動,等待client連接
    2. client 用RDMA_SEND把本地的一個buffer的rkey, raddress發送給server
    3. server收到后,用RDMA_READ,讀取client的數據

1和2都執行成功了,3遇到錯誤,檢查completion 時wr里面的vendor error, 是138。開始求助mellanox的技術支持這個錯誤是什么,對方說是:indicates InvReq Nack. 又追問Nack是什么,說是not ACK。

我的代碼之前是用softIWARP調試通過了的,所以認為沒有太多低級錯誤,以為這樣的vendor error能很快解決,但實際上廠家也給不出任何意見。還是得自己慢慢調試。又是從其網站上的各種文章里面的各種方法挨個試驗,其中包括了把roce 模式改成v2,

# echo "options mlx4_core roce_mode=2" > /etc/modprobe.d/mlx4_core.conf
  • 這個對·vendor error 138·沒有幫助,但對后面的調試造成了困難

后來發現ib_read_lat程序能正常工作,基於這個線索開始找我的代碼和ib_read_lat代碼的區別。要不怎么說開源好呢,還有最后的絕招可以用,看代碼啊!

其實也沒那么容易,ib_read_lat的代碼很多,不是一下子能找出關鍵點,只能一點一點把ib_read_lat的代碼往下減,果然,減到一定程度,出現了和我同樣的錯誤,再仔細看這減掉的部分,錯誤其實很簡單,在調用rdma_connect函數時,要設置connection param的responder_resources等幾個參數

struct rdma_conn_param cm_params; cm_params.responder_resources = priv_data.hsqsize; cm_params.initiator_depth = priv_data.hsqsize; cm_params.retry_count = 7; cm_params.rnr_retry_count = 7; rdma_connect(evt->id, &cm_params);
  • 這里不得不第一次吐槽rdma_cm,或者ofed,或者mellanox的錯誤信息,太不清晰了,這么簡單的錯誤,如果有明確的錯誤指示,何至於讓我浪費幾天的時間。
  • 步驟4: 繼續運行我的程序 
    這里先交代一下,前一步調試問題時,為縮小問題的來源范圍,開始在單個節點上調試,即: server, client都運行在同一個機器上。

我的程序需要運行在不同的機器上,在節點間進行RDMA傳輸(這個想必是自然的,沒人在同一個節點上吃飽了撐的用RDMA)。結果發現, 聯不通啊!!

又換回ib_send_bw這個工具開始測試,發現同樣聯不通,問題是:

ethernet_read_keys: Couldn't read remote address Unable to read to socket/rdam_cm Failed to close connection between server and client Trying to close this side resources
  • 各種google,和官網的文章亂看,重裝驅動,無果。 然后忽然想起了我自己的筆記,這里插播廣告:居家旅行, 編程調試必備之良器, evernote, 你值得擁有, 發現了我在前面把一個機器改成了RoCE v2模式!

既然如此,那就都用v2模式,問題解決!

  • 步驟5:重復步驟4, 運行我的程序 
    cao! 還是不行,換了個新說法:
# ib_send_bw -R 192.168.a.b Received 10 times ADDR_ERROR Unable to perform rdma_client function Unable to init the socket connection

先說明一下不重要的,這里的測試使用了-R參數,表示使用rdma_cm進行連接管理,這也是我的程序需要用的,前面的步驟測試時沒有使用這個參數。

可以想象我有多么崩潰,不過我覺得不用找廠家了,廠家也提供不了什么,其實有經驗的還是一線的工作者,所以認識的很多人,都被上游廠家挖走做AE/FAE去了。這次我先看了我的evernote,所以浪費時間不多。在去年的筆記里找到了下面的這個配置:

# mount -t configfs none /sys/kernel/config # cd /sys/kernel/config/rdma_cm # mkdir mlx4_0 # cd mlx4_0 # echo RoCE V2 > default_roce_mode

RoCE可以在以太網上運行RDMA協議,時延比普通以太網可以提升30%以上,也可以支持雙協議棧,同時用TCP和RDMA,編程過程類似IB。

有兩張建鏈方式,一種是通過RDMA_CM建鏈,一種是先通過TCP建鏈,通過tcp通道交換雙方的設備信息,QP信息,簡歷RDMA鏈路,然后關閉tcp鏈路,第二種更常用。

 

RDMA編程流程

 

1)初始化RDMA設備

ibv_get_device_list()獲取使用可以使用RDMA傳輸的設備個數,可以根據ibv_get_device_list結構中的dev_name找到需要使用的設備;

struct ibv_device **ibv_get_device_list(int *num_devices);

ibv_open_device()打開設備,獲取設備句柄;

ibv_query_device()查詢設備,獲取設備屬性

ibv_query_port()查詢設備端口屬性

如果類型為Ethernet,bv_query_gid()獲取設備GID,用於交換雙方信息使用

 

2)創建QP信息

ibv_alloc_pd()用於創建qp接口的參數

ibv_create_cq()創建CQ,一個CQ可以完成的CQE的個數,CQE與隊列個數有關,隊列多,CQE個數就設置多,否則設置少,一個CQ可以對應一個QP,也可以兩個CQ對應一個QP。一個CQ包含發送和接收隊列。

ibv_create_qp()創建QP。類似tcp的socket

3)注冊MR信息

ibv_reg_mr()注冊網卡內存信息,把操作系統物理內存注冊到網卡

4)交換QP信息

ibv_modify_qp()交換雙方QP信息,修改QP信息狀態級

Client端:先創建QP,修改狀態級reset到INIT,修改INIT到RTR,然后發送到server端,server端創建QP,修改狀態機有INIT到RTR,然后發送到客戶端,客戶端修改狀態機有RTR到RTS,發送到server端,server端修改狀態機有RTR到RTS,這樣rmda鏈路簡建立成功。

5)發送和接收

ibv_post_recv()接收消息接口

ibv_post_send()發送消息接口

ibv_poll_cq()用於查詢cq隊列是否有事件產生,如果有調用recv接口接收。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM