]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
eth: via-rhine: fix calling napi_enable() in atomic context
authorJakub Kicinski <kuba@kernel.org>
Fri, 24 Jan 2025 03:18:40 +0000 (19:18 -0800)
committerJakub Kicinski <kuba@kernel.org>
Mon, 27 Jan 2025 22:30:49 +0000 (14:30 -0800)
napi_enable() may sleep now, take netdev_lock() before rp->lock.
napi_enable() is hidden inside init_registers().

Note that this patch orders netdev_lock after rp->task_lock,
to avoid having to take the netdev_lock() around disable path.

Fixes: 413f0271f396 ("net: protect NAPI enablement with netdev_lock()")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Link: https://lore.kernel.org/dcfd56bc-de32-4b11-9e19-d8bd1543745d@stanley.mountain
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250124031841.1179756-7-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/via/via-rhine.c

index 894911f3d5603c109cba7651b6b047b59ec85c97..e56ebbdd428d532cf3238f015e7faa1a0d5fa06f 100644 (file)
@@ -1568,7 +1568,7 @@ static void init_registers(struct net_device *dev)
        if (rp->quirks & rqMgmt)
                rhine_init_cam_filter(dev);
 
-       napi_enable(&rp->napi);
+       napi_enable_locked(&rp->napi);
 
        iowrite16(RHINE_EVENT & 0xffff, ioaddr + IntrEnable);
 
@@ -1696,7 +1696,10 @@ static int rhine_open(struct net_device *dev)
        rhine_power_init(dev);
        rhine_chip_reset(dev);
        rhine_task_enable(rp);
+
+       netdev_lock(dev);
        init_registers(dev);
+       netdev_unlock(dev);
 
        netif_dbg(rp, ifup, dev, "%s() Done - status %04x MII status: %04x\n",
                  __func__, ioread16(ioaddr + ChipCmd),
@@ -1727,6 +1730,8 @@ static void rhine_reset_task(struct work_struct *work)
 
        napi_disable(&rp->napi);
        netif_tx_disable(dev);
+
+       netdev_lock(dev);
        spin_lock_bh(&rp->lock);
 
        /* clear all descriptors */
@@ -1740,6 +1745,7 @@ static void rhine_reset_task(struct work_struct *work)
        init_registers(dev);
 
        spin_unlock_bh(&rp->lock);
+       netdev_unlock(dev);
 
        netif_trans_update(dev); /* prevent tx timeout */
        dev->stats.tx_errors++;
@@ -2541,9 +2547,12 @@ static int rhine_resume(struct device *device)
        alloc_tbufs(dev);
        rhine_reset_rbufs(rp);
        rhine_task_enable(rp);
+
+       netdev_lock(dev);
        spin_lock_bh(&rp->lock);
        init_registers(dev);
        spin_unlock_bh(&rp->lock);
+       netdev_unlock(dev);
 
        netif_device_attach(dev);