From: netdev-bot+sashiko@kernel.org
To: tariqt@nvidia.com
Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, netdev@vger.kernel.org, pabeni@redhat.com,
erezsh@nvidia.com, gal@nvidia.com, leon@kernel.org,
linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org,
mbloch@nvidia.com, saeedm@nvidia.com, kliteyn@nvidia.com
Subject: Re: [PATCH net-next 4/6] net/mlx5: HWS, Add timeout mechanism to draining send queues
Date: Wed, 16 Sep 2026 23:42:38 +0000 [thread overview]
Message-ID: <178960215805.22033.5661773040766220983@kernel.org> (raw)
In-Reply-To: <20260915111912.3926585-5-tariqt@nvidia.com>
Thank you for your contribution! Sashiko AI review found 5 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 2 · Low: 3
- [Medium] The new drain timeout in mlx5hws_send_queue_action()
(send.c:1218-1228) does not mirror the…
- [Medium] The new -ETIMEDOUT return from mlx5hws_send_queue_action()
(send.c:1226) abandons the drain while WQEs are still owned by the HW…
- [Low] RESOLVED LATER IN THIS SERIES (retained only per the validation-
experiment directive): at this commit, mlx5hws_send_stes_fw()…
- [Low] This change converts a previously unbounded (infinite)
synchronous drain loop into one that fails with -ETIMEDOUT, i.e. it…
- [Low] In mlx5hws_send_queue_action() (send.c:1218-1228) the new
deadline test is evaluated unconditionally after…
--
net/mlx5: HWS, Add timeout mechanism to draining send queues
This adds a 60 second deadline (MLX5HWS_BWC_POLLING_TIMEOUT) to the
synchronous drain loop in mlx5hws_send_queue_action(), which previously
polled until the send engine became empty with no exit condition. It
also extends the existing BWC poll timeout message with the timeout
value.
A few questions below.
> net/mlx5: HWS, Add timeout mechanism to draining send queues
>
> HWS has a timeout mechanism for usual polling for completion,
> but it was missing such a mechanism for draining the send queues.
[Severity: Low]
Should this carry a Fixes: tag?
The DRAIN_SYNC arm of mlx5hws_send_queue_action() had no exit other than the
queue emptying, so callers such as mlx5hws_arg_write_inline_arg_data() and
hws_action_create_dest_match_range_fill_table() could spin indefinitely with
ctx->ctrl_lock held when the device stops generating completions.
git blame points at 2ca62599aa0b ("net/mlx5: HWS, added send engine and
context handling") for that loop.
The commit message describes the change as adding a missing mechanism rather
than fixing an indefinite hang, which makes it harder for stable maintainers
to pick this up.
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
> index 49dee44d0bef5..9ff109fc8230a 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c
> @@ -1192,6 +1192,8 @@ int mlx5hws_send_queue_action(struct mlx5hws_context *ctx,
> u16 queue_id,
> u32 actions)
> {
> + unsigned long timeout = jiffies +
> + secs_to_jiffies(MLX5HWS_BWC_POLLING_TIMEOUT);
> struct mlx5hws_send_ring_sq *send_sq;
> struct mlx5hws_send_engine *queue;
> bool wait_comp = false;
> @@ -1213,9 +1215,18 @@ int mlx5hws_send_queue_action(struct mlx5hws_context *ctx,
> mlx5hws_send_engine_flush_queue(queue);
>
> /* Poll queue until empty */
> - while (wait_comp && !mlx5hws_send_engine_empty(queue))
> + while (wait_comp && !mlx5hws_send_engine_empty(queue)) {
> hws_send_engine_poll_cq(queue, NULL, &polled, 0);
>
> + if (unlikely(time_after(jiffies, timeout))) {
[Severity: Medium]
Should this loop also short-circuit on MLX5_DEVICE_STATE_INTERNAL_ERROR the
way its sibling in bwc.c does?
mlx5hws_bwc_queue_poll() aborts immediately when the device is down:
if (unlikely(ctx->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)) {
/* If the device is down for any reason (e.g. FLR), the HW will
* no longer generate completions.
...
return -ETIMEDOUT;
}
The drain loop has no equivalent. hws_send_engine_poll_cq() returns before
reaching any device-state check when the CQ is empty:
cqe = mlx5_cqwq_get_cqe(&cq->wq);
if (!cqe)
return;
The device-state test lives in mlx5hws_cq_poll_one(), which is only reached
after a CQE has already been found, so it never fires on a dead device.
So in exactly the FLR / health-failure case where the hardware is documented
to stop producing completions, doesn't every DRAIN_SYNC call now spin on CQ
memory for the full MLX5HWS_BWC_POLLING_TIMEOUT of 60 seconds?
There is also no cond_resched() or cpu_relax() in the loop body, and both
callers hold ctx->ctrl_lock across the drain:
mlx5hws_arg_write_inline_arg_data() -> mlx5hws_send_queue_action()
hws_action_create_dest_match_range_fill_table() -> mlx5hws_send_queue_action()
On CONFIG_PREEMPT_NONE or PREEMPT_VOLUNTARY, can a 60 second spin here trip
the soft lockup detector (2 * watchdog_thresh, 20 seconds) and the RCU CPU
stall timeout, while every other task waiting on ctrl_lock is blocked?
[Severity: Low]
Can this report a timeout for a drain that actually completed?
The deadline test runs unconditionally after the poll and returns before the
while condition is re-evaluated. hws_send_engine_poll_cq() advances
cq->poll_wqe:
cq->poll_wqe = (wqe_cnt + priv->num_wqebbs) & sq->buf_mask;
and mlx5hws_send_engine_empty() compares exactly that field against
send_sq->cur_post:
return ((send_sq->cur_post & send_sq->buf_mask) == send_cq->poll_wqe);
So if the poll that empties the queue lands on the same iteration in which
jiffies crosses the deadline, -ETIMEDOUT is returned for a drained queue.
The sibling loop in mlx5hws_bwc_queue_poll() gates its check on lack of
progress:
if (unlikely(!got_comp && time_after(jiffies, timeout))) {
Would re-testing mlx5hws_send_engine_empty() (or adding a progress
qualifier) before returning be worth doing here?
> + mlx5hws_err(ctx,
> + "Error draining send queue %d - TIMEOUT (%d sec)\n",
> + queue_id,
> + MLX5HWS_BWC_POLLING_TIMEOUT);
> + return -ETIMEDOUT;
[Severity: Medium]
This return abandons the drain while cur_post != cq->poll_wqe, that is while
WQEs are still owned by the hardware, without setting queue->err and without
reaping the matching sq->wr_priv entries.
The bad-CQE path in hws_send_engine_poll_cq() does fence the engine off:
if (unlikely(cqe_opcode != MLX5_CQE_REQ))
queue->err = true;
Since queue->err stays clear on the timeout path, mlx5hws_send_engine_err()
keeps reporting the queue as healthy and it continues to be used with a
skewed cur_post / poll_wqe pair.
Callers treat the new error as an ordinary failure and free the objects the
outstanding WQEs still reference. In mlx5hws_arg_create():
ret = mlx5hws_arg_write_inline_arg_data(ctx, id, data, data_sz);
if (ret) {
mlx5hws_err(ctx, "Failed writing arg data\n");
mlx5hws_cmd_arg_destroy(ctx->mdev, id);
return ret;
}
while the MOD_ARG WQEs posted by mlx5hws_arg_write() still target that id:
send_attr.id = arg_idx++;
mlx5hws_send_engine_post_end(&ctrl, &send_attr);
Similarly, hws_action_create_dest_match_range_fill_table() propagates the
drain failure and mlx5hws_action_create_dest_match_range() unwinds:
destroy_hit_ft_action:
mlx5hws_action_destroy(hit_ft_action);
destroy_table_ste:
hws_action_destroy_dest_match_range_table(ctx, table_ste);
freeing the STC offset and destroying the RTCs and STE pool that
un-completed control queue work still refers to.
If the timeout is caused by a stalled but still live device that later
resumes executing those WQEs, can the argument id / STC offset / RTC id have
been reallocated to an unrelated object by then, so the late execution writes
into the new owner? Before this patch the DRAIN_SYNC arm could only return 0,
so these caller error paths were not reachable from this call.
Would setting queue->err on the timeout path, or otherwise quiescing the
queue before letting callers destroy objects, address this?
[Severity: Low]
One caller discards the new return value. In mlx5hws_send_stes_fw():
/* Writing through FW can't HW fence, therefore we drain the queue */
if (send_attr->fence)
mlx5hws_send_queue_action(ctx,
queue_id,
MLX5HWS_SEND_QUEUE_ACTION_DRAIN_SYNC);
The drain is the software substitute for a hardware fence here, and the path
is live: hws_action_create_dest_match_range_fill_table() sets
ste_attr.send_attr.fence = 1. With -ETIMEDOUT ignored, the firmware STE/RTC
write proceeds and MLX5HWS_FLOW_OP_SUCCESS is generated even though the
fence never completed.
This is addressed by the following patch in the series, "net/mlx5: HWS,
Handle timeout draining the send queue for FW STEs", which checks the return
value and goes to fail_rule, so it is only an issue at this commit.
> + }
> + }
> +
> break;
> default:
> return -EINVAL;
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260915111912.3926585-1-tariqt%40nvidia.com
next prev parent reply other threads:[~2026-09-16 23:42 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 11:19 [PATCH net-next 0/6] net/mlx5: more HWS misc enhancements Tariq Toukan
2026-09-15 11:19 ` [PATCH net-next 1/6] net/mlx5: HWS, Return meaningful error code in hws_send_wqe_fw Tariq Toukan
2026-09-15 11:19 ` [PATCH net-next 2/6] net/mlx5: HWS, Fix error message in mlx5hws_cmd_generate_wqe Tariq Toukan
2026-09-16 23:42 ` netdev-bot+sashiko
2026-09-15 11:19 ` [PATCH net-next 3/6] net/mlx5: HWS, Replace kzalloc with kzalloc_obj Tariq Toukan
2026-09-16 23:42 ` netdev-bot+sashiko
2026-09-15 11:19 ` [PATCH net-next 4/6] net/mlx5: HWS, Add timeout mechanism to draining send queues Tariq Toukan
2026-09-16 23:42 ` netdev-bot+sashiko [this message]
2026-09-15 11:19 ` [PATCH net-next 5/6] net/mlx5: HWS, Handle timeout draining the send queue for FW STEs Tariq Toukan
2026-09-16 23:42 ` netdev-bot+sashiko
2026-09-15 11:19 ` [PATCH net-next 6/6] net/mlx5: HWS, Remove unneeded WRITE_ONCE in post send Tariq Toukan
2026-09-16 23:42 ` netdev-bot+sashiko
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=178960215805.22033.5661773040766220983@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=erezsh@nvidia.com \
--cc=gal@nvidia.com \
--cc=kliteyn@nvidia.com \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=mbloch@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=saeedm@nvidia.com \
--cc=tariqt@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
all inboxes | Powered by JetHome®