in efawin/verbs.c [835:901]
static int efa_sq_initialize(struct efa_qp *qp,
const struct ibv_qp_init_attr_ex *attr,
struct efa_create_qp_resp *resp)
{
struct efa_context *ctx = to_efa_context(qp->verbs_qp.qp.context);
struct efa_wq_init_attr wq_attr;
struct efa_sq *sq = &qp->sq;
size_t desc_ring_size;
int err;
if (!sq->wq.wqe_cnt)
return 0;
wq_attr = (struct efa_wq_init_attr) {
.db_mmap_key = resp->sq_db_mmap_key,
.db_off = resp->sq_db_offset,
.cmd_fd = qp->verbs_qp.qp.context->cmd_fd,
.pgsz = qp->page_size,
.sub_cq_idx = resp->send_sub_cq_idx,
};
err = efa_wq_initialize(&qp->sq.wq, &wq_attr);
if (err)
return err;
sq->desc_offset = resp->llq_desc_offset;
desc_ring_size = sq->wq.wqe_cnt * sizeof(struct efa_io_tx_wqe);
sq->desc_ring_mmap_size = align(desc_ring_size + sq->desc_offset,
qp->page_size);
sq->max_inline_data = attr->cap.max_inline_data;
sq->local_queue = malloc(desc_ring_size);
if (!sq->local_queue) {
err = ENOMEM;
goto err_terminate_wq;
}
#ifndef _WIN32
sq->desc = mmap(NULL, sq->desc_ring_mmap_size, PROT_WRITE,
MAP_SHARED, qp->verbs_qp.qp.context->cmd_fd,
resp->llq_desc_mmap_key);
if (sq->desc == MAP_FAILED) {
err = errno;
goto err_free_local_queue;
}
sq->desc += sq->desc_offset;
#endif
sq->max_wr_rdma_sge = min_t(uint16_t, ctx->max_wr_rdma_sge,
EFA_IO_TX_DESC_NUM_RDMA_BUFS);
sq->max_batch_wr = ctx->max_tx_batch ?
(ctx->max_tx_batch * 64) / sizeof(struct efa_io_tx_wqe) :
UINT16_MAX;
if (ctx->min_sq_wr) {
/* The device can't accept a doorbell for the whole SQ at once,
* set the max batch to at least (SQ size - 1).
*/
sq->max_batch_wr = min_t(uint32_t, sq->max_batch_wr,
sq->wq.wqe_cnt - 1);
}
return 0;
err_free_local_queue:
free(sq->local_queue);
err_terminate_wq:
efa_wq_terminate(&sq->wq, qp->page_size);
return err;
}