diff options
| author | Lukas Wunner <[email protected]> | 2024-04-22 20:45:02 +0000 |
|---|---|---|
| committer | Jakub Kicinski <[email protected]> | 2024-04-25 03:09:30 +0000 |
| commit | c04d1b9ecce565455652ac3c6b17043cd475cf47 (patch) | |
| tree | c3698cea0d92b9fa71aa8dfcd2c7e4a217eb7918 /drivers/net/ethernet/intel/igc/igc.h | |
| parent | Revert "net: txgbe: fix clk_name exceed MAX_DEV_ID limits" (diff) | |
| download | kernel-c04d1b9ecce565455652ac3c6b17043cd475cf47.tar.gz kernel-c04d1b9ecce565455652ac3c6b17043cd475cf47.zip | |
igc: Fix LED-related deadlock on driver unbind
Roman reports a deadlock on unplug of a Thunderbolt docking station
containing an Intel I225 Ethernet adapter.
The root cause is that led_classdev's for LEDs on the adapter are
registered such that they're device-managed by the netdev. That
results in recursive acquisition of the rtnl_lock() mutex on unplug:
When the driver calls unregister_netdev(), it acquires rtnl_lock(),
then frees the device-managed resources. Upon unregistering the LEDs,
netdev_trig_deactivate() invokes unregister_netdevice_notifier(),
which tries to acquire rtnl_lock() again.
Avoid by using non-device-managed LED registration.
Stack trace for posterity:
schedule+0x6e/0xf0
schedule_preempt_disabled+0x15/0x20
__mutex_lock+0x2a0/0x750
unregister_netdevice_notifier+0x40/0x150
netdev_trig_deactivate+0x1f/0x60 [ledtrig_netdev]
led_trigger_set+0x102/0x330
led_classdev_unregister+0x4b/0x110
release_nodes+0x3d/0xb0
devres_release_all+0x8b/0xc0
device_del+0x34f/0x3c0
unregister_netdevice_many_notify+0x80b/0xaf0
unregister_netdev+0x7c/0xd0
igc_remove+0xd8/0x1e0 [igc]
pci_device_remove+0x3f/0xb0
Fixes: ea578703b03d ("igc: Add support for LEDs on i225/i226")
Reported-by: Roman Lozko <[email protected]>
Closes: https://lore.kernel.org/r/CAEhC_B=ksywxCG_+aQqXUrGEgKq+4mqnSV8EBHOKbC3-Obj9+Q@mail.gmail.com/
Reported-by: "Marek Marczykowski-Górecki" <[email protected]>
Closes: https://lore.kernel.org/r/ZhRD3cOtz5i-61PB@mail-itl/
Signed-off-by: Kurt Kanzenbach <[email protected]>
Signed-off-by: Lukas Wunner <[email protected]>
Cc: Heiner Kallweit <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Reviewed-by: Kurt Kanzenbach <[email protected]>
Tested-by: Kurt Kanzenbach <[email protected]> # Intel i225
Tested-by: Naama Meir <[email protected]>
Signed-off-by: Tony Nguyen <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
Diffstat (limited to 'drivers/net/ethernet/intel/igc/igc.h')
| -rw-r--r-- | drivers/net/ethernet/intel/igc/igc.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h index 90316dc58630..6bc56c7c181e 100644 --- a/drivers/net/ethernet/intel/igc/igc.h +++ b/drivers/net/ethernet/intel/igc/igc.h @@ -298,6 +298,7 @@ struct igc_adapter { /* LEDs */ struct mutex led_mutex; + struct igc_led_classdev *leds; }; void igc_up(struct igc_adapter *adapter); @@ -723,6 +724,7 @@ void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts); void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter); int igc_led_setup(struct igc_adapter *adapter); +void igc_led_free(struct igc_adapter *adapter); #define igc_rx_pg_size(_ring) (PAGE_SIZE << igc_rx_pg_order(_ring)) |
