]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
amd-xgbe: fix sleep while atomic on suspend/resume
authorRaju Rangoju <Raju.Rangoju@amd.com>
Mon, 2 Mar 2026 04:21:24 +0000 (09:51 +0530)
committerJakub Kicinski <kuba@kernel.org>
Wed, 4 Mar 2026 01:24:38 +0000 (17:24 -0800)
The xgbe_powerdown() and xgbe_powerup() functions use spinlocks
(spin_lock_irqsave) while calling functions that may sleep:
- napi_disable() can sleep waiting for NAPI polling to complete
- flush_workqueue() can sleep waiting for pending work items

This causes a "BUG: scheduling while atomic" error during suspend/resume
cycles on systems using the AMD XGBE Ethernet controller.

The spinlock protection in these functions is unnecessary as these
functions are called from suspend/resume paths which are already serialized
by the PM core

Fix this by removing the spinlock. Since only code that takes this lock
is xgbe_powerdown() and xgbe_powerup(), remove it completely.

Fixes: c5aa9e3b8156 ("amd-xgbe: Initial AMD 10GbE platform driver")
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Link: https://patch.msgid.link/20260302042124.1386445-1-Raju.Rangoju@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-main.c
drivers/net/ethernet/amd/xgbe/xgbe.h

index 62bb4b8a68e1ca8e59956c6cbfe83e1eea48fa05..8b79d88480dbe484e31eb0a98e79058e3c72e63b 100644 (file)
@@ -1120,7 +1120,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
-       unsigned long flags;
 
        DBGPR("-->xgbe_powerdown\n");
 
@@ -1131,8 +1130,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller)
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&pdata->lock, flags);
-
        if (caller == XGMAC_DRIVER_CONTEXT)
                netif_device_detach(netdev);
 
@@ -1148,8 +1145,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller)
 
        pdata->power_down = 1;
 
-       spin_unlock_irqrestore(&pdata->lock, flags);
-
        DBGPR("<--xgbe_powerdown\n");
 
        return 0;
@@ -1159,7 +1154,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
        struct xgbe_hw_if *hw_if = &pdata->hw_if;
-       unsigned long flags;
 
        DBGPR("-->xgbe_powerup\n");
 
@@ -1170,8 +1164,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller)
                return -EINVAL;
        }
 
-       spin_lock_irqsave(&pdata->lock, flags);
-
        pdata->power_down = 0;
 
        xgbe_napi_enable(pdata, 0);
@@ -1186,8 +1178,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller)
 
        xgbe_start_timers(pdata);
 
-       spin_unlock_irqrestore(&pdata->lock, flags);
-
        DBGPR("<--xgbe_powerup\n");
 
        return 0;
index d1f0419edb234925ee05d149cb28fa554eb88704..7d45ea22a02e299005b2b2e8d14e0d60e0d85e4a 100644 (file)
@@ -76,7 +76,6 @@ struct xgbe_prv_data *xgbe_alloc_pdata(struct device *dev)
        pdata->netdev = netdev;
        pdata->dev = dev;
 
-       spin_lock_init(&pdata->lock);
        spin_lock_init(&pdata->xpcs_lock);
        mutex_init(&pdata->rss_mutex);
        spin_lock_init(&pdata->tstamp_lock);
index 1269b8ce92492d35bfd70283496975d19b1f4cc6..e1d7d7150e16feb9996c124bd4c2ad1bc0da37f4 100644 (file)
@@ -1004,9 +1004,6 @@ struct xgbe_prv_data {
        unsigned int pp3;
        unsigned int pp4;
 
-       /* Overall device lock */
-       spinlock_t lock;
-
        /* XPCS indirect addressing lock */
        spinlock_t xpcs_lock;
        unsigned int xpcs_window_def_reg;