1. 18 8月, 2006 1 次提交
    • M
      [BNX2]: Fix tx race condition. · 2f8af120
      Michael Chan 提交于
      Fix a subtle race condition between bnx2_start_xmit() and bnx2_tx_int()
      similar to the one in tg3 discovered by Herbert Xu:
      
      CPU0					CPU1
      bnx2_start_xmit()
      	if (tx_ring_full) {
      		tx_lock
      					bnx2_tx()
      						if (!netif_queue_stopped)
      		netif_stop_queue()
      		if (!tx_ring_full)
      						update_tx_ring
      			netif_wake_queue()
      		tx_unlock
      	}
      
      Even though tx_ring is updated before the if statement in bnx2_tx_int() in
      program order, it can be re-ordered by the CPU as shown above.  This
      scenario can cause the tx queue to be stopped forever if bnx2_tx_int() has
      just freed up the entire tx_ring.  The possibility of this happening
      should be very rare though.
      
      The following changes are made, very much identical to the tg3 fix:
      
      1. Add memory barrier to fix the above race condition.
      
      2. Eliminate the private tx_lock altogether and rely solely on
      netif_tx_lock.  This eliminates one spinlock in bnx2_start_xmit()
      when the ring is full.
      
      3. Because of 2, use netif_tx_lock in bnx2_tx_int() before calling
      netif_wake_queue().
      
      4. Add memory barrier to bnx2_tx_avail().
      
      5. Add bp->tx_wake_thresh which is set to half the tx ring size.
      
      6. Check for the full wake queue condition before getting
      netif_tx_lock in tg3_tx().  This reduces the number of unnecessary
      spinlocks when the tx ring is full in a steady-state condition.
      Signed-off-by: NMichael Chan <mchan@broadcom.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      2f8af120
  2. 30 6月, 2006 1 次提交
  3. 18 6月, 2006 3 次提交
  4. 23 3月, 2006 4 次提交
  5. 21 3月, 2006 2 次提交
  6. 24 1月, 2006 6 次提交
  7. 06 11月, 2005 4 次提交
  8. 09 9月, 2005 1 次提交
  9. 30 8月, 2005 3 次提交
    • M
      [BNX2]: remove atomics in tx · e89bbf10
      Michael Chan 提交于
      Remove atomic operations in the fast tx path. Expensive atomic
      operations were used to keep track of the number of available tx
      descriptors. The new code uses the difference between the consumer
      and producer index to determine the number of free tx descriptors.
      
      As suggested by Jeff Garzik, the name of the inline function is
      changed to all lower case.
      Signed-off-by: NMichael Chan <mchan@broadcom.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e89bbf10
    • M
      [BNX2]: speedup serdes linkup · cd339a0e
      Michael Chan 提交于
      This speeds up link-up time on 5706 SerDes if the link partner does
      not autoneg, a rather common scenario in blade servers. Some blade
      servers use IPMI for keyboard input and it's important to minimize
      link disruptions.
      
      The speedup is achieved by shortening the timer to (HZ / 3) during
      the transient period right after initiating a SerDes autoneg. If
      autoneg does not complete, parallel detect can be done sooner. After
      the transient period is over, the timer goes back to its normal HZ
      interval.
      
      As suggested by Jeff Garzik, the timer initialization is moved to
      bnx2_init_board() from bnx2_open().
      
      An eeprom bit is also added to allow default forced SerDes speed for
      even faster link-up time.
      Signed-off-by: NMichael Chan <mchan@broadcom.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      cd339a0e
    • M
      [BNX2]: Fix rtnl deadlock in bnx2_close · afdc08b9
      Michael Chan 提交于
      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: NMichael Chan <mchan@broadcom.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      afdc08b9
  10. 27 5月, 2005 1 次提交