diff options
author | David S. Miller <davem@davemloft.net> | 2005-06-25 07:18:35 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-25 07:18:35 +0400 |
commit | f47c11eeccc8820010992eb32dbe7370a08f8bd3 (patch) | |
tree | 7cd6308a1796fae227c61208545593b79b12f21a /drivers/net/tg3.h | |
parent | cd024c8baf9756759c57f0a19be639da8d3d4f8c (diff) | |
download | linux-f47c11eeccc8820010992eb32dbe7370a08f8bd3.tar.xz |
[TG3]: Eliminate all hw IRQ handler spinlocks.
Move all driver spinlocks to be taken at sw IRQ
context only.
This fixes the skb_copy() we were doing with hw
IRQs disabled (which is illegal and triggers a
BUG() with HIGHMEM enabled). It also simplifies
the locking all over the driver tremendously.
We accomplish this feat by creating a special
sequence to synchronize with the hw IRQ handler
using a binary state and synchronize_irq().
This idea is from Herbert Xu.
Thanks to Michael Chan for helping to track down
all of the race conditions in initial versions
of this code.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.h')
-rw-r--r-- | drivers/net/tg3.h | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 993f84c93dc4..99c5f9675a56 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2006,17 +2006,31 @@ struct tg3_ethtool_stats { struct tg3 { /* begin "general, frequently-used members" cacheline section */ + /* If the IRQ handler (which runs lockless) needs to be + * quiesced, the following bitmask state is used. The + * SYNC flag is set by non-IRQ context code to initiate + * the quiescence. + * + * When the IRQ handler notices that SYNC is set, it + * disables interrupts and returns. + * + * When all outstanding IRQ handlers have returned after + * the SYNC flag has been set, the setter can be assured + * that interrupts will no longer get run. + * + * In this way all SMP driver locks are never acquired + * in hw IRQ context, only sw IRQ context or lower. + */ + unsigned int irq_sync; + /* SMP locking strategy: * * lock: Held during all operations except TX packet * processing. * - * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx + * tx_lock: Held during tg3_start_xmit and tg3_tx * - * If you want to shut up all asynchronous processing you must - * acquire both locks, 'lock' taken before 'tx_lock'. IRQs must - * be disabled to take 'lock' but only softirq disabling is - * necessary for acquisition of 'tx_lock'. + * Both of these locks are to be held with BH safety. */ spinlock_t lock; spinlock_t indirect_lock; |