patch 'net/mlx5: fix job leak on indirect meter creation failure' has been queued to stable release 24.11.5
luca.boccassi at gmail.com
luca.boccassi at gmail.com
Fri Feb 20 15:56:22 CET 2026
Hi,
FYI, your patch has been queued to stable release 24.11.5
Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet.
It will be pushed if I get no objections before 02/22/26. So please
shout if anyone has objections.
Also note that after the patch there's a diff of the upstream commit vs the
patch applied to the branch. This will indicate if there was any rebasing
needed to apply to the stable branch. If there were code changes for rebasing
(ie: not only metadata diffs), please double check that the rebase was
correctly done.
Queued patches are on a temporary branch at:
https://github.com/bluca/dpdk-stable
This queued commit can be viewed at:
https://github.com/bluca/dpdk-stable/commit/764d2d65f3f37432cc3f0c2c9b5ffaec060a5d48
Thanks.
Luca Boccassi
---
>From 764d2d65f3f37432cc3f0c2c9b5ffaec060a5d48 Mon Sep 17 00:00:00 2001
From: Rongwei Liu <rongweil at nvidia.com>
Date: Mon, 8 Dec 2025 12:12:03 +0200
Subject: [PATCH] net/mlx5: fix job leak on indirect meter creation failure
[ upstream commit f5a92b70f545e830bf6baae9d15f88bb500481c4 ]
Indirect meter_mark action needs to allocate a job to track
asynchronous HW operation to create the meter object.
When meter_mark creation failed, the job may have been leaked
because there was no job cleanup code for sync API.
Add necessary code to check if meter_mark creation failed before or
after HW operation is enqueued and call job_put accordingly.
Fixes: 4359d9d1f76b ("net/mlx5: fix sync meter processing in HWS")
Signed-off-by: Rongwei Liu <rongweil at nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnowski at nvidia.com>
---
drivers/net/mlx5/mlx5_flow_hw.c | 86 +++++++++++++++++++--------------
1 file changed, 49 insertions(+), 37 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index af85bb9ec3..b2b4a83466 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -1839,64 +1839,67 @@ static rte_be32_t vlan_hdr_to_be32(const struct rte_flow_action *actions)
#endif
}
-static __rte_always_inline struct mlx5_aso_mtr *
+static __rte_always_inline int
flow_hw_meter_mark_alloc(struct rte_eth_dev *dev, uint32_t queue,
const struct rte_flow_action *action,
struct mlx5_hw_q_job *job, bool push,
+ struct mlx5_aso_mtr **aso_mtr,
struct rte_flow_error *error)
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_aso_mtr_pool *pool = priv->hws_mpool;
const struct rte_flow_action_meter_mark *meter_mark = action->conf;
- struct mlx5_aso_mtr *aso_mtr;
struct mlx5_flow_meter_info *fm;
uint32_t mtr_id = 0;
uintptr_t handle = (uintptr_t)MLX5_INDIRECT_ACTION_TYPE_METER_MARK <<
MLX5_INDIRECT_ACTION_TYPE_OFFSET;
- if (priv->shared_host) {
- rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
- "Meter mark actions can only be created on the host port");
- return NULL;
- }
+ if (priv->shared_host)
+ return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "Meter mark actions can only be created on the host port");
+ MLX5_ASSERT(aso_mtr);
if (meter_mark->profile == NULL)
- return NULL;
- aso_mtr = mlx5_ipool_malloc(pool->idx_pool, &mtr_id);
- if (!aso_mtr) {
- rte_flow_error_set(error, ENOMEM,
- RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
- NULL,
- "failed to allocate aso meter entry");
+ return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+ "No Meter mark profile");
+
+ *aso_mtr = mlx5_ipool_malloc(pool->idx_pool, &mtr_id);
+ if (!*aso_mtr) {
if (mtr_id)
mlx5_ipool_free(pool->idx_pool, mtr_id);
- return NULL;
+ return rte_flow_error_set(error, ENOMEM,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "failed to allocate aso meter entry");
}
/* Fill the flow meter parameters. */
- aso_mtr->type = ASO_METER_INDIRECT;
- fm = &aso_mtr->fm;
+ (*aso_mtr)->type = ASO_METER_INDIRECT;
+ fm = &(*aso_mtr)->fm;
fm->meter_id = mtr_id;
fm->profile = (struct mlx5_flow_meter_profile *)(meter_mark->profile);
fm->is_enable = meter_mark->state;
fm->color_aware = meter_mark->color_mode;
- aso_mtr->pool = pool;
- aso_mtr->state = (queue == MLX5_HW_INV_QUEUE) ?
+ (*aso_mtr)->pool = pool;
+ (*aso_mtr)->state = (queue == MLX5_HW_INV_QUEUE) ?
ASO_METER_WAIT : ASO_METER_WAIT_ASYNC;
- aso_mtr->offset = mtr_id - 1;
- aso_mtr->init_color = fm->color_aware ? RTE_COLORS : RTE_COLOR_GREEN;
+ (*aso_mtr)->offset = mtr_id - 1;
+ (*aso_mtr)->init_color = fm->color_aware ? RTE_COLORS : RTE_COLOR_GREEN;
job->action = (void *)(handle | mtr_id);
/* Update ASO flow meter by wqe. */
- if (mlx5_aso_meter_update_by_wqe(priv, queue, aso_mtr,
+ if (mlx5_aso_meter_update_by_wqe(priv, queue, *aso_mtr,
&priv->mtr_bulk, job, push)) {
mlx5_ipool_free(pool->idx_pool, mtr_id);
- return NULL;
+ return rte_flow_error_set(error, EBUSY,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL,
+ "Failed to enqueue ASO meter update");
}
/* Wait for ASO object completion. */
if (queue == MLX5_HW_INV_QUEUE &&
- mlx5_aso_mtr_wait(priv, aso_mtr, true)) {
+ mlx5_aso_mtr_wait(priv, *aso_mtr, true)) {
mlx5_ipool_free(pool->idx_pool, mtr_id);
- return NULL;
+ return -EIO;
}
- return aso_mtr;
+ return 0;
}
static __rte_always_inline int
@@ -1910,20 +1913,22 @@ flow_hw_meter_mark_compile(struct rte_eth_dev *dev,
{
struct mlx5_priv *priv = dev->data->dev_private;
struct mlx5_aso_mtr_pool *pool = priv->hws_mpool;
- struct mlx5_aso_mtr *aso_mtr;
+ struct mlx5_aso_mtr *aso_mtr = NULL;
struct mlx5_hw_q_job *job =
flow_hw_action_job_init(priv, queue, NULL, NULL, NULL,
MLX5_HW_Q_JOB_TYPE_CREATE,
MLX5_HW_INDIRECT_TYPE_LEGACY, NULL);
+ int ret;
if (!job)
return -1;
- aso_mtr = flow_hw_meter_mark_alloc(dev, queue, action, job,
- true, error);
- if (!aso_mtr) {
- if (queue == MLX5_HW_INV_QUEUE)
- queue = CTRL_QUEUE_ID(priv);
- flow_hw_job_put(priv, job, queue);
+ ret = flow_hw_meter_mark_alloc(dev, queue, action, job, true, &aso_mtr, error);
+ if (ret) {
+ if (ret != -EIO) {
+ if (queue == MLX5_HW_INV_QUEUE)
+ queue = CTRL_QUEUE_ID(priv);
+ flow_hw_job_put(priv, job, queue);
+ }
return -1;
}
@@ -12377,12 +12382,13 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
struct mlx5_hw_q_job *job = NULL;
struct mlx5_priv *priv = dev->data->dev_private;
const struct rte_flow_action_age *age;
- struct mlx5_aso_mtr *aso_mtr;
+ struct mlx5_aso_mtr *aso_mtr = NULL;
cnt_id_t cnt_id;
uint32_t age_idx;
bool push = flow_hw_action_push(attr);
bool aso = false;
bool force_job = action->type == RTE_FLOW_ACTION_TYPE_METER_MARK;
+ int ret;
if (!mlx5_hw_ctx_validate(dev, error))
return NULL;
@@ -12438,9 +12444,15 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
break;
case RTE_FLOW_ACTION_TYPE_METER_MARK:
aso = true;
- aso_mtr = flow_hw_meter_mark_alloc(dev, queue, action, job, push, error);
- if (!aso_mtr)
+ ret = flow_hw_meter_mark_alloc(dev, queue, action, job, push, &aso_mtr, error);
+ if (ret) {
+ if (ret != -EIO) {
+ if (queue == MLX5_HW_INV_QUEUE)
+ queue = CTRL_QUEUE_ID(priv);
+ flow_hw_job_put(priv, job, queue);
+ }
break;
+ }
handle = (void *)(uintptr_t)job->action;
break;
case RTE_FLOW_ACTION_TYPE_RSS:
@@ -12456,7 +12468,7 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
NULL, "action type not supported");
break;
}
- if (job && !force_job) {
+ if (job && (!force_job || handle)) {
job->action = handle;
flow_hw_action_finalize(dev, queue, job, push, aso,
handle != NULL);
--
2.47.3
---
Diff of the applied patch vs upstream commit (please double-check if non-empty:
---
--- - 2026-02-20 14:55:46.291718436 +0000
+++ 0080-net-mlx5-fix-job-leak-on-indirect-meter-creation-fai.patch 2026-02-20 14:55:43.296192634 +0000
@@ -1 +1 @@
-From f5a92b70f545e830bf6baae9d15f88bb500481c4 Mon Sep 17 00:00:00 2001
+From 764d2d65f3f37432cc3f0c2c9b5ffaec060a5d48 Mon Sep 17 00:00:00 2001
@@ -5,0 +6,2 @@
+[ upstream commit f5a92b70f545e830bf6baae9d15f88bb500481c4 ]
+
@@ -16 +17,0 @@
-Cc: stable at dpdk.org
@@ -25 +26 @@
-index 9cd6ae8a8d..22cc7efe65 100644
+index af85bb9ec3..b2b4a83466 100644
@@ -28 +29 @@
-@@ -1952,64 +1952,67 @@ static rte_be32_t vlan_hdr_to_be32(const struct rte_flow_action *actions)
+@@ -1839,64 +1839,67 @@ static rte_be32_t vlan_hdr_to_be32(const struct rte_flow_action *actions)
@@ -122 +123 @@
-@@ -2023,20 +2026,22 @@ flow_hw_meter_mark_compile(struct rte_eth_dev *dev,
+@@ -1910,20 +1913,22 @@ flow_hw_meter_mark_compile(struct rte_eth_dev *dev,
@@ -152 +153 @@
-@@ -12850,12 +12855,13 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
+@@ -12377,12 +12382,13 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
@@ -167 +168 @@
-@@ -12911,9 +12917,15 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
+@@ -12438,9 +12444,15 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
@@ -185 +186 @@
-@@ -12929,7 +12941,7 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
+@@ -12456,7 +12468,7 @@ flow_hw_action_handle_create(struct rte_eth_dev *dev, uint32_t queue,
More information about the stable
mailing list