提交 f47c11ee 编写于 作者: D David S. Miller

[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: NDavid S. Miller <davem@davemloft.net>
上级 cd024c8b
此差异已折叠。
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册