一、安装
# Download wget https://github.com/Mellanox/libvma/archive/refs/tags/9.4.0.zip unzip 9.4.0.zip cd libvma-9.4.0 # Build ./autogen.sh ./configure --with-ofed=/usr --prefix=/usr --libdir=/usr/lib64 \ --includedir=/usr/include --docdir=/usr/share/doc/libvma --sysconfdir=/etc make # Install make install
二、测试
通过环境变量
LD_PRELOAD
即可实现对内核协议栈的替换。1. Ping-pong
# server side VMA_SPEC=latency LD_PRELOAD=libvma.so numactl --cpunodebind=1 taskset -c 19,13 sockperf server -i 10.1.1.1 -p 5555 --msg-size 64 # client side VMA_SPEC=latency LD_PRELOAD=libvma.so sockperf pp -i 10.1.1.1 -p 5555 --msg-size 64 --time 4
内核协议栈
VMA
三、结果
通过抓包可以发现 VMA 传输过程中并未对数据包进行修改,只是在两端收发的位置利用 RDMA Verbs 绕过了协议栈,并实现了零拷贝。
对比下图中的RoCE数据包
推断其是通过将 QP 设为
IBV_QPT_RAW_PACKET
或IBV_QPT_RAW_ETH
来进行的收发,通过观察源代码发现其具体代码逻辑和 RDMA 编程非常相似,都是基于工作队列(SQ, RQ)和完成队列(CQ)来实现的,也发现了其 QP 使用的方式是符合推测的。因此可以得出结论的是,VMA 是一个利用了 RDMA Verbs 来实现的 socket 协议栈,它具有了 RDMA 零拷贝和 bypass 的特性,但其使用方式仍是传统的消息模式,与 RDMA 类似内存访问的机制存在本质区别,因此不能实现 offload 特性,对于数据量大的数据,其仍需要两端 CPU 参与消息的收发,而 RDMA 可以只利用客户端的 CPU 完成数据传输。