У меня проблема с выполнением атомарных операций 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("");
}
Постскриптум так как я использую librdmacm, переход пар очереди между INIT и RTR и RTS выполняется автоматически, поэтому я не могу установить вручную qp_attr->qp_access_flags
, qp_attr->max_rd_atomic
а также qp_attr->max_dest_rd_atomic
с помощью ibv_modify_qp()
, Однако я написал небольшой код в libibcm с атомарными операциями и установил эти атрибуты при переходе очереди вручную. Тем не менее, не повезло.
Задача ещё не решена.