Skip to content

Commit ba44066

Browse files
Kohei EnjuNipaLocal
authored andcommitted
igc: don't fail igc_probe() on LED setup error
When igc_led_setup() fails, igc_probe() fails and triggers kernel panic in free_netdev() since unregister_netdev() is not called. [1] This behavior can be tested using fault-injection framework, especially the failslab feature. [2] Since LED support is not mandatory, treat LED setup failures as non-fatal and continue probe with a warning message, consequently avoiding the kernel panic. [1] kernel BUG at net/core/dev.c:12047! Oops: invalid opcode: 0000 [kernel-patches#1] SMP NOPTI CPU: 0 UID: 0 PID: 937 Comm: repro-igc-led-e Not tainted 6.17.0-rc4-enjuk-tnguy-00865-gc4940196ab02 kernel-patches#64 PREEMPT(voluntary) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:free_netdev+0x278/0x2b0 [...] Call Trace: <TASK> igc_probe+0x370/0x910 local_pci_probe+0x3a/0x80 pci_device_probe+0xd1/0x200 [...] [2] #!/bin/bash -ex FAILSLAB_PATH=/sys/kernel/debug/failslab/ DEVICE=0000:00:05.0 START_ADDR=$(grep " igc_led_setup" /proc/kallsyms \ | awk '{printf("0x%s", $1)}') END_ADDR=$(printf "0x%x" $((START_ADDR + 0x100))) echo $START_ADDR > $FAILSLAB_PATH/require-start echo $END_ADDR > $FAILSLAB_PATH/require-end echo 1 > $FAILSLAB_PATH/times echo 100 > $FAILSLAB_PATH/probability echo N > $FAILSLAB_PATH/ignore-gfp-wait echo $DEVICE > /sys/bus/pci/drivers/igc/bind Fixes: ea57870 ("igc: Add support for LEDs on i225/i226") Signed-off-by: Kohei Enju <enjuk@amazon.com> Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Reviewed-by: Vitaly Lifshits <vitaly.lifshits@intel.com> Reviewed-by: Kurt Kanzenbach <kurt@linutronix.de> Tested-by: Mor Bar-Gabay <morx.bar.gabay@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: NipaLocal <nipa@local>
1 parent 4812dbf commit ba44066

File tree

2 files changed

+10
-3
lines changed

2 files changed

+10
-3
lines changed

drivers/net/ethernet/intel/igc/igc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ struct igc_adapter {
345345
/* LEDs */
346346
struct mutex led_mutex;
347347
struct igc_led_classdev *leds;
348+
bool leds_available;
348349
};
349350

350351
void igc_up(struct igc_adapter *adapter);

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7335,8 +7335,14 @@ static int igc_probe(struct pci_dev *pdev,
73357335

73367336
if (IS_ENABLED(CONFIG_IGC_LEDS)) {
73377337
err = igc_led_setup(adapter);
7338-
if (err)
7339-
goto err_register;
7338+
if (err) {
7339+
netdev_warn_once(netdev,
7340+
"LED init failed (%d); continuing without LED support\n",
7341+
err);
7342+
adapter->leds_available = false;
7343+
} else {
7344+
adapter->leds_available = true;
7345+
}
73407346
}
73417347

73427348
return 0;
@@ -7392,7 +7398,7 @@ static void igc_remove(struct pci_dev *pdev)
73927398
cancel_work_sync(&adapter->watchdog_task);
73937399
hrtimer_cancel(&adapter->hrtimer);
73947400

7395-
if (IS_ENABLED(CONFIG_IGC_LEDS))
7401+
if (IS_ENABLED(CONFIG_IGC_LEDS) && adapter->leds_available)
73967402
igc_led_free(adapter);
73977403

73987404
/* Release control of h/w to f/w. If f/w is AMT enabled, this

0 commit comments

Comments
 (0)