Message ID | 201108021052.37368.vladz@broadcom.com |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: "Vlad Zolotarov" <vladz@broadcom.com> Date: Tue, 2 Aug 2011 10:52:37 +0300 > 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> Applied, thansk Vlad. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 5b0dba6..d724a18 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -1989,14 +1989,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;