From: Konstantin Taranov <kotaranov@linux.microsoft.com>
To: kotaranov@microsoft.com, snsanghvi@microsoft.com,
longli@microsoft.com, jgg@ziepe.ca, leon@kernel.org
Cc: linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH rdma-next v3 03/10] net/mana: Extend GDMA encoding for new RDMA WQEs
Date: Wed, 7 Oct 2026 08:33:23 -0700 [thread overview]
Message-ID: <20261007153330.2979799-4-kotaranov@linux.microsoft.com> (raw)
In-Reply-To: <20261007153330.2979799-1-kotaranov@linux.microsoft.com>
From: Konstantin Taranov <kotaranov@microsoft.com>
Extend mana_gd_post_work_request() to support extra-large OOB data and
fixed-size WQEs. These formats are supported only for power-of-two WQE
sizes.
For fixed-size WQEs, use num_pad_sge to specify the padding size. Encode
the WQE header fields required by RC QPs based on the WR flags.
Signed-off-by: Konstantin Taranov <kotaranov@microsoft.com>
---
v2:
- Reject fixed WQEs that cannot fit the header, aligned OOB and SGEs.
.../net/ethernet/microsoft/mana/gdma_main.c | 55 ++++++++++++++++---
include/net/mana/gdma.h | 21 +++++--
2 files changed, 63 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c
index 05ba7055405d..2717889e626e 100644
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -1699,8 +1699,27 @@ static u32 mana_gd_write_client_oob(const struct gdma_wqe_request *wqe_req,
header->num_sge = wqe_req->num_sge;
header->inline_oob_size_div4 = client_oob_size / sizeof(u32);
+ if (client_oob_size == INLINE_OOB_EXTRA_LARGE_SIZE) {
+ /* Extra large oob is encoded as 7 */
+ header->inline_oob_size_div4 = 7;
+ /* Extra large oob has 8 byte padding */
+ client_oob_size += 8;
+ }
+
+ if (wqe_req->wqe_size_in_bu) {
+ header->num_sge = (wqe_req->wqe_size_in_bu * GDMA_WQE_BU_SIZE
+ - sizeof(struct gdma_wqe) - client_oob_size) / sizeof(struct gdma_sge);
+ header->num_pad_sge = header->num_sge - wqe_req->num_sge;
+ }
+
+ header->check_rsn = !!(wqe_req->flags & GDMA_WR_CHECK_RSN);
+ header->check_sn = !!(wqe_req->flags & GDMA_WR_CHECK_SN);
+ header->fence = !!(wqe_req->flags & GDMA_WR_FENCE);
+ header->fence_extended = !!(wqe_req->flags & GDMA_WR_FENCE_EXTENDED);
+ header->generation1 = !!(wqe_req->flags & GDMA_WR_GENERATION_1);
+
if (oob_in_sgl) {
- WARN_ON_ONCE(wqe_req->num_sge < 2);
+ WARN_ON_ONCE(wqe_req->num_sge < 1);
header->client_oob_in_sgl = 1;
@@ -1714,8 +1733,10 @@ static u32 mana_gd_write_client_oob(const struct gdma_wqe_request *wqe_req,
/* The size of gdma_wqe + client_oob_size must be less than or equal
* to one Basic Unit (i.e. 32 bytes), so the pointer can't go beyond
* the queue memory buffer boundary.
+ * The exception is when the WQE size is fixed and a power of 2, as
+ * such a wqe cannot go beyond the queue memory buffer boundary.
*/
- ptr = wqe_ptr + sizeof(header);
+ ptr = wqe_ptr + sizeof(struct gdma_wqe);
if (wqe_req->inline_oob_data && wqe_req->inline_oob_size > 0) {
memcpy(ptr, wqe_req->inline_oob_data, wqe_req->inline_oob_size);
@@ -1724,8 +1745,8 @@ static u32 mana_gd_write_client_oob(const struct gdma_wqe_request *wqe_req,
memset(ptr + wqe_req->inline_oob_size, 0,
client_oob_size - wqe_req->inline_oob_size);
}
-
- return sizeof(header) + client_oob_size;
+ /* The hw requires that (gdma_wqe + client_oob_size) is sge size aligned */
+ return ALIGN(sizeof(struct gdma_wqe) + client_oob_size, sizeof(struct gdma_sge));
}
static void mana_gd_write_sgl(struct gdma_queue *wq, u32 sgl_offset,
@@ -1784,7 +1805,8 @@ int mana_gd_post_work_request(struct gdma_queue *wq,
return -EINVAL;
if (wq->type == GDMA_RQ) {
- if (client_oob_size != 0)
+ if (client_oob_size != 0 &&
+ client_oob_size != INLINE_OOB_SMALL_SIZE)
return -EINVAL;
client_oob_size = INLINE_OOB_SMALL_SIZE;
@@ -1792,15 +1814,32 @@ int mana_gd_post_work_request(struct gdma_queue *wq,
max_wqe_size = GDMA_MAX_RQE_SIZE;
} else {
if (client_oob_size != INLINE_OOB_SMALL_SIZE &&
- client_oob_size != INLINE_OOB_LARGE_SIZE)
+ client_oob_size != INLINE_OOB_LARGE_SIZE &&
+ client_oob_size != INLINE_OOB_EXTRA_LARGE_SIZE)
return -EINVAL;
max_wqe_size = GDMA_MAX_SQE_SIZE;
}
sgl_data_size = sizeof(struct gdma_sge) * wqe_req->num_sge;
- wqe_size = ALIGN(sizeof(struct gdma_wqe) + client_oob_size +
- sgl_data_size, GDMA_WQE_BU_SIZE);
+ if (wqe_req->wqe_size_in_bu) {
+ wqe_size = wqe_req->wqe_size_in_bu * GDMA_WQE_BU_SIZE;
+ oob_len = ALIGN(sizeof(struct gdma_wqe) + client_oob_size,
+ sizeof(struct gdma_sge));
+ if (wqe_size < oob_len ||
+ wqe_req->num_sge > (wqe_size - oob_len) / sizeof(struct gdma_sge))
+ return -EINVAL;
+ } else {
+ wqe_size = ALIGN(sizeof(struct gdma_wqe) + client_oob_size +
+ sgl_data_size, GDMA_WQE_BU_SIZE);
+ }
+ /* Ensure the WQE size is a power of 2 when a fixed wqe size or extra large OOB are used.
+ * Otherwise, the WQE may cross the queue memory buffer boundary, which is not allowed.
+ */
+ if (wqe_req->wqe_size_in_bu || client_oob_size == INLINE_OOB_EXTRA_LARGE_SIZE) {
+ if (!is_power_of_2(wqe_size))
+ return -EINVAL;
+ }
if (wqe_size > max_wqe_size)
return -EINVAL;
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 332f394b82e1..508da28591ae 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -56,6 +56,11 @@ enum gdma_work_request_flags {
GDMA_WR_OOB_IN_SGL = BIT(0),
GDMA_WR_PAD_BY_SGE0 = BIT(1),
GDMA_WR_IB_SGL = BIT(2),
+ GDMA_WR_CHECK_SN = BIT(3),
+ GDMA_WR_CHECK_RSN = BIT(4),
+ GDMA_WR_FENCE = BIT(5),
+ GDMA_WR_FENCE_EXTENDED = BIT(6),
+ GDMA_WR_GENERATION_1 = BIT(7),
};
enum gdma_eqe_type {
@@ -219,8 +224,8 @@ struct gdma_wqe_request {
struct ib_sge *ib_sgl;
};
u32 num_sge;
-
- u32 inline_oob_size;
+ u16 wqe_size_in_bu;
+ u16 inline_oob_size;
const void *inline_oob_data;
u32 flags;
@@ -538,7 +543,9 @@ void mana_gd_ring_dim(struct gdma_queue *cq, u32 mod_usec, bool mod_usec_vld,
u32 mod_comps, bool mod_comps_vld);
struct gdma_wqe {
- u32 reserved :24;
+ u32 num_pad_sge :5;
+ u32 generation1 :1;
+ u32 reserved :18;
u32 last_vbytes :8;
union {
@@ -548,9 +555,13 @@ struct gdma_wqe {
u32 num_sge :8;
u32 inline_oob_size_div4:3;
u32 client_oob_in_sgl :1;
- u32 reserved1 :4;
+ u32 check_rsn :1;
+ u32 fence :1;
+ u32 fence_extended :1;
+ u32 reserved1 :1;
u32 client_data_unit :14;
- u32 reserved2 :2;
+ u32 check_sn :1;
+ u32 reserved2 :1;
};
};
}; /* HW DATA */
--
2.43.0
next prev parent reply other threads:[~2026-10-07 15:34 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-07 15:33 [PATCH rdma-next v3 00/10] RDMA/mana_ib: Add kernel RC and fast registration support Konstantin Taranov
2026-10-07 15:33 ` [PATCH rdma-next v3 01/10] RDMA/mana_ib: Allocate and map fast-registration MRs Konstantin Taranov
2026-10-07 15:46 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 02/10] RDMA/mana: Create and destroy kernel RC QPs Konstantin Taranov
2026-10-07 15:50 ` sashiko-bot
2026-10-07 15:33 ` Konstantin Taranov [this message]
2026-10-07 15:47 ` [PATCH rdma-next v3 03/10] net/mana: Extend GDMA encoding for new RDMA WQEs sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 04/10] RDMA/mana_ib: Maintain kernel RC QP state Konstantin Taranov
2026-10-07 15:46 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 05/10] RDMA/mana_ib: Post receive WRs on kernel RC QPs Konstantin Taranov
2026-10-07 15:43 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 06/10] RDMA/mana_ib: Post send and memory-management WRs on " Konstantin Taranov
2026-10-07 15:53 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 07/10] RDMA/mana_ib: Poll RC completions using PSN and FSN progress Konstantin Taranov
2026-10-07 15:48 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 08/10] RDMA/mana_ib: Flush and notify CQs when kernel QPs enter ERR Konstantin Taranov
2026-10-07 15:46 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 09/10] RDMA/mana_ib: Handle error CQEs for RC QPs Konstantin Taranov
2026-10-07 15:51 ` sashiko-bot
2026-10-07 15:33 ` [PATCH rdma-next v3 10/10] RDMA/mana_ib: Drain kernel receive and send queues Konstantin Taranov
2026-10-07 15:51 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261007153330.2979799-4-kotaranov@linux.microsoft.com \
--to=kotaranov@linux.microsoft.com \
--cc=jgg@ziepe.ca \
--cc=kotaranov@microsoft.com \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=longli@microsoft.com \
--cc=snsanghvi@microsoft.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.