API 查询网址:
https://docs.oracle.com/cd/E88353_01/html/E37842/ibv-modify-qp-3.html
https://www.rdmamojo.com/2013/01/26/ibv_post_send/
ibv_post_send()
函数原型为
int ibv_post_send(struct ibv_qp *qp, struct ibv_send_wr *wr,
struct ibv_send_wr **bad_wr);
其中struct ibv_send_wr结构体的定义为:
https://www.rdmamojo.com/2013/01/26/ibv_post_send/
struct ibv_send_wr {
uint64_t wr_id;
struct ibv_send_wr *next;
struct ibv_sge *sg_list;
int num_sge;
enum ibv_wr_opcode opcode;
int send_flags;
uint32_t imm_data;
union {
struct {
uint64_t remote_addr;
uint32_t rkey;
} rdma;
struct {
uint64_t remote_addr;
uint64_t compare_add;
uint64_t swap;
uint32_t rkey;
} atomic;
struct {
struct ibv_ah *ah;
uint32_t remote_qpn;
uint32_t remote_qkey;
} ud;
} wr;
};
在ibv_send_wr 结构体中opcode参数决定了数据传输类型,比如说:
IBV_WR_SEND——这种传输方式,当前buffer内存中在sg_list中的内容会被发送给远方的QP。发送方并不会知道数据会写到远方节点的何处(接收方决定)。接收方要post_recv,并且接收到的数据要放到指定的地址中。
IBV_WR_RDMA_WRITE——这种传输方式,本地内存buffer中sg_list中的内容会被发送和写到远方节点的QP的虚拟空间中的一段连续内存块中——这并不意味着远方的内存在物理上也是连续的。并且remote QP也不需要post_recv。 (真正的RDMA,对方cpu不参与,本端直接用最开始握手时得到的addr和key 操作对端的内存。)
ibv_send_flags send_flags
https://www.rdmamojo.com/2013/01/26/ibv_post_send/
enum ibv_send_flags {
IBV_SEND_FENCE = 1 << 0,
IBV_SEND_SIGNALED = 1 << 1,
IBV_SEND_SOLICITED = 1 << 2,
IBV_SEND_INLINE = 1 << 3,
IBV_SEND_IP_CSUM = 1 << 4
};
描述WR的属性。它是0或以下一个或多个标志的按位“或”:
IBV_SEND_FENCE -设置此WR的围栅指示符。这意味着该WR的处理将被阻塞,直到所有先前发布的RDMA读取和原子WR完成。仅对Transport Service Type为IBV_QPT_RC的QP有效。IBV_SEND_SIGNALED -设置此WR的完成通知指示符。这意味着