Skip to content

Commit

Permalink
bnx2x: Prevent restarting Tx during bnx2x_nic_unload
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Vladislav Zolotarov authored and David S. Miller committed Aug 2, 2011
1 parent 22019b1 commit 87b7ba3
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions drivers/net/bnx2x/bnx2x_cmn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 87b7ba3

Please sign in to comment.