From afdc08b9f9a7174d7912a160f657f39d46379b5e Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 25 Aug 2005 15:34:29 -0700 Subject: [BNX2]: Fix rtnl deadlock in bnx2_close This fixes an rtnl deadlock problem when flush_scheduled_work() is called from bnx2_close(). In rare cases, linkwatch_event() may be on the workqueue from a previous close of a different device and it will try to get the rtnl lock which is already held by dev_close(). The fix is to set a flag if we are in the reset task which is run from the workqueue. bnx2_close() will loop until the flag is cleared. As suggested by Jeff Garzik, the loop is changed to call msleep(1) instead of yield() in the original patch. flush_scheduled_work() is also moved to bnx2_remove_one() before the netdev is freed. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/bnx2.h') diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 8214a2853d0d..63b94ca0018b 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -3874,6 +3874,7 @@ struct bnx2 { int timer_interval; struct timer_list timer; struct work_struct reset_task; + int in_reset_task; /* Used to synchronize phy accesses. */ spinlock_t phy_lock; -- cgit v1.2.3-59-g8ed1b