From: sashiko-bot@kernel.org
To: "Tariq Toukan" <tariqt@nvidia.com>
Cc: bpf@vger.kernel.org, linux-rdma@vger.kernel.org
Subject: Re: [PATCH net-next V2 1/2] net/mlx5e: Batch NAPI RCU grace periods on channel close
Date: Wed, 11 Nov 2026 18:51:55 +0000 [thread overview]
Message-ID: <sashiko-outbox-209498@kernel.org> (raw)
In-Reply-To: <20261110185005.2932568-2-tariqt@nvidia.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] net/mlx5e: missing grace period after page_pool_destroy() in
channel close
- [Low] net/mlx5e: redundant pre/post_sync open-coding and duplicated
queue teardown
--
commit 2f06177c661abed7fd45e14fc9a588083535c8b2
Author: Carolina Jubran <cjubran@nvidia.com>
net/mlx5e: Batch NAPI RCU grace periods on channel close
This commit splits channel deactivation and teardown into pre_sync and
post_sync phases so that synchronize_net() grace periods are batched
across all channels during channel close.
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> index c3c2c5720c6f3..73b504ba8c8c6 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
[ ... ]
> @@ -2749,6 +2785,27 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)
> mlx5e_close_cq(&c->icosq.cq);
> }
>
> +static void mlx5e_close_queues_post_sync(struct mlx5e_channel *c)
> +{
> + if (c->xdp)
> + mlx5e_close_xdpsq_post_sync(&c->rq_xdpsq);
> + /* The same ICOSQ is used for UMRs for both RQ and XSKRQ. */
> + cancel_work_sync(&c->icosq.recover_work);
> + mlx5e_close_rq(&c->rq);
> + mlx5e_close_sqs(c);
> + mlx5e_close_icosq(&c->icosq);
> + mutex_destroy(&c->icosq_recovery_lock);
> + if (c->async_icosq)
> + mlx5e_close_async_icosq(c->async_icosq);
> + if (c->xdp)
> + mlx5e_close_cq(&c->rq_xdpsq.cq);
> + mlx5e_close_cq(&c->rq.cq);
> + if (c->xdpsq)
> + mlx5e_close_xdpredirect_sq_post_sync(c->xdpsq);
> + mlx5e_close_tx_cqs(c);
> + mlx5e_close_cq(&c->icosq.cq);
> +}
[ ... ]
> @@ -3060,32 +3144,67 @@ static int mlx5e_wait_channels_min_rx_wqes(struct mlx5e_channels *chs)
[ ... ]
> +static void mlx5e_close_channels_pre_sync(struct mlx5e_channels *chs)
> +{
> + int i;
> +
> + if (chs->ptp)
> + __netif_napi_del_locked(&chs->ptp->napi);
> +
> + for (i = 0; i < chs->num; i++) {
> + mlx5e_close_channel_pre_sync(chs->c[i]);
> + __netif_napi_del_locked(&chs->c[i]->napi);
> + }
> +}
> +
> +static void mlx5e_close_channels_post_sync(struct mlx5e_channels *chs)
> +{
> + int i;
> +
> + if (chs->ptp) {
> + mlx5e_ptp_close_queues(chs->ptp);
> + kvfree(chs->ptp);
> + chs->ptp = NULL;
> + }
> +
> + for (i = 0; i < chs->num; i++) {
> + mlx5e_close_channel_post_sync(chs->c[i]);
> + kvfree(chs->c[i]);
> + }
>
> kfree(chs->c);
> chs->num = 0;
> }
>
> +void mlx5e_close_channels(struct mlx5e_channels *chs)
> +{
> + mlx5e_close_channels_pre_sync(chs);
> + synchronize_net();
> + mlx5e_close_channels_post_sync(chs);
> +}
[Severity: High]
Can freeing chs->ptp and chs->c[i] in mlx5e_close_channels_post_sync()
cause a use-after-free on &c->napi (or &ptp->napi) in
page_pool_napi_local()?
rq->page_pool is created with pool->p.napi pointing to the NAPI struct
embedded in struct mlx5e_channel or struct mlx5e_ptp. That pointer is
only cleared when mlx5e_close_rq() -> mlx5e_free_rq() ->
xdp_rxq_info_unreg() calls page_pool_destroy():
net/core/page_pool.c:page_pool_disable_direct_recycling() {
...
WRITE_ONCE(pool->p.napi, NULL);
}
Before this patch, mlx5e_close_queues() and mlx5e_ptp_close_queues() ran
before netif_napi_del_locked(), so synchronize_net() waited for any
concurrent softirq running page_pool_napi_local() to finish before
kvfree() freed the channel. Moving queue teardown into
mlx5e_close_channels_post_sync() places page_pool_destroy() after
synchronize_net(), and page_pool_scrub() skips its own synchronize_net()
when dma_dev_need_sync() is false:
CPU0 CPU1 (<softirq>)
mlx5e_close_channels()
mlx5e_close_channels_pre_sync()
synchronize_net()
mlx5e_close_channels_post_sync()
mlx5e_close_channel_post_sync()
...
napi_consume_skb()
...
page_pool_napi_local()
napi = READ_ONCE(pool->p.napi);
page_pool_destroy()
WRITE_ONCE(pool->p.napi, NULL);
kvfree(chs->c[i])
READ_ONCE(napi->list_owner)
<-- use-after-free
Closing the queues before synchronize_net() (or waiting for a grace period
after page_pool_destroy() before kvfree()) would avoid freeing the channel
while a softirq still holds the NAPI pointer.
[ ... ]
> @@ -3610,8 +3742,14 @@ int mlx5e_close_locked(struct net_device *netdev)
> clear_bit(MLX5E_STATE_OPENED, &priv->state);
>
> netif_carrier_off(priv->netdev);
> - mlx5e_deactivate_priv_channels(priv);
> - mlx5e_close_channels(&priv->channels);
> +
> + mlx5e_deactivate_priv_channels_pre_sync(priv);
> + synchronize_net();
> + mlx5e_deactivate_priv_channels_post_sync(priv);
> +
> + mlx5e_close_channels_pre_sync(&priv->channels);
> + synchronize_net();
> + mlx5e_close_channels_post_sync(&priv->channels);
>
> return 0;
> }
[Severity: Low]
This isn't a bug, but mlx5e_close_locked() open-codes the exact bodies of
mlx5e_deactivate_priv_channels() and mlx5e_close_channels() without
combining their synchronize_net() calls, so it could keep calling those
two helpers directly. Similarly, mlx5e_close_queues_post_sync()
duplicates mlx5e_close_queues(); mlx5e_close_queues() could run the
pre_sync steps, call synchronize_net(), and call
mlx5e_close_queues_post_sync() like mlx5e_close_channel() does.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261110185005.2932568-1-tariqt@nvidia.com?part=1
next prev parent reply other threads:[~2026-11-11 18:51 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 18:50 [PATCH net-next V2 0/2] net/mlx5e: Batch RCU grace periods on channel open and close Tariq Toukan
2026-11-10 18:50 ` [PATCH net-next V2 1/2] net/mlx5e: Batch NAPI RCU grace periods on channel close Tariq Toukan
2026-11-11 18:51 ` sashiko-bot [this message]
2026-11-12 18:50 ` netdev-bot+sashiko
2026-11-10 18:50 ` [PATCH net-next V2 2/2] net/mlx5e: Batch ICOSQ trigger RCU synchronization Tariq Toukan
2026-11-11 18: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=sashiko-outbox-209498@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--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 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.