diff options
author | David S. Miller <davem@davemloft.net> | 2005-06-24 23:18:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-06-24 23:18:35 -0400 |
commit | f47c11eeccc8820010992eb32dbe7370a08f8bd3 (patch) | |
tree | 7cd6308a1796fae227c61208545593b79b12f21a /drivers/net/tg3.h | |
parent | cd024c8baf9756759c57f0a19be639da8d3d4f8c (diff) |
[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 { | |||
2006 | struct tg3 { | 2006 | struct tg3 { |
2007 | /* begin "general, frequently-used members" cacheline section */ | 2007 | /* begin "general, frequently-used members" cacheline section */ |
2008 | 2008 | ||
2009 | /* If the IRQ handler (which runs lockless) needs to be | ||
2010 | * quiesced, the following bitmask state is used. The | ||
2011 | * SYNC flag is set by non-IRQ context code to initiate | ||
2012 | * the quiescence. | ||
2013 | * | ||
2014 | * When the IRQ handler notices that SYNC is set, it | ||
2015 | * disables interrupts and returns. | ||
2016 | * | ||
2017 | * When all outstanding IRQ handlers have returned after | ||
2018 | * the SYNC flag has been set, the setter can be assured | ||
2019 | * that interrupts will no longer get run. | ||
2020 | * | ||
2021 | * In this way all SMP driver locks are never acquired | ||
2022 | * in hw IRQ context, only sw IRQ context or lower. | ||
2023 | */ | ||
2024 | unsigned int irq_sync; | ||
2025 | |||
2009 | /* SMP locking strategy: | 2026 | /* SMP locking strategy: |
2010 | * | 2027 | * |
2011 | * lock: Held during all operations except TX packet | 2028 | * lock: Held during all operations except TX packet |
2012 | * processing. | 2029 | * processing. |
2013 | * | 2030 | * |
2014 | * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx | 2031 | * tx_lock: Held during tg3_start_xmit and tg3_tx |
2015 | * | 2032 | * |
2016 | * If you want to shut up all asynchronous processing you must | 2033 | * Both of these locks are to be held with BH safety. |
2017 | * acquire both locks, 'lock' taken before 'tx_lock'. IRQs must | ||
2018 | * be disabled to take 'lock' but only softirq disabling is | ||
2019 | * necessary for acquisition of 'tx_lock'. | ||
2020 | */ | 2034 | */ |
2021 | spinlock_t lock; | 2035 | spinlock_t lock; |
2022 | spinlock_t indirect_lock; | 2036 | spinlock_t indirect_lock; |