From: Sandeep Haemoon <sandeeph@loljews.com>
To: netdev@vger.kernel.org
Cc: Felix Fietkau <nbd@nbd.name>,
Lorenzo Bianconi <lorenzo@kernel.org>,
stable@vger.kernel.org
Subject: [PATCH net v2] net: ethernet: mtk_eth_soc: allocate dummy netdev before registering netdevs
Date: Sun, 20 Sep 2026 20:38:15 +0300 [thread overview]
Message-ID: <patch-33e50d280ef35a7fd2f2dc09deea463a@loljews.com> (raw)
In-Reply-To: <patch-12c1a57b1d914b28b89455f24de55ee4@loljews.com>
The RX rings and the shared NAPI are carried by an internal "dummy" netdev
(eth->dummy_dev). mtk_probe() creates that dummy device only after the MAC
netdevs have been registered, so for a brief window the netdevs are visible
to the network core while eth->dummy_dev is still NULL.
If anything brings the first netdev up during that window (e.g. netifd
opening the WAN link the instant the interface is registered), mtk_open()
takes the first-open path and runs mtk_start_dma() -> mtk_dma_init() ->
mtk_rx_alloc(), which calls __xdp_rxq_info_reg() with eth->dummy_dev ==
NULL. That triggers
WARNING: CPU: ... Missing net_device from driver
in net/core/xdp.c and returns -ENODEV, so mtk_open() fails and the
interface stays down until it is manually brought up once probe finishes.
Allocate the dummy netdev and add the shared tx/rx NAPI to it before the
register_netdev() loop. Both the dummy-allocation failure and a
register_netdev() failure now unwind through mtk_unreg_dev(), which
unregisters the net_device notifiers and the netdevs registered so far -
stopping a concurrently-opened netdev (ndo_stop) and its NAPI before the
dummy carrier is freed. The never-registered netdevs are skipped thanks to
the NETREG_REGISTERED guard in mtk_unreg_dev() and freed directly.
Fixes: b209bd6d0bff ("net: mediatek: mtk_eth_sock: allocate dummy net_device dynamically")
Signed-off-by: Sandeep Haemoon <sandeeph@loljews.com>
---
Version 2:
- Rebased on top of netdev/net.git, which now carries Lorenzo Bianconi's
"mtk_eth_soc: unregister net_devices in case of probe failure" fix; the
dummy allocation sits before the register_netdev() loop and both its
failure and a register_netdev() failure unwind through mtk_unreg_dev(),
unregistering the net_device notifiers and every netdev registered so
far (never-registered ones are skipped by the NETREG_REGISTERED guard)
before the dummy carrier is freed.
- Error path stops any concurrently-opened netdev (ndo_stop, NAPI
disabled) via that unregister, then frees the dummy carrier; a
dummy-allocation failure likewise cleans the notifier chain that
mtk_add_mac() registered.
- Add Fixes: b209bd6d0bff, the commit that made eth->dummy_dev dynamic
and introduced the NULL window.
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 33 +++++++++++++--------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 2ea5dfe85..5e7d8b8be 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -5341,6 +5341,22 @@ static int mtk_probe(struct platform_device *pdev)
}
}
+ /* we run 2 devices on the same DMA ring so we need a dummy device
+ * for NAPI to work. Allocate it before registering the netdevs so a
+ * concurrent ndo_open (e.g. netifd bringing the first netdev up the
+ * instant it is registered) never observes eth->dummy_dev == NULL in
+ * mtk_dma_init() -> mtk_rx_alloc() -> __xdp_rxq_info_reg() (net/core/xdp.c
+ * "Missing net_device from driver") and fails the first open.
+ */
+ eth->dummy_dev = alloc_netdev_dummy(0);
+ if (!eth->dummy_dev) {
+ err = -ENOMEM;
+ dev_err(eth->dev, "failed to allocated dummy device\n");
+ goto err_unreg_netdev;
+ }
+ netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx);
+ netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx);
+
for (i = 0; i < MTK_MAX_DEVS; i++) {
if (!eth->netdev[i])
continue;
@@ -5355,18 +5371,6 @@ static int mtk_probe(struct platform_device *pdev)
eth->netdev[i]->base_addr, eth->irq[MTK_FE_IRQ_SHARED]);
}
- /* we run 2 devices on the same DMA ring so we need a dummy device
- * for NAPI to work
- */
- eth->dummy_dev = alloc_netdev_dummy(0);
- if (!eth->dummy_dev) {
- err = -ENOMEM;
- dev_err(eth->dev, "failed to allocated dummy device\n");
- goto err_unreg_netdev;
- }
- netif_napi_add(eth->dummy_dev, ð->tx_napi, mtk_napi_tx);
- netif_napi_add(eth->dummy_dev, ð->rx_napi, mtk_napi_rx);
-
platform_set_drvdata(pdev, eth);
schedule_delayed_work(ð->reset.monitor_work,
MTK_DMA_MONITOR_TIMEOUT);
@@ -5376,6 +5380,11 @@ static int mtk_probe(struct platform_device *pdev)
err_unreg_netdev:
mtk_unreg_dev(eth);
err_deinit_ppe:
+ if (eth->dummy_dev) {
+ netif_napi_del(ð->tx_napi);
+ netif_napi_del(ð->rx_napi);
+ free_netdev(eth->dummy_dev);
+ }
mtk_ppe_deinit(eth);
mtk_mdio_cleanup(eth);
err_free_dev:
--
2.53.0
next prev parent reply other threads:[~2026-09-20 17:38 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-15 18:55 [PATCH] net: ethernet: mtk_eth_soc: allocate dummy netdev before registering netdevs Sandeep Haemoon
2026-09-16 13:32 ` Lorenzo Bianconi
2026-09-19 1:52 ` netdev-bot+sashiko
2026-09-20 17:38 ` Sandeep Haemoon [this message]
2026-09-24 16:31 ` [PATCH net v2] " Jakub Kicinski
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=patch-33e50d280ef35a7fd2f2dc09deea463a@loljews.com \
--to=sandeeph@loljews.com \
--cc=lorenzo@kernel.org \
--cc=nbd@nbd.name \
--cc=netdev@vger.kernel.org \
--cc=stable@vger.kernel.org \
/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.