]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
e1000e: hitting BUG_ON() from napi_enable
authorBruce Allan <bruce.w.allan@intel.com>
Tue, 29 Nov 2011 08:09:19 +0000 (08:09 +0000)
committerJoe Jin <joe.jin@oracle.com>
Thu, 17 May 2012 06:29:50 +0000 (14:29 +0800)
Based on a patch from Mike McElroy created against the out-of-tree e1000e
driver:

Hitting the BUG_ON in napi_enable(). Code inspection shows that this can
only be triggered by calling napi_enable() twice without an intervening
napi_disable().

I saw the following sequence of events in the stack trace:

1) We simulated a cable pull using an Extreme switch.
2) e1000_tx_timeout() was entered.
3) e1000_reset_task() was called. Saw the message from e_err() in the
console log.
4) e1000_reinit_locked was called. This function calls e1000_down() and
e1000_up(). These functions call napi_disable() and napi_enable()
respectively.
5) Then on another thread, a monitor task saw carrier was down and executed
'ip set link down' and 'ip set link up' commands.
6) Saw the '_E1000_RESETTING'warning fron the e1000_close function.
7) Either the e1000_open() executed between the e1000_down() and e1000_up()
calls in step 4 or the e1000_open() call executed after the e1000_up()
call.  In either case, napi_enable() is called twice which triggers the
BUG_ON.

(cherry picked from commit 5f4a780ddd453c4918555fed9d9c5f2d455a087d)
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Cc: Mike McElroy <mike.mcelroy@stratus.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/e1000e/netdev.c

index d1df57440af9931b51580cb6cc7374d39d0d34f8..5555a5e0c98112502c252b91e7bf1d44e2fcbbe4 100644 (file)
@@ -3431,7 +3431,6 @@ int e1000e_up(struct e1000_adapter *adapter)
 
        clear_bit(__E1000_DOWN, &adapter->state);
 
-       napi_enable(&adapter->napi);
        if (adapter->msix_entries)
                e1000_configure_msix(adapter);
        e1000_irq_enable(adapter);
@@ -3493,7 +3492,6 @@ void e1000e_down(struct e1000_adapter *adapter)
        e1e_flush();
        usleep_range(10000, 20000);
 
-       napi_disable(&adapter->napi);
        e1000_irq_disable(adapter);
 
        del_timer_sync(&adapter->watchdog_timer);
@@ -3816,6 +3814,8 @@ static int e1000_close(struct net_device *netdev)
 
        pm_runtime_get_sync(&pdev->dev);
 
+       napi_disable(&adapter->napi);
+
        if (!test_bit(__E1000_DOWN, &adapter->state)) {
                e1000e_down(adapter);
                e1000_free_irq(adapter);