[PATCH net-next V2 04/13] net/mlx5e: Pre-calculate UMR padding and entry size

From: Tariq Toukan

Date: Tue Nov 10 2026 - 13:49:04 EST


From: Dragos Tatulea <dtatulea@xxxxxxxxxx>

A future patch will add KSM UMRs alongside MTT UMRs for data direct. To
avoid additional ifs in the datapath, pre-calculate the UMR padding and
entry size based on the UMR mode of the RQ.

An additional side benefit is that the padding check from
mlx5e_alloc_rx_mpwqe() is no longer needed.

This patch doesn't introduce any functional changes. The mlx5e_rq struct
doesn't grow because the new members were added in a hole.

Signed-off-by: Dragos Tatulea <dtatulea@xxxxxxxxxx>
Reviewed-by: Cosmin Ratiu <cratiu@xxxxxxxxxx>
Signed-off-by: Tariq Toukan <tariqt@xxxxxxxxxx>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 3 +++
.../net/ethernet/mellanox/mlx5/core/en_main.c | 11 +++++++++++
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c | 16 ++++++----------
3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 78cf6aedd04d..000493f42912 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -696,6 +696,9 @@ struct mlx5e_rq {
u8 umr_wqebbs;
u8 mtts_per_wqe;
u8 umr_mode;
+ u8 umr_entry_size;
+ u8 umr_pad_bytes;
+ u16 umr_pad_offset;
struct mlx5e_mpw_linear_info *linear_info;
struct mlx5e_shampo_hd *shampo;
} mpwqe;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 1993da0fdb91..96b521d8bed3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -901,6 +901,7 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
void *rqc_wq = MLX5_ADDR_OF(rqc, rq_param->rqc, wq);
struct mlx5_core_dev *mdev = rq->mdev;
u32 pool_order = 0;
+ u16 entries_bytes;
u32 pool_size;
int wq_sz;
int err;
@@ -947,6 +948,16 @@ static int mlx5e_alloc_rq(struct mlx5e_params *params,
mlx5e_mpwrq_mtts_per_wqe(mdev, rq->mpwqe.page_shift,
rq->mpwqe.umr_mode);

+ rq->mpwqe.umr_entry_size =
+ mlx5e_mpwrq_umr_entry_size(rq->mpwqe.umr_mode);
+ entries_bytes = rq->mpwqe.pages_per_wqe *
+ rq->mpwqe.umr_entry_size;
+ rq->mpwqe.umr_pad_offset = entries_bytes;
+ /* padding can be 0 when no padding is needed */
+ rq->mpwqe.umr_pad_bytes =
+ ALIGN(entries_bytes, MLX5_UMR_FLEX_ALIGNMENT) -
+ entries_bytes;
+
pool_size = rq->mpwqe.pages_per_wqe <<
mlx5e_mpwqe_get_log_rq_size(mdev, params, rqo);
pool_order = rq->mpwqe.page_shift - PAGE_SHIFT;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
index 22fea4739a2c..a9392ee5376e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -675,16 +675,11 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
};
}

- /* Pad if needed, in case the value set to ucseg->xlt_octowords
- * in mlx5e_build_umr_wqe() needed alignment.
+ /* Pad when the value set to ucseg->xlt_octowords in
+ * mlx5e_build_umr_wqe() needed alignment.
*/
- if (rq->mpwqe.pages_per_wqe & (MLX5_UMR_MTT_NUM_ENTRIES_ALIGNMENT - 1)) {
- int pad = ALIGN(rq->mpwqe.pages_per_wqe, MLX5_UMR_MTT_NUM_ENTRIES_ALIGNMENT) -
- rq->mpwqe.pages_per_wqe;
-
- memset(&umr_wqe->inline_mtts[rq->mpwqe.pages_per_wqe], 0,
- sizeof(*umr_wqe->inline_mtts) * pad);
- }
+ memset((u8 *)umr_wqe->inline_mtts + rq->mpwqe.umr_pad_offset, 0,
+ rq->mpwqe.umr_pad_bytes);

bitmap_zero(wi->skip_release_bitmap, rq->mpwqe.pages_per_wqe);
wi->consumed_strides = 0;
@@ -693,7 +688,8 @@ static int mlx5e_alloc_rx_mpwqe(struct mlx5e_rq *rq, u16 ix)
cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) |
MLX5_OPCODE_UMR);

- offset = (ix * rq->mpwqe.mtts_per_wqe) * sizeof(struct mlx5_mtt) / MLX5_OCTWORD;
+ offset = ix * rq->mpwqe.mtts_per_wqe *
+ rq->mpwqe.umr_entry_size / MLX5_OCTWORD;
umr_wqe->hdr.uctrl.xlt_offset = cpu_to_be16(offset);

sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) {
--
2.44.0