From 084046597bb1f856baae511dfe70e041629af1f4 Mon Sep 17 00:00:00 2001 From: Saravanan Vajravel Date: Thu, 9 Nov 2023 00:24:17 -0800 Subject: [PATCH] bnxt_re/lib: Add check for device atomic capability Adds a check in lib for atomic_cap when processing IB_ATOMIC_WR. If atomic capability is not set, fail the WR. Also, fail if any atomic requests which has more than 1 SGE. Signed-off-by: Damodharam Ammepalli Signed-off-by: Hongguang Gao Signed-off-by: Saravanan Vajravel Signed-off-by: Selvin Xavier --- providers/bnxt_re/main.h | 1 + providers/bnxt_re/verbs.c | 34 +++++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/providers/bnxt_re/main.h b/providers/bnxt_re/main.h index d14739674..dbc234d79 100644 --- a/providers/bnxt_re/main.h +++ b/providers/bnxt_re/main.h @@ -146,6 +146,7 @@ struct bnxt_re_qpcap { uint32_t max_rsge; uint32_t max_inline; uint8_t sqsig; + uint8_t is_atomic_cap; }; struct bnxt_re_srq { diff --git a/providers/bnxt_re/verbs.c b/providers/bnxt_re/verbs.c index b0f4cb083..dd9b3591c 100644 --- a/providers/bnxt_re/verbs.c +++ b/providers/bnxt_re/verbs.c @@ -1339,6 +1339,7 @@ struct ibv_qp *bnxt_re_create_qp(struct ibv_pd *ibvpd, cap->max_rsge = attr->cap.max_recv_sge; cap->max_inline = attr->cap.max_inline_data; cap->sqsig = attr->sq_sig_all; + cap->is_atomic_cap = dev->devattr.atomic_cap; fque_init_node(&qp->snode); fque_init_node(&qp->rnode); @@ -1651,6 +1652,12 @@ static int bnxt_re_build_ud_sqe(struct ibv_send_wr *wr, return 0; } +static bool __atomic_not_supported(struct bnxt_re_qp *qp, struct ibv_send_wr *wr) +{ + /* Atomic capability disabled or the request has more than 1 SGE */ + return (!qp->cap.is_atomic_cap || wr->num_sge > 1); +} + static void bnxt_re_build_cns_sqe(struct ibv_send_wr *wr, struct bnxt_re_bsqe *hdr, void *hdr2) @@ -1674,6 +1681,25 @@ static void bnxt_re_build_fna_sqe(struct ibv_send_wr *wr, sqe->swp_dt = htole64(wr->wr.atomic.compare_add); } +static int bnxt_re_build_atomic_sqe(struct bnxt_re_qp *qp, + struct ibv_send_wr *wr, + struct bnxt_re_bsqe *hdr, + void *hdr2) +{ + if (__atomic_not_supported(qp, wr)) + return -EINVAL; + switch (wr->opcode) { + case IBV_WR_ATOMIC_CMP_AND_SWP: + bnxt_re_build_cns_sqe(wr, hdr, hdr2); + return 0; + case IBV_WR_ATOMIC_FETCH_AND_ADD: + bnxt_re_build_fna_sqe(wr, hdr, hdr2); + return 0; + default: + return -EINVAL; + } +} + static void bnxt_re_force_rts2rts(struct bnxt_re_qp *qp) { struct ibv_qp_attr attr; @@ -1766,10 +1792,12 @@ int bnxt_re_post_send(struct ibv_qp *ibvqp, struct ibv_send_wr *wr, rsqe->rkey = htole32(wr->wr.rdma.rkey); break; case IBV_WR_ATOMIC_CMP_AND_SWP: - bnxt_re_build_cns_sqe(wr, hdr, sqe); - break; case IBV_WR_ATOMIC_FETCH_AND_ADD: - bnxt_re_build_fna_sqe(wr, hdr, sqe); + if (bnxt_re_build_atomic_sqe(qp, wr, hdr, sqe)) { + ret = EINVAL; + *bad = wr; + goto bad_wr; + } break; default: ret = -EINVAL;