From: Rongwei Liu <rongweil@nvidia.com>
To: <dev@dpdk.org>, <matan@nvidia.com>, <viacheslavo@nvidia.com>,
<orika@nvidia.com>, <suanmingm@nvidia.com>, <thomas@monjalon.net>
Cc: <getelson@nvidia.com>, <stable@dpdk.org>,
Dariusz Sosnowski <dsosnowski@nvidia.com>,
Bing Zhao <bingz@nvidia.com>
Subject: [PATCH v1] net/mlx5: fix job leak on indirect meter creation failure
Date: Mon, 8 Dec 2025 12:12:03 +0200 [thread overview]
Message-ID: <20251208101203.315647-1-rongweil@nvidia.com> (raw)
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")
Cc: getelson@nvidia.com
Cc: stable@dpdk.org
Signed-off-by: Rongwei Liu <rongweil@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 c41b99746f..e1121e74dc 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -1870,64 +1870,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
@@ -1941,20 +1944,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;
}
@@ -12649,12 +12654,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;
@@ -12710,9 +12716,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:
@@ -12728,7 +12740,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.27.0
reply other threads:[~2025-12-08 10:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20251208101203.315647-1-rongweil@nvidia.com \
--to=rongweil@nvidia.com \
--cc=bingz@nvidia.com \
--cc=dev@dpdk.org \
--cc=dsosnowski@nvidia.com \
--cc=getelson@nvidia.com \
--cc=matan@nvidia.com \
--cc=orika@nvidia.com \
--cc=stable@dpdk.org \
--cc=suanmingm@nvidia.com \
--cc=thomas@monjalon.net \
--cc=viacheslavo@nvidia.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).