in efawin/ibv_win_cmd.c [173:236]
int ibv_cmd_create_cq_ex(struct ibv_context* context,
const struct ibv_cq_init_attr_ex* cq_attr,
struct verbs_cq* cq,
struct ibv_create_cq_ex* cmd,
size_t cmd_size,
struct ib_uverbs_ex_create_cq_resp* resp,
size_t resp_size,
uint32_t cmd_flags)
{
struct ibv_cq* ibv_cq = NULL;
struct efa_context* ctx = to_efa_context(context);
struct efa_dev* edev = to_efa_dev(context->device);
struct efa_cq* efa_cq = to_efa_cq(&cq->cq);
struct efa_create_cq_resp* efa_resp = container_of(resp, struct efa_create_cq_resp, ibv_resp);
EFA_CREATE_CQ_PARAMS params = { 0 };
EFA_CQ_INFO result = { 0 };
int err;
uint64_t cqe_rounded;
if (resp_size > UINT32_MAX) {
return E_INVALIDARG;
}
cqe_rounded = roundup_pow_of_two(cq_attr->cqe);
if (cqe_rounded > UINT16_MAX) {
return E_INVALIDARG;
}
params.CqDepth = (UINT16)cqe_rounded;
params.NumSubCqs = ctx->sub_cqs_per_cq;
if (ctx->cqe_size > UINT8_MAX) {
return E_INVALIDARG;
}
params.EntrySizeInBytes = (UINT8)ctx->cqe_size;
err = efa_win_create_cq(&edev->device, ¶ms, &result);
if (err) {
return err;
}
ibv_cq = &cq->cq;
ibv_cq->async_events_completed = 0;
ibv_cq->comp_events_completed = 0;
ibv_cq->channel = cq_attr->channel;
ibv_cq->context = context;
ibv_cq->cqe = result.CqActualDepth;
ibv_cq->cq_context = cq_attr->cq_context;
ibv_cq->handle = result.CqIndex;
pthread_cond_init(&ibv_cq->cond, 0);
pthread_mutex_init(&ibv_cq->mutex, 0);
efa_cq->buf = result.CqAddr;
efa_cq->num_sub_cqs = ctx->sub_cqs_per_cq;
efa_cq->buf_size = result.CqActualDepth * ctx->sub_cqs_per_cq * ctx->cqe_size;
efa_cq->cqn = result.CqIndex;
resp->base.cq_handle = result.CqIndex;
resp->base.cqe = result.CqActualDepth;
resp->response_length = (uint32_t)resp_size;
efa_resp->q_mmap_size = efa_cq->buf_size;
efa_resp->cq_idx = result.CqIndex;
return 0;
}