-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
e1000: Do not perform reset in reset_task if we are already down (#148)
Signed-off-by: Guohan Lu <[email protected]>
- Loading branch information
Showing
2 changed files
with
66 additions
and
0 deletions.
There are no files selected for viewing
65 changes: 65 additions & 0 deletions
65
patch/e1000-Do-not-perform-reset-in-reset_task-if-we-are-a.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
From 49ee3c2ab5234757bfb56a0b3a3cb422f427e3a3 Mon Sep 17 00:00:00 2001 | ||
From: Alexander Duyck <[email protected]> | ||
Date: Fri, 17 Apr 2020 09:35:31 -0700 | ||
Subject: [PATCH] e1000: Do not perform reset in reset_task if we are already | ||
down | ||
|
||
We are seeing a deadlock in e1000 down when NAPI is being disabled. Looking | ||
over the kernel function trace of the system it appears that the interface | ||
is being closed and then a reset is hitting which deadlocks the interface | ||
as the NAPI interface is already disabled. | ||
|
||
To prevent this from happening I am disabling the reset task when | ||
__E1000_DOWN is already set. In addition code has been added so that we set | ||
the __E1000_DOWN while holding the __E1000_RESET flag in e1000_close in | ||
order to guarantee that the reset task will not run after we have started | ||
the close call. | ||
|
||
Signed-off-by: Alexander Duyck <[email protected]> | ||
Tested-by: Maxim Zhukov <[email protected]> | ||
Signed-off-by: Jeff Kirsher <[email protected]> | ||
--- | ||
drivers/net/ethernet/intel/e1000/e1000_main.c | 18 ++++++++++++++---- | ||
1 file changed, 14 insertions(+), 4 deletions(-) | ||
|
||
diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c | ||
index 05bc6e216bca..d9fa4600f745 100644 | ||
--- a/drivers/net/ethernet/intel/e1000/e1000_main.c | ||
+++ b/drivers/net/ethernet/intel/e1000/e1000_main.c | ||
@@ -542,8 +542,13 @@ void e1000_reinit_locked(struct e1000_adapter *adapter) | ||
WARN_ON(in_interrupt()); | ||
while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) | ||
msleep(1); | ||
- e1000_down(adapter); | ||
- e1000_up(adapter); | ||
+ | ||
+ /* only run the task if not already down */ | ||
+ if (!test_bit(__E1000_DOWN, &adapter->flags)) { | ||
+ e1000_down(adapter); | ||
+ e1000_up(adapter); | ||
+ } | ||
+ | ||
clear_bit(__E1000_RESETTING, &adapter->flags); | ||
} | ||
|
||
@@ -1433,10 +1438,15 @@ int e1000_close(struct net_device *netdev) | ||
struct e1000_hw *hw = &adapter->hw; | ||
int count = E1000_CHECK_RESET_COUNT; | ||
|
||
- while (test_bit(__E1000_RESETTING, &adapter->flags) && count--) | ||
+ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags) && count--) | ||
usleep_range(10000, 20000); | ||
|
||
- WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags)); | ||
+ WARN_ON(count < 0); | ||
+ | ||
+ /* signal that we're down so that the reset task will no longer run */ | ||
+ set_bit(__E1000_DOWN, &adapter->flags); | ||
+ clear_bit(__E1000_RESETTING, &adapter->flags); | ||
+ | ||
e1000_down(adapter); | ||
e1000_power_down_phy(adapter); | ||
e1000_free_irq(adapter); | ||
-- | ||
2.17.1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters