git: 054db357a1a5 - main - libcxgb4: Support for RDMA SEND_WITH_INV requests

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Tue, 15 Sep 2026 14:47:43 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=054db357a1a5282f205cd0d1827fb4cd19833d55

commit 054db357a1a5282f205cd0d1827fb4cd19833d55
Author:     Potnuri Bharat Teja <bharat@chelsio.com>
AuthorDate: 2018-11-16 10:17:52 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-09-15 14:22:39 +0000

    libcxgb4: Support for RDMA SEND_WITH_INV requests
    
    Sponsored by:   Chelsio Communications
---
 contrib/ofed/libcxgb4/cq.c      | 25 ++++++++++++++++++++++---
 contrib/ofed/libcxgb4/qp.c      | 35 +++++++++++++++++++++++++++--------
 contrib/ofed/libibverbs/verbs.h |  5 ++++-
 3 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/contrib/ofed/libcxgb4/cq.c b/contrib/ofed/libcxgb4/cq.c
index 4841535f8878..a5ce335d7e60 100644
--- a/contrib/ofed/libcxgb4/cq.c
+++ b/contrib/ofed/libcxgb4/cq.c
@@ -616,12 +616,28 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ibv_wc *wc)
 			wc->byte_len = CQE_LEN(&cqe);
 		else
 			wc->byte_len = 0;
-		if (CQE_OPCODE(&cqe) == FW_RI_WRITE_IMMEDIATE) {
+
+		switch (CQE_OPCODE(&cqe)) {
+		case FW_RI_SEND:
+			wc->opcode = IBV_WC_RECV;
+			break;
+		case FW_RI_SEND_WITH_INV:
+		case FW_RI_SEND_WITH_SE_INV:
+			wc->opcode = IBV_WC_RECV;
+			wc->wc_flags |= IBV_WC_WITH_INV;
+			wc->invalidated_rkey = CQE_WRID_STAG(&cqe);
+			break;
+		case FW_RI_WRITE_IMMEDIATE:
 			wc->opcode = IBV_WC_RECV_RDMA_WITH_IMM;
 			wc->imm_data = CQE_IMM_DATA(&cqe);
 			wc->wc_flags |= IBV_WC_WITH_IMM;
-		} else {
-			wc->opcode = IBV_WC_RECV;
+			break;
+		default:
+			PDBG("Unexpected opcode %d "
+			     "in the CQE received for QPID=0x%0x\n",
+			     CQE_OPCODE(&cqe), CQE_QPID(&cqe));
+			ret = -EINVAL;
+			goto out;
 		}
 	} else {
 		switch (CQE_OPCODE(&cqe)) {
@@ -635,8 +651,11 @@ static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ibv_wc *wc)
 			break;
 		case FW_RI_SEND:
 		case FW_RI_SEND_WITH_SE:
+			wc->opcode = IBV_WC_SEND;
+			break;
 		case FW_RI_SEND_WITH_INV:
 		case FW_RI_SEND_WITH_SE_INV:
+			wc->wc_flags |= IBV_WC_WITH_INV;
 			wc->opcode = IBV_WC_SEND;
 			break;
 		case FW_RI_BIND_MW:
diff --git a/contrib/ofed/libcxgb4/qp.c b/contrib/ofed/libcxgb4/qp.c
index 6d899c07ddae..36531af67ae8 100644
--- a/contrib/ofed/libcxgb4/qp.c
+++ b/contrib/ofed/libcxgb4/qp.c
@@ -164,13 +164,28 @@ static int build_rdma_send(struct t4_sq *sq, union t4_wr *wqe,
 
 	if (wr->num_sge > T4_MAX_SEND_SGE)
 		return -EINVAL;
-	if (wr->send_flags & IBV_SEND_SOLICITED)
-		wqe->send.sendop_pkd = htobe32(
-			V_FW_RI_SEND_WR_SENDOP(FW_RI_SEND_WITH_SE));
-	else
-		wqe->send.sendop_pkd = htobe32(
-			V_FW_RI_SEND_WR_SENDOP(FW_RI_SEND));
-	wqe->send.stag_inv = 0;
+	switch (wr->opcode) {
+	case IBV_WR_SEND:
+		if (wr->send_flags & IBV_SEND_SOLICITED)
+			wqe->send.sendop_pkd = htobe32(
+				V_FW_RI_SEND_WR_SENDOP(FW_RI_SEND_WITH_SE));
+		else
+			wqe->send.sendop_pkd = htobe32(
+				V_FW_RI_SEND_WR_SENDOP(FW_RI_SEND));
+		wqe->send.stag_inv = 0;
+		break;
+	case IBV_WR_SEND_WITH_INV:
+		if (wr->send_flags & IBV_SEND_SOLICITED)
+			wqe->send.sendop_pkd = htobe32(
+				V_FW_RI_SEND_WR_SENDOP(FW_RI_SEND_WITH_SE_INV));
+		else
+			wqe->send.sendop_pkd = htobe32(
+				V_FW_RI_SEND_WR_SENDOP(FW_RI_SEND_WITH_INV));
+		wqe->send.stag_inv = htobe32(wr->invalidate_rkey);
+		break;
+	default:
+		return -EINVAL;
+	}
 	wqe->send.r3 = 0;
 	wqe->send.r4 = 0;
 
@@ -350,12 +365,16 @@ int c4iw_post_send(struct ibv_qp *ibqp, struct ibv_send_wr *wr,
 			fw_flags |= FW_RI_COMPLETION_FLAG;
 		swsqe = &qhp->wq.sq.sw_sq[qhp->wq.sq.pidx];
 		switch (wr->opcode) {
+		case IBV_WR_SEND_WITH_INV:
 		case IBV_WR_SEND:
 			INC_STAT(send);
 			if (wr->send_flags & IBV_SEND_FENCE)
 				fw_flags |= FW_RI_READ_FENCE_FLAG;
 			fw_opcode = FW_RI_SEND_WR;
-			swsqe->opcode = FW_RI_SEND;
+			if (wr->opcode == IBV_WR_SEND)
+				swsqe->opcode = FW_RI_SEND;
+			else
+				swsqe->opcode = FW_RI_SEND_WITH_INV;
 			err = build_rdma_send(&qhp->wq.sq, wqe, wr, &len16);
 			break;
 		case IBV_WR_RDMA_WRITE_WITH_IMM:
diff --git a/contrib/ofed/libibverbs/verbs.h b/contrib/ofed/libibverbs/verbs.h
index 63a9ddbb1538..a3eb1826a09a 100644
--- a/contrib/ofed/libibverbs/verbs.h
+++ b/contrib/ofed/libibverbs/verbs.h
@@ -947,7 +947,10 @@ struct ibv_send_wr {
 	int			num_sge;
 	enum ibv_wr_opcode	opcode;
 	int			send_flags;
-	__be32			imm_data;
+	union {
+		__be32		imm_data;
+		u32		invalidate_rkey;
+	};
 	union {
 		struct {
 			uint64_t	remote_addr;