1

我在执行 RDMA 原子操作(FETCH_ADD 和 CMP_AND_SWAP)时遇到问题。当我尝试提交原子 RDMA 请求时,ibv_post_send() 函数失败,Errno 设置为“无效参数”。RDMA READ/WRITE 没有这样的问题。

我注册内存地址如下:

local_buffer = new uint64_t[1];   // so the memory region is byte-aligned
local_mr = ibv_reg_mr(pd, local_buffer, sizeof(uint64_t),
    IBV_ACCESS_LOCAL_WRITE
    | IBV_ACCESS_REMOTE_READ
    | IBV_ACCESS_REMOTE_ATOMIC));

我按如下方式构建队列对:

memset(qp_attr, 0, sizeof(*qp_attr));
qp_attr->send_cq = s_ctx->cq;
qp_attr->recv_cq = s_ctx->cq;
qp_attr->qp_type = IBV_QPT_RC;
qp_attr->cap.max_send_wr = 10;
qp_attr->cap.max_recv_wr = 10;
qp_attr->cap.max_send_sge = 1;
qp_attr->cap.max_recv_sge = 1;
TEST_NZ(rdma_create_qp(id, s_ctx->pd, qp_attr));

最后用原子操作码提交RDMA操作如下:

struct ibv_send_wr wr, *bad_wr = NULL;
struct ibv_sge sge;
memset(&sge, 0, sizeof(sge));
sge.addr        = (uintptr_t)conn->local_buffer;
sge.length      = 8;
sge.lkey        = conn->local_mr->lkey;
memset(&wr, 0, sizeof(wr));
wr.wr_id                    = 0;
wr.opcode                   = IBV_WR_ATOMIC_FETCH_AND_ADD;
wr.sg_list                  = &sge;
wr.num_sge                  = 1;
wr.send_flags               = IBV_SEND_SIGNALED;
wr.wr.atomic.remote_addr    = (uintptr_t)conn->peer_mr.addr;
wr.wr.atomic.rkey           = conn->peer_mr.rkey;
wr.wr.atomic.compare_add    = 1ULL; /* value to be added to the remote address content */
if (ibv_post_send(conn->qp, &wr, &bad_wr)) {
    fprintf(stderr, "Error, ibv_post_send() failed\n");
    die("");
}   

PS 因为我使用的是 librdmacm,所以 INIT 和 RTR 和 RTS 之间的队列对的转换是自动完成的,所以我不能手动设置qp_attr->qp_access_flagsqp_attr->max_rd_atomicqp_attr->max_dest_rd_atomic使用ibv_modify_qp(). 但是,我在 libibcm 中编写了一个带有原子操作的小代码,并在手动转换队列时设置了这些属性。尽管如此,还是没有运气。

4

0 回答 0