Merge pull request #1793 from yishaih/misc
[mlx4, mthca]: Fix signed-overflow as part of cq cleanup
diff --git a/debian/ibverbs-providers.symbols b/debian/ibverbs-providers.symbols
index 40e627d..044b4c9 100644
--- a/debian/ibverbs-providers.symbols
+++ b/debian/ibverbs-providers.symbols
@@ -211,8 +211,10 @@
libmana.so.1 ibverbs-providers #MINVER#
* Build-Depends-Package: libibverbs-dev
MANA_1.0@MANA_1.0 41
+ MANA_1.1@MANA_1.1 65
manadv_init_obj@MANA_1.0 41
manadv_set_context_attr@MANA_1.0 41
+ manadv_alloc_pd@MANA_1.1 65
libionic.so.1 ibverbs-providers #MINVER#
* Build-Depends-Package: libibverbs-dev
IONIC_1.0@IONIC_1.0 59
diff --git a/kernel-headers/rdma/mana-abi.h b/kernel-headers/rdma/mana-abi.h
index a75bf32..32cbbfc 100644
--- a/kernel-headers/rdma/mana-abi.h
+++ b/kernel-headers/rdma/mana-abi.h
@@ -25,7 +25,7 @@
struct mana_ib_create_cq {
__aligned_u64 buf_addr;
- __u16 flags;
+ __u16 comp_mask;
__u16 reserved0;
__u32 reserved1;
};
@@ -57,6 +57,17 @@
__u32 queue_id[4];
};
+struct mana_ib_create_uc_qp {
+ __aligned_u64 queue_buf[3];
+ __u32 queue_size[3];
+ __u32 comp_mask;
+};
+
+struct mana_ib_create_uc_qp_resp {
+ __u32 queue_id[3];
+ __u32 reserved;
+};
+
struct mana_ib_create_wq {
__aligned_u64 wq_buf_addr;
__u32 wq_buf_size;
@@ -87,4 +98,26 @@
struct rss_resp_entry entries[64];
};
+enum mana_ib_ucontext_support {
+ MANA_IB_UCNTX_ALLOC_PDN_SUPPORT = 1 << 0,
+};
+
+struct mana_ib_alloc_ucontext_resp {
+ __aligned_u64 comp_mask;
+};
+
+enum mana_ib_create_pd_flags {
+ MANA_IB_PD_SHORT_PDN = 1 << 0,
+};
+
+struct mana_ib_alloc_pd {
+ __u32 comp_mask;
+ __u32 reserved;
+};
+
+struct mana_ib_alloc_pd_resp {
+ __u32 pdn;
+ __u32 reserved;
+};
+
#endif
diff --git a/providers/mana/CMakeLists.txt b/providers/mana/CMakeLists.txt
index 05011be..3ae2b02 100644
--- a/providers/mana/CMakeLists.txt
+++ b/providers/mana/CMakeLists.txt
@@ -1,5 +1,5 @@
rdma_shared_provider(mana libmana.map
- 1 1.0.${PACKAGE_VERSION}
+ 1 1.1.${PACKAGE_VERSION}
mana.c
manadv.c
qp.c
diff --git a/providers/mana/cq.c b/providers/mana/cq.c
index 367d5a2..09da80c 100644
--- a/providers/mana/cq.c
+++ b/providers/mana/cq.c
@@ -165,7 +165,7 @@
cmd_drv = &cmd.drv_payload;
cmd_drv->buf_addr = (uintptr_t)cq->buf;
- cmd_drv->flags = flags;
+ cmd_drv->comp_mask = flags;
resp.cqid = UINT32_MAX;
ret = ibv_cmd_create_cq(context, cq->cqe, channel, comp_vector,
@@ -284,6 +284,25 @@
return produced;
}
+static inline int handle_requester_cqe(struct mana_qp *qp, struct gdma_cqe *cqe, struct ibv_wc *wc)
+{
+ struct mana_gdma_queue *send_queue = mana_ib_get_sreq(qp);
+ struct shadow_wqe_header *wqe;
+ int produced = 0;
+
+ while (!produced && (wqe = shadow_queue_get_next_to_consume(&qp->shadow_sq)) != NULL) {
+ send_queue->cons_idx += wqe->posted_wqe_size_in_bu;
+ send_queue->cons_idx &= GDMA_QUEUE_OFFSET_MASK;
+ if (wqe->flags != MANA_NO_SIGNAL_WC) {
+ fill_verbs_from_shadow_wqe(qp, wc, wqe);
+ produced++;
+ }
+ shadow_queue_advance_consumer(&qp->shadow_sq);
+ }
+
+ return produced;
+}
+
static inline int handle_rc_requester_cqe(struct mana_qp *qp, struct gdma_cqe *cqe,
struct ibv_wc *wc, int nwc, bool *consumed)
{
@@ -443,6 +462,8 @@
return handle_error_cqe(qp, cqe, wc, nwc, consumed);
else if (cqe->rdma_cqe.cqe_type == CQE_TYPE_ARMED_CMPL)
return handle_rc_requester_cqe(qp, cqe, wc, nwc, consumed);
+ else if (cqe->is_sq && cqe->rdma_cqe.cqe_type == CQE_TYPE_UD_SEND)
+ return handle_requester_cqe(qp, cqe, wc);
else
return handle_responder_cqe(qp, cqe, wc);
}
diff --git a/providers/mana/doorbells.h b/providers/mana/doorbells.h
index d805cdb..7651e76 100644
--- a/providers/mana/doorbells.h
+++ b/providers/mana/doorbells.h
@@ -87,6 +87,16 @@
mmio_flush_writes();
}
+/* Has HW already produced the CQE at this index? Owner bits are written by HW,
+ * so a match proves idx < cur_cqe. Only meaningful for idx >= cq->head.
+ */
+static inline bool gdma_cq_idx_produced(struct mana_cq *cq, uint32_t idx)
+{
+ struct gdma_cqe *cqe = ((struct gdma_cqe *)cq->buf) + (idx % cq->cqe);
+
+ return cqe->owner_bits == ((idx / cq->cqe) & CQ_OWNER_MASK);
+}
+
static inline void gdma_ring_cq_doorbell(struct mana_cq *cq, uint8_t arm)
{
union gdma_doorbell_entry e;
@@ -94,8 +104,14 @@
uint32_t max_credit = cq->cqe << (GDMA_CQE_OWNER_BITS - 1);
if (cq->poll_credit >= max_credit) {
- // To address the use-case of ibv that re-arms the CQ without polling
- cq->poll_credit++;
+ // To address the use-case of ibv that re-arms the CQ without polling.
+ // (prod_idx + poll_credit - max_credit) is the index last given to HW,
+ // so only claim the next one once HW has produced it. Nothing produced
+ // implies no notification fired, so the CQ is still armed.
+ if (gdma_cq_idx_produced(cq, prod_idx + cq->poll_credit - max_credit))
+ cq->poll_credit++;
+ else
+ return;
} else {
// Set index of already polled CQE for unarm
cq->poll_credit = max_credit - (arm ? 0 : 1);
diff --git a/providers/mana/libmana.map b/providers/mana/libmana.map
index ab66295..24af016 100644
--- a/providers/mana/libmana.map
+++ b/providers/mana/libmana.map
@@ -6,3 +6,8 @@
manadv_init_obj;
local: *;
};
+
+MANA_1.1 {
+ global:
+ manadv_alloc_pd;
+} MANA_1.0;
diff --git a/providers/mana/man/CMakeLists.txt b/providers/mana/man/CMakeLists.txt
index 24f1859..3458443 100644
--- a/providers/mana/man/CMakeLists.txt
+++ b/providers/mana/man/CMakeLists.txt
@@ -2,4 +2,5 @@
manadv.7.md
manadv_init_obj.3.md
manadv_set_context_attr.3.md
+ manadv_alloc_pd.3.md
)
diff --git a/providers/mana/man/manadv_alloc_pd.3.md b/providers/mana/man/manadv_alloc_pd.3.md
new file mode 100644
index 0000000..b121ea2
--- /dev/null
+++ b/providers/mana/man/manadv_alloc_pd.3.md
@@ -0,0 +1,36 @@
+---
+layout: page
+title: manadv_alloc_pd
+section: 3
+tagline: Verbs
+---
+
+# NAME
+manadv_alloc_pd \- Create a MANA specific PD for the RDMA device context.
+
+# SYNOPSIS"
+```c
+#include <infiniband/manadv.h>
+
+struct ibv_pd *manadv_alloc_pd(struct ibv_context *context, uint32_t flags);
+```
+
+# DESCRIPTION
+**manadv_alloc_pd()** allocates a PD for the RDMA device context with additional
+creation flags.
+
+# ARGUMENTS
+*context*
+: RDMA device context to work on.
+
+*flags*
+: A bitwise OR of the various values described below.
+
+ MANADV_PD_FLAGS_SHORT_PDN:
+ allocates a PD with 16 bit PDN.
+
+# RETURN VALUE
+returns a pointer to the allocated PD, or NULL if the request fails.
+
+# AUTHORS
+Konstantin Taranov <kotaranov@microsoft.com>
diff --git a/providers/mana/man/manadv_init_obj.3.md b/providers/mana/man/manadv_init_obj.3.md
index 575ea34..a4dd712 100644
--- a/providers/mana/man/manadv_init_obj.3.md
+++ b/providers/mana/man/manadv_init_obj.3.md
@@ -48,6 +48,10 @@
void *db_page;
};
+struct manadv_pd {
+ uint32_t pdn;
+};
+
struct manadv_obj {
struct {
struct ibv_qp *in;
@@ -63,6 +67,11 @@
struct ibv_wq *in;
struct manadv_rwq *out;
} rwq;
+
+ struct {
+ struct ibv_pd *in;
+ struct manadv_pd *out;
+ } pd;
};
```
@@ -74,6 +83,7 @@
MANADV_OBJ_QP = 1 << 0,
MANADV_OBJ_CQ = 1 << 1,
MANADV_OBJ_RWQ = 1 << 2,
+ MANADV_OBJ_PD = 1 << 3,
};
```
# RETURN VALUE
diff --git a/providers/mana/mana.c b/providers/mana/mana.c
index a59248b..87411d4 100644
--- a/providers/mana/mana.c
+++ b/providers/mana/mana.c
@@ -21,9 +21,10 @@
#include "mana.h"
DECLARE_DRV_CMD(mana_alloc_ucontext, IB_USER_VERBS_CMD_GET_CONTEXT, empty,
- empty);
+ mana_ib_alloc_ucontext_resp);
-DECLARE_DRV_CMD(mana_alloc_pd, IB_USER_VERBS_CMD_ALLOC_PD, empty, empty);
+DECLARE_DRV_CMD(mana_alloc_pd, IB_USER_VERBS_CMD_ALLOC_PD, mana_ib_alloc_pd,
+ mana_ib_alloc_pd_resp);
static const struct verbs_match_ent hca_table[] = {
VERBS_DRIVER_ID(RDMA_DRIVER_MANA),
@@ -114,19 +115,34 @@
return ibv_cmd_query_port(context, port, attr, &cmd, sizeof(cmd));
}
-struct ibv_pd *mana_alloc_pd(struct ibv_context *context)
+struct ibv_pd *mana_alloc_pd_ex(struct ibv_context *context, uint32_t flags)
{
- struct ibv_alloc_pd cmd;
- struct mana_alloc_pd_resp resp;
+ struct mana_context *mctx = to_mctx(context);
+ struct mana_alloc_pd cmd = {};
+ struct mana_ib_alloc_pd *cmd_drv = &cmd.drv_payload;
+ struct mana_alloc_pd_resp resp = {};
+ size_t cmd_size = sizeof(cmd.ibv_cmd); /* v0 size */
struct mana_pd *pd;
int ret;
+ if ((flags & MANADV_PD_FLAGS_SHORT_PDN) &&
+ !(mctx->comp_mask & MANA_IB_UCNTX_ALLOC_PDN_SUPPORT)) {
+ errno = EOPNOTSUPP;
+ return NULL;
+ }
+
pd = calloc(1, sizeof(*pd));
if (!pd)
return NULL;
- ret = ibv_cmd_alloc_pd(context, &pd->ibv_pd, &cmd, sizeof(cmd),
- &resp.ibv_resp, sizeof(resp));
+ if (mctx->comp_mask & MANA_IB_UCNTX_ALLOC_PDN_SUPPORT)
+ cmd_size = sizeof(cmd); /* v1 size */
+
+ if (flags & MANADV_PD_FLAGS_SHORT_PDN)
+ cmd_drv->comp_mask |= MANA_IB_PD_SHORT_PDN;
+
+ ret = ibv_cmd_alloc_pd(context, &pd->ibv_pd, &cmd.ibv_cmd, cmd_size,
+ &resp.ibv_resp, sizeof(resp));
if (ret) {
verbs_err(verbs_get_ctx(context), "Failed to allocate PD\n");
errno = ret;
@@ -134,9 +150,16 @@
return NULL;
}
+ pd->pdn = resp.pdn;
+
return &pd->ibv_pd;
}
+static struct ibv_pd *mana_alloc_pd(struct ibv_context *context)
+{
+ return mana_alloc_pd_ex(context, 0);
+}
+
struct ibv_pd *
mana_alloc_parent_domain(struct ibv_context *context,
struct ibv_parent_domain_init_attr *attr)
@@ -452,7 +475,7 @@
{
int ret, i;
struct mana_context *context;
- struct mana_alloc_ucontext_resp resp;
+ struct mana_alloc_ucontext_resp resp = {};
struct ibv_get_context cmd;
context = verbs_init_and_alloc_context(ibdev, cmd_fd, context, ibv_ctx,
@@ -468,6 +491,8 @@
goto free_ctx;
}
+ context->comp_mask = resp.drv_payload.comp_mask;
+
verbs_set_ops(&context->ibv_ctx, &mana_ctx_ops);
pthread_mutex_init(&context->qp_table_mutex, NULL);
diff --git a/providers/mana/mana.h b/providers/mana/mana.h
index 1f8a147..98318d1 100644
--- a/providers/mana/mana.h
+++ b/providers/mana/mana.h
@@ -49,7 +49,8 @@
USER_RNIC_SEND_QUEUE_RESPONDER = 1,
USER_RNIC_RECV_QUEUE_REQUESTER = 2,
USER_RNIC_RECV_QUEUE_RESPONDER = 3,
- USER_RNIC_QUEUE_TYPE_MAX = 4,
+ USER_RNIC_SEND_QUEUE_MM = 4,
+ USER_RNIC_QUEUE_TYPE_MAX = 5,
};
#define QUEUE_TYPE_MASK 0x3
@@ -89,6 +90,7 @@
struct mana_table qp_rtable[MANA_QP_TABLE_SIZE];
struct mana_table qp_stable[MANA_QP_TABLE_SIZE];
pthread_mutex_t qp_table_mutex;
+ uint64_t comp_mask;
struct manadv_ctx_allocators extern_alloc;
void *db_page;
@@ -196,6 +198,7 @@
struct mana_pd {
struct ibv_pd ibv_pd;
+ uint32_t pdn;
struct mana_pd *mprotection_domain;
};
@@ -216,7 +219,7 @@
int mana_query_port(struct ibv_context *context, uint8_t port,
struct ibv_port_attr *attr);
-struct ibv_pd *mana_alloc_pd(struct ibv_context *context);
+struct ibv_pd *mana_alloc_pd_ex(struct ibv_context *context, uint32_t flags);
struct ibv_pd *
mana_alloc_parent_domain(struct ibv_context *context,
struct ibv_parent_domain_init_attr *attr);
diff --git a/providers/mana/manadv.c b/providers/mana/manadv.c
index 4b40d05..2392adf 100644
--- a/providers/mana/manadv.c
+++ b/providers/mana/manadv.c
@@ -42,7 +42,7 @@
int manadv_init_obj(struct manadv_obj *obj, uint64_t obj_type)
{
- if (obj_type & ~(MANADV_OBJ_QP | MANADV_OBJ_CQ | MANADV_OBJ_RWQ))
+ if (obj_type & ~(MANADV_OBJ_QP | MANADV_OBJ_CQ | MANADV_OBJ_RWQ | MANADV_OBJ_PD))
return EINVAL;
if (obj_type & MANADV_OBJ_QP) {
@@ -84,5 +84,17 @@
obj->rwq.out->db_page = ctx->db_page;
}
+ if (obj_type & MANADV_OBJ_PD) {
+ struct ibv_pd *ibpd = obj->pd.in;
+ struct mana_pd *pd = container_of(ibpd, struct mana_pd, ibv_pd);
+
+ obj->pd.out->pdn = pd->pdn;
+ }
+
return 0;
}
+
+struct ibv_pd *manadv_alloc_pd(struct ibv_context *context, uint32_t flags)
+{
+ return mana_alloc_pd_ex(context, flags);
+}
diff --git a/providers/mana/manadv.h b/providers/mana/manadv.h
index 27c8fe9..87f6e8f 100644
--- a/providers/mana/manadv.h
+++ b/providers/mana/manadv.h
@@ -52,6 +52,10 @@
void *db_page;
};
+struct manadv_pd {
+ uint32_t pdn;
+};
+
struct manadv_obj {
struct {
struct ibv_qp *in;
@@ -67,16 +71,27 @@
struct ibv_wq *in;
struct manadv_rwq *out;
} rwq;
+ struct {
+ struct ibv_pd *in;
+ struct manadv_pd *out;
+ } pd;
};
enum manadv_obj_type {
MANADV_OBJ_QP = 1 << 0,
MANADV_OBJ_CQ = 1 << 1,
MANADV_OBJ_RWQ = 1 << 2,
+ MANADV_OBJ_PD = 1 << 3,
+};
+
+enum {
+ MANADV_PD_FLAGS_SHORT_PDN = 1 << 0,
};
int manadv_init_obj(struct manadv_obj *obj, uint64_t obj_type);
+struct ibv_pd *manadv_alloc_pd(struct ibv_context *context, uint32_t flags);
+
#ifdef __cplusplus
}
#endif
diff --git a/providers/mana/qp.c b/providers/mana/qp.c
index b6a9a7e..752959b 100644
--- a/providers/mana/qp.c
+++ b/providers/mana/qp.c
@@ -31,6 +31,9 @@
DECLARE_DRV_CMD(mana_create_rc_qp, IB_USER_VERBS_CMD_CREATE_QP,
mana_ib_create_rc_qp, mana_ib_create_rc_qp_resp);
+DECLARE_DRV_CMD(mana_create_uc_qp, IB_USER_VERBS_CMD_CREATE_QP,
+ mana_ib_create_uc_qp, mana_ib_create_uc_qp_resp);
+
static struct ibv_qp *mana_create_qp_raw(struct ibv_pd *ibpd,
struct ibv_qp_init_attr *attr)
{
@@ -216,46 +219,142 @@
uint32_t size = 0;
uint32_t sges = 0;
- if (attr->qp_type == IBV_QPT_RC) {
- switch (type) {
- case USER_RNIC_SEND_QUEUE_REQUESTER:
- /* WQE must have at least one SGE */
- /* For write with imm we need one extra SGE */
- sges = max(1U, attr->cap.max_send_sge) + 1;
- size = attr->cap.max_send_wr * get_large_wqe_size(sges);
- break;
- case USER_RNIC_SEND_QUEUE_RESPONDER:
- size = MANA_PAGE_SIZE;
- break;
- case USER_RNIC_RECV_QUEUE_REQUESTER:
- size = MANA_PAGE_SIZE;
- break;
- case USER_RNIC_RECV_QUEUE_RESPONDER:
- /* WQE must have at least one SGE */
- sges = max(1U, attr->cap.max_recv_sge);
- size = attr->cap.max_recv_wr * get_wqe_size(sges);
- break;
- default:
- return 0;
- }
+ switch (type) {
+ case USER_RNIC_SEND_QUEUE_REQUESTER:
+ /* WQE must have at least one SGE */
+ /* For write with imm we need one extra SGE */
+ sges = max(1U, attr->cap.max_send_sge) + 1;
+ size = align_hw_size(attr->cap.max_send_wr * get_large_wqe_size(sges));
+ break;
+ case USER_RNIC_SEND_QUEUE_RESPONDER:
+ if (attr->qp_type == IBV_QPT_RC)
+ size = align_hw_size(MANA_PAGE_SIZE);
+ break;
+ case USER_RNIC_RECV_QUEUE_REQUESTER:
+ if (attr->qp_type == IBV_QPT_RC)
+ size = align_hw_size(MANA_PAGE_SIZE);
+ break;
+ case USER_RNIC_RECV_QUEUE_RESPONDER:
+ /* WQE must have at least one SGE */
+ sges = max(1U, attr->cap.max_recv_sge);
+ size = align_hw_size(attr->cap.max_recv_wr * get_wqe_size(sges));
+ break;
+ case USER_RNIC_SEND_QUEUE_MM:
+ sges = 2;
+ size = align_hw_size(attr->cap.max_send_wr * get_large_wqe_size(sges));
+ break;
+ default:
+ return 0;
}
- size = align_hw_size(size);
-
if (attr->qp_type == IBV_QPT_RC && type == USER_RNIC_SEND_QUEUE_REQUESTER)
size += sizeof(struct mana_ib_rollback_shared_mem);
return size;
}
-static struct ibv_qp *mana_create_qp_rnic(struct ibv_pd *ibpd,
- struct ibv_qp_init_attr *attr)
+static int mana_create_cmd_qp_rc(struct mana_qp *qp, struct ibv_pd *ibpd,
+ struct ibv_qp_init_attr *attr)
{
- struct mana_context *ctx = to_mctx(ibpd->context);
struct mana_ib_create_rc_qp_resp *qp_resp_drv;
struct mana_create_rc_qp_resp qp_resp = {};
struct mana_ib_create_rc_qp *qp_cmd_drv;
struct mana_create_rc_qp qp_cmd = {};
+ int ret, i;
+
+ qp_cmd_drv = &qp_cmd.drv_payload;
+ qp_resp_drv = &qp_resp.drv_payload;
+
+ for (i = 0; i < USER_RNIC_QUEUE_TYPE_MAX; ++i) {
+ if (i == USER_RNIC_SEND_QUEUE_MM)
+ continue;
+ qp_cmd_drv->queue_buf[i] = (uintptr_t)qp->rnic_qp.queues[i].buffer;
+ qp_cmd_drv->queue_size[i] = qp->rnic_qp.queues[i].size;
+ }
+
+ ret = ibv_cmd_create_qp(ibpd, &qp->ibqp.qp, attr, &qp_cmd.ibv_cmd,
+ sizeof(qp_cmd), &qp_resp.ibv_resp,
+ sizeof(qp_resp));
+ if (ret) {
+ verbs_err(verbs_get_ctx(ibpd->context), "Create QP failed\n");
+ return ret;
+ }
+
+ for (i = 0; i < USER_RNIC_QUEUE_TYPE_MAX; ++i) {
+ if (i == USER_RNIC_SEND_QUEUE_MM)
+ continue;
+ qp->rnic_qp.queues[i].id = qp_resp_drv->queue_id[i];
+ }
+
+ return 0;
+}
+
+enum {
+ MANA_UC_UDATA_SQR = 0,
+ MANA_UC_UDATA_RQR = 1,
+ MANA_UC_UDATA_SMQ = 2,
+};
+
+static int mana_create_cmd_qp_uc(struct mana_qp *qp, struct ibv_pd *ibpd,
+ struct ibv_qp_init_attr *attr)
+{
+ struct mana_ib_create_uc_qp_resp *qp_resp_drv;
+ struct mana_create_uc_qp_resp qp_resp = {};
+ struct mana_ib_create_uc_qp *qp_cmd_drv;
+ struct mana_create_uc_qp qp_cmd = {};
+ int ret;
+
+ qp_cmd_drv = &qp_cmd.drv_payload;
+ qp_resp_drv = &qp_resp.drv_payload;
+
+ qp_cmd_drv->queue_buf[MANA_UC_UDATA_SQR] =
+ (uintptr_t)qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_REQUESTER].buffer;
+ qp_cmd_drv->queue_size[MANA_UC_UDATA_SQR] =
+ qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_REQUESTER].size;
+
+ qp_cmd_drv->queue_buf[MANA_UC_UDATA_RQR] =
+ (uintptr_t)qp->rnic_qp.queues[USER_RNIC_RECV_QUEUE_RESPONDER].buffer;
+ qp_cmd_drv->queue_size[MANA_UC_UDATA_RQR] =
+ qp->rnic_qp.queues[USER_RNIC_RECV_QUEUE_RESPONDER].size;
+
+ qp_cmd_drv->queue_buf[MANA_UC_UDATA_SMQ] =
+ (uintptr_t)qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_MM].buffer;
+ qp_cmd_drv->queue_size[MANA_UC_UDATA_SMQ] =
+ qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_MM].size;
+
+ ret = ibv_cmd_create_qp(ibpd, &qp->ibqp.qp, attr, &qp_cmd.ibv_cmd,
+ sizeof(qp_cmd), &qp_resp.ibv_resp,
+ sizeof(qp_resp));
+ if (ret) {
+ verbs_err(verbs_get_ctx(ibpd->context), "Create QP failed\n");
+ return ret;
+ }
+
+ qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_REQUESTER].id =
+ qp_resp_drv->queue_id[MANA_UC_UDATA_SQR];
+ qp->rnic_qp.queues[USER_RNIC_RECV_QUEUE_RESPONDER].id =
+ qp_resp_drv->queue_id[MANA_UC_UDATA_RQR];
+ qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_MM].id =
+ qp_resp_drv->queue_id[MANA_UC_UDATA_SMQ];
+
+ return 0;
+}
+
+static int mana_create_cmd_qp(struct mana_qp *qp, struct ibv_pd *ibpd,
+ struct ibv_qp_init_attr *attr)
+{
+ if (attr->qp_type == IBV_QPT_RC)
+ return mana_create_cmd_qp_rc(qp, ibpd, attr);
+ else if (attr->qp_type == IBV_QPT_UC)
+ return mana_create_cmd_qp_uc(qp, ibpd, attr);
+ else
+ return -EOPNOTSUPP;
+}
+
+static struct ibv_qp *mana_create_qp_rnic(struct ibv_pd *ibpd,
+ struct ibv_qp_init_attr *attr)
+{
+ struct mana_context *ctx = to_mctx(ibpd->context);
struct mana_qp *qp;
int ret, i;
@@ -263,9 +362,6 @@
if (!qp)
return NULL;
- qp_cmd_drv = &qp_cmd.drv_payload;
- qp_resp_drv = &qp_resp.drv_payload;
-
pthread_spin_init(&qp->sq_lock, PTHREAD_PROCESS_PRIVATE);
pthread_spin_init(&qp->rq_lock, PTHREAD_PROCESS_PRIVATE);
qp->sq_sig_all = attr->sq_sig_all;
@@ -291,29 +387,18 @@
if (qp->rnic_qp.queues[i].size != 0 && !qp->rnic_qp.queues[i].buffer) {
verbs_err(verbs_get_ctx(ibpd->context),
- "Failed to allocate memory for RC queue %d\n", i);
+ "Failed to allocate memory for queue %d\n", i);
errno = ENOMEM;
goto destroy_queues;
}
-
- qp_cmd_drv->queue_buf[i] = (uintptr_t)qp->rnic_qp.queues[i].buffer;
- qp_cmd_drv->queue_size[i] = qp->rnic_qp.queues[i].size;
}
- mana_ib_init_rb_shmem(qp);
-
- ret = ibv_cmd_create_qp(ibpd, &qp->ibqp.qp, attr, &qp_cmd.ibv_cmd,
- sizeof(qp_cmd), &qp_resp.ibv_resp,
- sizeof(qp_resp));
+ ret = mana_create_cmd_qp(qp, ibpd, attr);
if (ret) {
- verbs_err(verbs_get_ctx(ibpd->context), "Create QP failed\n");
errno = ret;
- goto free_rb;
+ goto destroy_queues;
}
- for (i = 0; i < USER_RNIC_QUEUE_TYPE_MAX; ++i)
- qp->rnic_qp.queues[i].id = qp_resp_drv->queue_id[i];
-
qp->ibqp.qp.qp_num = qp->rnic_qp.queues[USER_RNIC_RECV_QUEUE_RESPONDER].id;
ret = mana_store_qp(ctx, qp);
@@ -322,12 +407,12 @@
goto destroy_qp;
}
+ mana_ib_init_rb_shmem(qp);
+
return &qp->ibqp.qp;
destroy_qp:
ibv_cmd_destroy_qp(&qp->ibqp.qp);
-free_rb:
- mana_ib_deinit_rb_shmem(qp);
destroy_queues:
while (i-- > 0)
mana_dealloc_mem(qp->rnic_qp.queues[i].buffer, qp->rnic_qp.queues[i].size);
@@ -346,6 +431,7 @@
case IBV_QPT_RAW_PACKET:
return mana_create_qp_raw(ibpd, attr);
case IBV_QPT_RC:
+ case IBV_QPT_UC:
return mana_create_qp_rnic(ibpd, attr);
default:
verbs_err(verbs_get_ctx(ibpd->context),
@@ -382,7 +468,8 @@
if (attr_mask & IBV_QP_SQ_PSN) {
qp->sq_ssn = 1;
qp->sq_psn = attr->sq_psn;
- gdma_arm_normal_cqe(mana_ib_get_rreq(qp), attr->sq_psn);
+ if (qp->ibqp.qp.qp_type == IBV_QPT_RC)
+ gdma_arm_normal_cqe(mana_ib_get_rreq(qp), attr->sq_psn);
}
break;
default:
@@ -397,7 +484,7 @@
struct ibv_modify_qp cmd = {};
int err;
- if (ibqp->qp_type != IBV_QPT_RC)
+ if (ibqp->qp_type != IBV_QPT_RC && ibqp->qp_type != IBV_QPT_UC)
return EOPNOTSUPP;
pthread_spin_lock(&qp->sq_lock);
@@ -443,7 +530,7 @@
struct mana_context *ctx = to_mctx(ibqp->context);
int ret, i;
- if (ibqp->qp_type == IBV_QPT_RC) {
+ if (ibqp->qp_type == IBV_QPT_RC || ibqp->qp_type == IBV_QPT_UC) {
mana_remove_qp(ctx, qp);
mana_drain_cqes(qp);
}
@@ -459,6 +546,7 @@
ctx->extern_alloc.free(qp->raw_qp.send_buf, ctx->extern_alloc.data);
break;
case IBV_QPT_RC:
+ case IBV_QPT_UC:
pthread_spin_destroy(&qp->sq_lock);
pthread_spin_destroy(&qp->rq_lock);
destroy_shadow_queue(&qp->shadow_sq);
diff --git a/providers/mana/rollback.h b/providers/mana/rollback.h
index 59621a5..c908f3f 100644
--- a/providers/mana/rollback.h
+++ b/providers/mana/rollback.h
@@ -39,6 +39,8 @@
static inline void mana_ib_init_rb_shmem(struct mana_qp *qp)
{
+ if (qp->ibqp.qp.qp_type != IBV_QPT_RC)
+ return;
// take some bytes for rollback memory
struct mana_gdma_queue *req_sq =
&qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_REQUESTER];
@@ -54,6 +56,8 @@
static inline void mana_ib_deinit_rb_shmem(struct mana_qp *qp)
{
+ if (qp->ibqp.qp.qp_type != IBV_QPT_RC)
+ return;
// return back bytes for rollback memory
struct mana_gdma_queue *req_sq =
&qp->rnic_qp.queues[USER_RNIC_SEND_QUEUE_REQUESTER];
@@ -62,6 +66,9 @@
static inline void mana_ib_reset_rb_shmem(struct mana_qp *qp)
{
+ if (qp->ibqp.qp.qp_type != IBV_QPT_RC)
+ return;
+
struct mana_ib_rollback_shared_mem *rb_shmem =
mana_ib_get_rollback_sh_mem(qp);
@@ -71,6 +78,9 @@
static inline void mana_ib_update_shared_mem_right_offset(struct mana_qp *qp, uint32_t offset_in_bu)
{
+ if (qp->ibqp.qp.qp_type != IBV_QPT_RC)
+ return;
+
struct mana_ib_rollback_shared_mem *rb_shmem =
mana_ib_get_rollback_sh_mem(qp);
diff --git a/providers/mana/wr.c b/providers/mana/wr.c
index 88ee8ad..e4d7c38 100644
--- a/providers/mana/wr.c
+++ b/providers/mana/wr.c
@@ -191,6 +191,7 @@
{
switch (ibqp->qp_type) {
case IBV_QPT_RC:
+ case IBV_QPT_UC:
return mana_ib_post_recv(ibqp, wr, bad);
default:
verbs_err(verbs_get_ctx(ibqp->context), "QPT not supported %d\n", ibqp->qp_type);
@@ -350,7 +351,7 @@
&send_oob, oob_sge, num_sge, MTU_SIZE(qp->mtu), flags, &gdma_wqe);
if (ret) {
verbs_err(verbs_get_ctx(qp->ibqp.qp.context),
- "rc post send error, ret %d\n", ret);
+ "post send error, ret %d\n", ret);
goto cleanup;
}
@@ -430,6 +431,7 @@
{
switch (ibqp->qp_type) {
case IBV_QPT_RC:
+ case IBV_QPT_UC:
return mana_ib_post_send(ibqp, wr, bad);
default:
verbs_err(verbs_get_ctx(ibqp->context), "QPT not supported %d\n", ibqp->qp_type);
diff --git a/providers/mlx5/cq.c b/providers/mlx5/cq.c
index eeaf4e6..f892658 100644
--- a/providers/mlx5/cq.c
+++ b/providers/mlx5/cq.c
@@ -1842,7 +1842,8 @@
* that match our QP by copying older entries on top of them.
*/
cqe_version = (to_mctx(cq->verbs_cq.cq.context))->cqe_version;
- while ((int) --prod_index - (int) cq->cons_index >= 0) {
+ while (prod_index != cq->cons_index) {
+ --prod_index;
cqe = get_cqe(cq, prod_index & cq->verbs_cq.cq.cqe);
cqe64 = (cq->cqe_sz == 64) ? cqe : cqe + 64;
if (free_res_cqe(cqe64, rsn, srq, cqe_version)) {
diff --git a/providers/mlx5/dbrec.c b/providers/mlx5/dbrec.c
index c5d1c3f..ae99cd9 100644
--- a/providers/mlx5/dbrec.c
+++ b/providers/mlx5/dbrec.c
@@ -105,8 +105,10 @@
mparent_domain->pd_context, 8, 8,
MLX5DV_RES_TYPE_DBR);
- if (db == IBV_ALLOCATOR_USE_DEFAULT)
+ if (db == IBV_ALLOCATOR_USE_DEFAULT) {
+ db = NULL;
goto default_alloc;
+ }
if (!db)
return NULL;