Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

amd-xgbe: fix sleep while atomic on suspend/resume

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>

authored by

Raju Rangoju and committed by
Jakub Kicinski
e2f27363 5af6e8b5

-14
-10
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
··· 1120 1120 { 1121 1121 struct xgbe_prv_data *pdata = netdev_priv(netdev); 1122 1122 struct xgbe_hw_if *hw_if = &pdata->hw_if; 1123 - unsigned long flags; 1124 1123 1125 1124 DBGPR("-->xgbe_powerdown\n"); 1126 1125 ··· 1129 1130 DBGPR("<--xgbe_powerdown\n"); 1130 1131 return -EINVAL; 1131 1132 } 1132 - 1133 - spin_lock_irqsave(&pdata->lock, flags); 1134 1133 1135 1134 if (caller == XGMAC_DRIVER_CONTEXT) 1136 1135 netif_device_detach(netdev); ··· 1145 1148 1146 1149 pdata->power_down = 1; 1147 1150 1148 - spin_unlock_irqrestore(&pdata->lock, flags); 1149 - 1150 1151 DBGPR("<--xgbe_powerdown\n"); 1151 1152 1152 1153 return 0; ··· 1154 1159 { 1155 1160 struct xgbe_prv_data *pdata = netdev_priv(netdev); 1156 1161 struct xgbe_hw_if *hw_if = &pdata->hw_if; 1157 - unsigned long flags; 1158 1162 1159 1163 DBGPR("-->xgbe_powerup\n"); 1160 1164 ··· 1163 1169 DBGPR("<--xgbe_powerup\n"); 1164 1170 return -EINVAL; 1165 1171 } 1166 - 1167 - spin_lock_irqsave(&pdata->lock, flags); 1168 1172 1169 1173 pdata->power_down = 0; 1170 1174 ··· 1177 1185 netif_tx_start_all_queues(netdev); 1178 1186 1179 1187 xgbe_start_timers(pdata); 1180 - 1181 - spin_unlock_irqrestore(&pdata->lock, flags); 1182 1188 1183 1189 DBGPR("<--xgbe_powerup\n"); 1184 1190
-1
drivers/net/ethernet/amd/xgbe/xgbe-main.c
··· 76 76 pdata->netdev = netdev; 77 77 pdata->dev = dev; 78 78 79 - spin_lock_init(&pdata->lock); 80 79 spin_lock_init(&pdata->xpcs_lock); 81 80 mutex_init(&pdata->rss_mutex); 82 81 spin_lock_init(&pdata->tstamp_lock);
-3
drivers/net/ethernet/amd/xgbe/xgbe.h
··· 1004 1004 unsigned int pp3; 1005 1005 unsigned int pp4; 1006 1006 1007 - /* Overall device lock */ 1008 - spinlock_t lock; 1009 - 1010 1007 /* XPCS indirect addressing lock */ 1011 1008 spinlock_t xpcs_lock; 1012 1009 unsigned int xpcs_window_def_reg;