From: netdev-bot+sashiko@kernel.org
To: almasrymina@google.com
Cc: kuba@kernel.org, dw@davidwei.uk, asml.silence@gmail.com,
ap420073@gmail.com, sdf@fomichev.me, pabeni@redhat.com,
kaiyuanz@google.com, bobbyeshleman@meta.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org, linux-media@vger.kernel.org,
dri-devel@lists.freedesktop.org, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@kernel.org, horms@kernel.org,
shuah@kernel.org, sumit.semwal@linaro.org,
christian.koenig@amd.com, daniel@iogearbox.net,
razor@blackwall.org, tariqt@nvidia.com, kaifengw@google.com
Subject: Re: [PATCH net v1 3/4] netdevsim: support devmem RX and TX bindings
Date: Sun, 11 Oct 2026 03:38:20 +0000 [thread overview]
Message-ID: <179168990038.434549.9826013939304899900@kernel.org> (raw)
In-Reply-To: <20261010025532.839559-4-almasrymina@google.com>
Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider.
Critical: 0 · High: 0 (1) · Medium: 2 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] This patch adds PP_FLAG_ALLOW_UNREADABLE_NETMEM and .queue_idx
to nsim_create_page_pool().
- [Medium] nsim_bus_dev_new() ignores the return value of
dma_coerce_mask_and_coherent(&nsim_bus_dev->dev, DMA_BIT_MASK(64)) and…
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but
nsim_pp_hold_write() holds only rtnl_lock() while it loads ns->rq[0],…
--
netdevsim: support devmem RX and TX bindings
This patch sets a 64-bit DMA mask on the netdevsim bus device and enables
NETMEM_TX_DMA on the netdevsim net_device. It also creates the RX page_pools
with DMA mapping, unreadable netmem and queue_idx set, so that devmem
bind-rx and bind-tx can be tested against netdevsim in selftests.
> diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c
> index 5c55c308487b4..f87f5e037b6fb 100644
> --- a/drivers/net/netdevsim/bus.c
> +++ b/drivers/net/netdevsim/bus.c
> @@ -462,6 +462,7 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu
> nsim_bus_dev->port_count = port_count;
> nsim_bus_dev->num_queues = num_queues;
> nsim_bus_dev->initial_net = current->nsproxy->net_ns;
> + dma_coerce_mask_and_coherent(&nsim_bus_dev->dev, DMA_BIT_MASK(64));
[Severity: Medium]
What happens here on CONFIG_HAS_DMA=n builds?
NETDEVSIM does not depend on HAS_DMA. Some configs select NO_DMA, for
example UML without UML_DMA_EMULATION. On those builds the dma_set_mask()
stub returns -EIO. The return value is ignored here, so the device
registers and no error is reported.
The PP_FLAG_DMA_MAP change in nsim_create_page_pool() below means every
slow-path page_pool allocation would then fail:
page_pool_alloc_netmems()
...
page_pool_dma_map()
dma_map_page_attrs() <- stub returns DMA_MAPPING_ERROR
if (dma_mapping_error(pool->p.dev, dma))
return false;
After that, nsim_pp_hold_write() returns -ENOMEM:
ns->page = page_pool_dev_alloc_pages(ns->rq[0]->page_pool);
if (!ns->page)
ret = -ENOMEM;
Would the existing page_pool selftests that use pp_hold now fail on these
builds? They passed there before this patch.
Should the error be checked here? Alternatively, should the DMA flags only
be set when the mask setup succeeds?
> /* Disallow using nsim_bus_dev */
> smp_store_release(&nsim_bus_dev->init, false);
>
> diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
> index b4a99f3ceac60..4415dc01c610b 100644
> --- a/drivers/net/netdevsim/netdev.c
> +++ b/drivers/net/netdevsim/netdev.c
> @@ -414,16 +414,22 @@ static int nsim_poll(struct napi_struct *napi, int budget)
> return done;
> }
>
> -static int nsim_create_page_pool(struct page_pool **p, struct napi_struct *napi)
> +static int nsim_create_page_pool(struct net_device *dev, struct page_pool **p,
> + struct napi_struct *napi, int idx)
> {
> + struct netdevsim *ns = netdev_priv(dev);
> struct page_pool_params params = {
> .order = 0,
> .pool_size = NSIM_RING_SIZE,
> + .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV |
> + PP_FLAG_ALLOW_UNREADABLE_NETMEM,
> + .max_len = PAGE_SIZE,
> .nid = NUMA_NO_NODE,
> - .dev = &napi->dev->dev,
> + .dev = &ns->nsim_bus_dev->dev,
> .napi = napi,
> .dma_dir = DMA_BIDIRECTIONAL,
> - .netdev = napi->dev,
> + .netdev = dev,
> + .queue_idx = idx,
> };
[Severity: Medium]
With PP_FLAG_ALLOW_UNREADABLE_NETMEM and queue_idx set, page_pool_init()
now copies rxq->mp_params.mp_ops and mp_priv into the pool. After a devmem
(or io_uring zcrx) bind-rx on queue 0, ns->rq[0]->page_pool is therefore
backed by a memory provider.
nsim_pp_hold_write() still allocates from that pool with the page-only API:
ns->page = page_pool_dev_alloc_pages(ns->rq[0]->page_pool);
What happens to the net_iov in that case? The call chain looks like:
nsim_pp_hold_write()
page_pool_dev_alloc_pages()
page_pool_alloc_pages()
page_pool_alloc_netmems()
mp_dmabuf_devmem_alloc_netmems()
page_pool_set_pp_info(pool, netmem);
pool->pages_state_hold_cnt++;
netmem_to_page()
if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
return NULL;
The WARN fires, and it is fatal with panic_on_warn. ns->page becomes NULL
and the write returns -ENOMEM. The net_iov is already counted in
pages_state_hold_cnt, but nothing holds a pointer to it anymore.
Is this net_iov leaked for good? If so, the pool's inflight count would
never reach zero. page_pool_destroy() at unbind or queue restart would then
keep deferring the release, and the provider's destroy hook would never
run. That would also leak the pool, its dmabuf binding reference and the
binding's genpool chunk.
Should nsim_pp_hold_write() use the netmem allocation API instead? Or
should it refuse to allocate when a memory provider is bound to the queue?
> struct page_pool *pool;
>
[ ... ]
> @@ -762,14 +768,16 @@ nsim_queue_mem_alloc(struct net_device *dev,
> if (ns->rq_reset_mode == 1) {
> if (!netif_running(ns->netdev))
> return -ENETDOWN;
> - return nsim_create_page_pool(&qmem->pp, &ns->rq[idx]->napi);
> + return nsim_create_page_pool(dev, &qmem->pp,
> + &ns->rq[idx]->napi, idx);
> }
>
> qmem->rq = nsim_queue_alloc();
> if (!qmem->rq)
> return -ENOMEM;
>
> - err = nsim_create_page_pool(&qmem->rq->page_pool, &qmem->rq->napi);
> + err = nsim_create_page_pool(dev, &qmem->rq->page_pool, &qmem->rq->napi,
> + idx);
[Severity: High]
This is a pre-existing issue that this patch did not introduce. It seems
worth raising because bind-rx now gives netdevsim another way to restart
queues.
nsim_pp_hold_write() holds only rtnl_lock() while it loads ns->rq[0],
dereferences its page_pool and allocates from it. The RX queue restart
path replaces and frees those objects while holding only the netdev instance
lock:
netdev_rx_queue_restart()
nsim_queue_mem_alloc()
nsim_queue_stop()
nsim_queue_start()
ns->rq[idx] = qmem->rq; (modes 0/2/3)
ns->rq[idx]->page_pool = qmem->pp; (mode 1)
nsim_queue_mem_free()
page_pool_destroy(qmem->rq->page_pool);
nsim_queue_free(dev, qmem->rq); <- kfree()s the old rq
nsim_qreset_write() takes only netdev_lock(), and so do devmem bind-rx and
unbind. None of them takes rtnl, so these paths share no lock with
nsim_pp_hold_write().
Can this interleaving lead to a use-after-free?
CPU0 CPU1
nsim_pp_hold_write()
rtnl_lock()
loads old ns->rq[0]
restart of queue 0
ns->rq[0] = new rq
page_pool_destroy(old pool)
kfree(old rq)
old rq->page_pool
page_pool_dev_alloc_pages()
Should nsim_pp_hold_write() also take the netdev instance lock?
> if (err)
> goto err_free;
>
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261010025532.839559-1-almasrymina%40google.com
next prev parent reply other threads:[~2026-10-11 3:38 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-10 2:55 [PATCH net v1 0/4] net: devmem: fix RX and TX binding teardown on device unregistration Mina Almasry
2026-10-10 2:55 ` [PATCH net v1 1/4] net: devmem: unmap dma_buf synchronously on queue uninstall Mina Almasry
2026-10-10 14:02 ` Pavel Begunkov
2026-10-11 3:38 ` netdev-bot+sashiko
2026-10-11 15:51 ` Mina Almasry
2026-10-10 2:55 ` [PATCH net v1 2/4] net: devmem: detach TX bindings on NETDEV_UNREGISTER Mina Almasry
2026-10-11 3:38 ` netdev-bot+sashiko
2026-10-10 2:55 ` [PATCH net v1 3/4] netdevsim: support devmem RX and TX bindings Mina Almasry
2026-10-11 3:38 ` netdev-bot+sashiko [this message]
2026-10-10 2:55 ` [PATCH net v1 4/4] selftests: net: add devmem RX and TX netdev unregister tests Mina Almasry
2026-10-11 3:38 ` 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=179168990038.434549.9826013939304899900@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=almasrymina@google.com \
--cc=andrew+netdev@lunn.ch \
--cc=ap420073@gmail.com \
--cc=asml.silence@gmail.com \
--cc=bobbyeshleman@meta.com \
--cc=christian.koenig@amd.com \
--cc=daniel@iogearbox.net \
--cc=davem@davemloft.net \
--cc=dri-devel@lists.freedesktop.org \
--cc=dw@davidwei.uk \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kaifengw@google.com \
--cc=kaiyuanz@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=razor@blackwall.org \
--cc=sdf@fomichev.me \
--cc=shuah@kernel.org \
--cc=sumit.semwal@linaro.org \
--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®