Michael Chan
2f8af120a1
[BNX2]: Fix tx race condition.
...
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: Michael Chan <mchan@broadcom.com >
Signed-off-by: David S. Miller <davem@davemloft.net >
2006-08-17 16:29:51 -07:00
..
2006-08-02 13:38:17 -07:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-07-08 13:34:32 -07:00
2006-07-02 13:58:51 -07:00
2006-08-02 13:38:27 -07:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-07-10 14:50:33 -07:00
2006-06-30 19:25:36 +02:00
2006-07-12 17:42:40 -04:00
2006-07-12 17:42:40 -04:00
2006-07-02 13:58:51 -07:00
2006-08-09 00:12:47 -04:00
2006-07-02 13:58:51 -07:00
2006-08-03 17:29:59 -04:00
2006-07-12 18:39:21 -04:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-07-05 13:40:49 -04:00
2006-07-21 14:41:36 -07:00
2006-08-02 14:26:51 -04:00
2006-07-05 14:28:34 -04:00
2006-06-26 18:35:02 +02:00
2006-06-11 12:16:01 -04:00
2006-06-11 12:16:01 -04:00
2006-06-11 12:16:01 -04:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-01-08 20:14:07 -08:00
2006-01-28 21:42:28 -05:00
2006-07-12 17:42:40 -04:00
2006-07-05 14:29:26 -04:00
2006-07-03 15:27:09 -07:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-01-09 10:54:48 -05:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-03-25 08:22:52 -08:00
2006-03-25 08:22:52 -08:00
2006-06-23 02:06:41 -07:00
2006-06-30 19:25:36 +02:00
2006-06-11 23:19:00 -04:00
2006-07-05 13:42:57 -04:00
2006-06-22 23:16:13 -04:00
2006-06-30 19:25:36 +02:00
2006-06-17 21:30:47 -07:00
2006-08-17 16:29:51 -07:00
2006-08-17 16:29:51 -07:00
2006-07-05 13:42:57 -04:00
2006-03-20 22:34:09 -08:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-03-11 13:29:09 -05:00
2006-07-05 14:08:08 -04:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-03-03 21:33:57 -05:00
2006-07-02 13:58:51 -07:00
2006-07-05 13:40:49 -04:00
2006-06-26 23:47:50 -04:00
2006-07-02 13:58:51 -07:00
2006-07-21 15:09:07 -07:00
2006-07-02 13:58:51 -07:00
2006-01-09 10:54:48 -05:00
2006-07-05 13:42:57 -04:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-07-05 13:42:57 -04:00
2006-04-02 13:52:48 +02:00
2006-01-09 10:54:48 -05:00
2006-06-23 02:06:41 -07:00
2006-07-05 13:42:57 -04:00
2006-06-30 19:25:36 +02:00
2006-06-25 17:43:33 -07:00
2006-07-12 17:38:20 -04:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2005-11-18 13:31:26 -05:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-07-05 13:40:49 -04:00
2006-07-05 13:40:49 -04:00
2006-07-05 13:42:07 -04:00
2006-07-02 13:58:51 -07:00
2006-06-11 12:16:01 -04:00
2006-06-11 12:16:01 -04:00
2006-03-25 08:22:53 -08:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-05-24 01:31:14 -04:00
2006-06-30 19:25:36 +02:00
2006-05-24 01:31:14 -04:00
2006-07-21 14:56:02 -07:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-06-22 22:15:09 -07:00
2006-06-23 02:06:41 -07:00
2006-06-23 02:06:41 -07:00
2006-01-09 10:54:48 -05:00
2006-07-08 13:34:32 -07:00
2006-07-02 13:58:51 -07:00
2006-03-25 08:22:52 -08:00
2006-01-12 09:09:01 -08:00
2006-07-03 21:36:01 +10:00
2006-01-28 21:42:22 -05:00
2006-06-22 23:28:05 -04:00
2006-03-25 08:22:52 -08:00
2006-07-02 13:58:51 -07:00
2005-12-01 02:26:45 -05:00
2006-07-02 13:58:51 -07:00
2006-06-30 18:25:18 +02:00
2006-07-02 13:58:51 -07:00
2006-06-23 23:16:09 -07:00
2006-07-05 13:40:49 -04:00
2006-06-11 12:16:01 -04:00
2006-07-05 13:42:57 -04:00
2006-03-25 08:22:52 -08:00
2006-06-11 12:16:01 -04:00
2006-06-05 15:04:37 -07:00
2006-07-02 13:58:51 -07:00
2006-07-05 14:08:08 -04:00
2006-07-05 14:08:08 -04:00
2006-01-17 07:59:23 -05:00
2006-07-05 13:42:57 -04:00
2006-07-05 14:07:15 -04:00
2006-03-03 21:33:57 -05:00
2006-01-17 07:59:23 -05:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2005-11-08 09:40:47 -08:00
2006-03-03 21:33:57 -05:00
2006-06-05 15:34:33 -07:00
2006-01-03 13:11:23 -08:00
2006-07-05 13:42:57 -04:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-05-02 15:16:36 -04:00
2006-08-03 17:27:26 -04:00
2006-08-03 17:27:26 -04:00
2005-11-11 08:31:35 -05:00
2005-11-18 13:29:41 -05:00
2006-03-03 21:33:57 -05:00
2006-07-02 13:58:51 -07:00
2006-06-23 02:06:41 -07:00
2006-03-11 20:32:17 -05:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-04-20 17:29:43 -04:00
2006-07-02 13:58:51 -07:00
2005-11-09 07:55:57 -08:00
2006-07-29 01:23:51 -04:00
2006-07-12 18:39:21 -04:00
2006-07-17 13:27:46 -04:00
2006-07-12 18:39:21 -04:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-07-12 17:42:40 -04:00
2006-07-02 13:58:51 -07:00
2006-04-20 17:39:14 -04:00
2006-06-23 02:06:41 -07:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-06-23 02:06:41 -07:00
2006-06-30 19:25:36 +02:00
2006-06-30 19:25:36 +02:00
2006-01-17 07:25:01 -05:00
2006-07-17 13:30:12 -04:00
2006-07-17 13:30:12 -04:00
2006-07-05 13:40:50 -04:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-06-23 23:16:02 -07:00
2006-07-05 13:40:50 -04:00
2006-06-30 19:25:36 +02:00
2006-05-08 16:01:12 -07:00
2006-07-02 13:58:51 -07:00
2006-03-20 22:34:25 -08:00
2006-07-21 14:51:02 -07:00
2006-06-30 19:25:36 +02:00
2006-07-28 01:09:40 -07:00
2006-07-02 13:58:51 -07:00
2006-07-02 13:58:51 -07:00
2006-08-07 21:46:02 -07:00
2006-08-07 21:46:02 -07:00
2006-07-02 13:58:51 -07:00
2006-06-30 19:25:36 +02:00
2006-07-08 13:34:32 -07:00
2006-07-05 13:40:50 -04:00
2006-07-20 23:28:23 +02:00
2006-07-05 13:40:50 -04:00
2006-01-09 10:54:48 -05:00
2006-07-05 13:40:49 -04:00
2006-06-30 19:25:36 +02:00
2006-07-02 13:58:51 -07:00