From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E9BD235C6A8; Fri, 9 Oct 2026 14:24:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791555884; cv=none; b=P92v9/Ou3WIbTkKauA2CwDPJOiU3sXrnYtlmisYcFNpHQ/F01ob4DHh6PjzbBTSo7yHb2J+nZYpKzNAIsS02yF8S7mHi088VOQFjikanHBMHbwlTg7Yn2+4qe9A9e+hS0Y3u95hbtSO/ZaKRNkdW8eLghmPAmyo54Uhy1nSloMk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791555884; c=relaxed/simple; bh=K/6OnBTXhD5c56bdhLUASCc8HktH+RcZg5tBnA7DAb0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MVXkJcf5jt6wn6OWOh8Sj5FsCtb68J6/UyzfRs9t6MkfyU8HaTzImnwkCbMOQLKGnH1jL+JHzDhdj0uv5AzohF2NsLQLGf1wXEA2D3kJncfm8tGoprVXiky/O8nwL7oTWg7SrUCEsEhm3XI+U0a6u5jgbyBhxDrgvq1kymPECjs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=bFX5NbKE; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="bFX5NbKE" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F10A1F000FF; Fri, 9 Oct 2026 14:24:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1791555882; bh=3HqeTdTHLoA7xKaZYve7wVp4PRTfgmkC/2HXnx/Sdzk=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=bFX5NbKEi1EmHucuRYLXvyA0GElkIUcNiBE221LLu5JOrMk5K1eEXSnM4ulq4CPdi f5e1IgnsGyM7+U7yUYohB7tx73zPWpOPMRPayuhd0ffT2h68t5QyxGxmyrNgnQu9rY 70XVSwjrYsQDIygjq1q1nFUXgVHywxn67SN/y4ko= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Sandeep Haemoon , Simon Horman , Jakub Kicinski , Sasha Levin Subject: [PATCH 6.18 111/403] net: ethernet: mtk_eth_soc: allocate dummy netdev sooner Date: Fri, 9 Oct 2026 16:07:52 +0200 Message-ID: <20261009140954.675813236@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261009140952.119038291@linuxfoundation.org> References: <20261009140952.119038291@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Sandeep Haemoon [ Upstream commit 6f0c2c4f5e7143eba75153ecc8af3a03f7b6a98b ] The RX rings and the shared NAPI are carried by an internal "dummy" netdev (eth->dummy_dev). mtk_probe() creates that dummy device, and adds the shared tx/rx NAPI to it, only after the MAC netdevs have been registered. That order has been there since the MT7623 support was added and leaves a window in which the netdevs are visible to the network core before the shared NAPI and the dummy device exist. If anything brings the first netdev up during that window (e.g. netifd opening the WAN link the instant the interface is registered), the first-open path runs without them. On NETSYS v2 and later SoCs mtk_rx_alloc() -> __xdp_rxq_info_reg() then dereferences eth->dummy_dev == NULL: WARNING: CPU: ... Missing net_device from driver in net/core/xdp.c and mtk_open() fails with -ENODEV. On NETSYS v1 SoCs (MT7621/MT7622/MT7623/MT7629) there is no page pool, so the same open instead calls napi_enable() on a napi_struct that netif_napi_add() has not initialised yet and dereferences a NULL napi->dev. 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. A netdev that opened during the window can also have queued the frame-engine reset worker (via the tx watchdog or phylink), so the probe error path now cancels eth->pending_work before freeing the shared state, as mtk_cleanup() already does on remove. Fixes: 656e705243fd ("net-next: mediatek: add support for MT7623 ethernet") Signed-off-by: Sandeep Haemoon Reviewed-by: Simon Horman Link: https://patch.msgid.link/patch-e52c13380b0768fec63af04c80e4b487@loljews.com Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 38 ++++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 3f43e487d8875..162a17a87c7f5 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -5337,6 +5337,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; @@ -5351,18 +5367,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); @@ -5372,6 +5376,16 @@ static int mtk_probe(struct platform_device *pdev) err_unreg_netdev: mtk_unreg_dev(eth); err_deinit_ppe: + /* A netdev opened while probe was still registering can have queued + * the frame-engine reset worker, which takes rtnl and drives the + * hardware; cancel it before anything below is torn down. + */ + cancel_work_sync(ð->pending_work); + 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