]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bnx2x: Prevent restarting Tx during bnx2x_nic_unload
authorVladislav Zolotarov <vladz@broadcom.com>
Tue, 2 Aug 2011 08:35:43 +0000 (01:35 -0700)
committerJoe Jin <joe.jin@oracle.com>
Wed, 16 May 2012 08:31:36 +0000 (16:31 +0800)
Tx queues were stopped before  bp->state was changed to a value different
from BNX2X_STATE_OPEN, which allowed the bnx2x_tx_int() called from the
NAPI context to re-enable it. This then allowed the netdev->ndo_start_xmit()
to be called in the middle of the function reset and rings freeing.

This patch changes bp->state to a value different
from BNX2X_STATE_OPEN BEFORE disabling the Tx queues in order to restore the
broken protection against the above race in the bnx2x_tx_int().

Signed-off-by: Vladislav Zolotarov <vladz@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit 87b7ba3d24a25cf18aece447de27d7804fa9668c)

Signed-off-by: Joe Jin <joe.jin@oracle.com>
drivers/net/bnx2x/bnx2x_cmn.c

index ab8287f9ebcc96a04a9aa537eae2dff7f7650f5e..28e1f031979debf13bbf9331bed24ce12c577103 100644 (file)
@@ -1987,14 +1987,20 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
                return -EINVAL;
        }
 
+       /*
+        * It's important to set the bp->state to the value different from
+        * BNX2X_STATE_OPEN and only then stop the Tx. Otherwise bnx2x_tx_int()
+        * may restart the Tx from the NAPI context (see bnx2x_tx_int()).
+        */
+       bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
+       smp_mb();
+
        /* Stop Tx */
        bnx2x_tx_disable(bp);
 
 #ifdef BCM_CNIC
        bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD);
 #endif
-       bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT;
-       smp_mb();
 
        bp->rx_mode = BNX2X_RX_MODE_NONE;