efa: Add QP support for 64-bit SQ WR request IDs Add support for creating QPs that use 64-bit SQ request IDs. Enable 64-bit SQ request IDs automatically if the device support it. When enabled, the QP doesn't allocate a WR ID pool to translate 64-bit IDs to 16-bit IDs and place the 64-bit ID directly in the WR meta descriptor. Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
diff --git a/providers/efa/efa_io_defs.h b/providers/efa/efa_io_defs.h index 12514f3..69909b6 100644 --- a/providers/efa/efa_io_defs.h +++ b/providers/efa/efa_io_defs.h
@@ -136,7 +136,9 @@ /* Queue key */ uint32_t qkey; - uint8_t reserved2[12]; + uint8_t reserved2[6]; + + struct efa_io_req_id_ex req_id_ex; }; /*
diff --git a/providers/efa/verbs.c b/providers/efa/verbs.c index bd860cf..e21df3a 100644 --- a/providers/efa/verbs.c +++ b/providers/efa/verbs.c
@@ -529,6 +529,21 @@ return efa_wq_get_wrid_by_dev_req_id(wq, cqe->req_id); } +static inline void efa_set_sq_comp_wrid(struct efa_io_tx_meta_desc *md, struct efa_wq *wq, + uint64_t wr_id) ALWAYS_INLINE; +static inline void efa_set_sq_comp_wrid(struct efa_io_tx_meta_desc *md, struct efa_wq *wq, + uint64_t wr_id) +{ + if (wq->req_id_64_bit) { + md->req_id = (uint16_t)wr_id; + md->req_id_ex.w[0] = (uint16_t)(wr_id >> 16); + md->req_id_ex.w[1] = (uint16_t)(wr_id >> 32); + md->req_id_ex.w[2] = (uint16_t)(wr_id >> 48); + } else { + md->req_id = efa_wq_get_dev_req_id_locked(wq, wr_id); + } +} + static uint32_t efa_sub_cq_get_current_index(struct efa_sub_cq *sub_cq) { return sub_cq->consumed_cnt & sub_cq->qmask; @@ -1632,8 +1647,11 @@ db_aligned = (void *)((uintptr_t)wq->db & ~(pgsz - 1)); munmap(db_aligned, pgsz); - free(wq->wrid_idx_pool); - free(wq->wrid); + if (wq->wrid_idx_pool) + free(wq->wrid_idx_pool); + + if (wq->wrid) + free(wq->wrid); } static int efa_wq_initialize(struct efa_wq *wq, struct efa_wq_init_attr *attr) @@ -1643,14 +1661,20 @@ int err; int i; - wq->wrid = malloc(wq->wqe_cnt * sizeof(*wq->wrid)); - if (!wq->wrid) - return ENOMEM; + if (!wq->req_id_64_bit) { + wq->wrid = malloc(wq->wqe_cnt * sizeof(*wq->wrid)); + if (!wq->wrid) + return ENOMEM; - wq->wrid_idx_pool = malloc(wq->wqe_cnt * sizeof(uint32_t)); - if (!wq->wrid_idx_pool) { - err = ENOMEM; - goto err_free_wrid; + wq->wrid_idx_pool = malloc(wq->wqe_cnt * sizeof(uint32_t)); + if (!wq->wrid_idx_pool) { + err = ENOMEM; + goto err_free_wrid; + } + + /* Initialize the wrid free indexes pool. */ + for (i = 0; i < wq->wqe_cnt; i++) + wq->wrid_idx_pool[i] = i; } wrid_idx_mask = roundup_pow_of_two(wq->wqe_cnt) - 1; @@ -1666,10 +1690,6 @@ wq->db = (uint32_t *)(db_base + attr->db_off); - /* Initialize the wrid free indexes pool. */ - for (i = 0; i < wq->wqe_cnt; i++) - wq->wrid_idx_pool[i] = i; - wq->need_lock = attr->need_lock; if (wq->need_lock) pthread_spin_init(&wq->wqlock, PTHREAD_PROCESS_PRIVATE); @@ -1679,9 +1699,11 @@ return 0; err_free_wrid_idx_pool: - free(wq->wrid_idx_pool); + if (wq->wrid_idx_pool) + free(wq->wrid_idx_pool); err_free_wrid: - free(wq->wrid); + if (wq->wrid) + free(wq->wrid); return err; } @@ -1965,12 +1987,14 @@ ctx->min_sq_wr)); qp->sq.wq.max_sge = cap->max_send_sge; qp->sq.wq.desc_mask = qp->sq.wq.wqe_cnt - 1; + qp->sq.wq.req_id_64_bit = !!(EFA_DEV_CAP(ctx, SQ_64_BIT_REQ_ID)); qp->sq.inline_write_enabled = inline_write_enabled; qp->rq.wq.max_sge = cap->max_recv_sge; rq_desc_cnt = roundup_pow_of_two(cap->max_recv_sge * cap->max_recv_wr); qp->rq.wq.desc_mask = rq_desc_cnt - 1; qp->rq.wq.wqe_cnt = rq_desc_cnt / qp->rq.wq.max_sge; + qp->rq.wq.req_id_64_bit = false; qp->page_size = page_size; } @@ -2186,6 +2210,9 @@ req.sl = efa_attr->sl; + if (qp->sq.wq.req_id_64_bit) + req.flags |= EFA_CREATE_QP_WITH_SQ_64_BIT_REQ_ID; + err = ibv_cmd_create_qp_ex(ibvctx, &qp->verbs_qp, attr, &req.ibv_cmd, sizeof(req), &resp.ibv_resp, sizeof(resp)); @@ -2734,7 +2761,8 @@ /* Set rest of the descriptor fields */ efa_set_common_ctrl_flags(md, sq, EFA_IO_SEND); - md->req_id = efa_wq_get_dev_req_id_locked(wq, wr->wr_id); + efa_set_sq_comp_wrid(md, wq, wr->wr_id); + md->dest_qp_num = wr->wr.ud.remote_qpn; md->ah = ah->efa_ah; md->qkey = wr->wr.ud.remote_qkey; @@ -2807,7 +2835,7 @@ sq->curr_tx_wqe.md = md; efa_set_common_ctrl_flags(sq->curr_tx_wqe.md, sq, op_type); - sq->curr_tx_wqe.md->req_id = efa_wq_get_dev_req_id_locked(&sq->wq, ibvqpx->wr_id); + efa_set_sq_comp_wrid(sq->curr_tx_wqe.md, &sq->wq, ibvqpx->wr_id); /* advance index and change phase */ efa_sq_advance_post_idx(sq);