mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
pcnet32: stop holding device spin lock during napi_complete_done
napi_complete_done may call gro_flush_normal (though not currently, as GRO
is unsupported at the moment), which may result in packet TX. This will
eventually result in calling pcnet32_start_xmit - resulting in a deadlock
while trying to re-acquire the already locked spin lock.
It is safe to split the spinlock block into two, because the hardware
registers are still protected from concurrent access, and the two blocks
perform unrelated operations that don't need to happen atomically.
Fixes: 5b2ec6f2be ("pcnet32: use napi_complete_done()")
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Oscar Maes <oscmaes92@gmail.com>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Link: https://patch.msgid.link/20260528140320.5556-1-oscmaes92@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
3522b21fd7
commit
73bf3cca7d
|
|
@ -1407,8 +1407,10 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
|
|||
pcnet32_restart(dev, CSR0_START);
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
spin_unlock_irqrestore(&lp->lock, flags);
|
||||
|
||||
if (work_done < budget && napi_complete_done(napi, work_done)) {
|
||||
spin_lock_irqsave(&lp->lock, flags);
|
||||
/* clear interrupt masks */
|
||||
val = lp->a->read_csr(ioaddr, CSR3);
|
||||
val &= 0x00ff;
|
||||
|
|
@ -1416,9 +1418,9 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
|
|||
|
||||
/* Set interrupt enable. */
|
||||
lp->a->write_csr(ioaddr, CSR0, CSR0_INTEN);
|
||||
spin_unlock_irqrestore(&lp->lock, flags);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&lp->lock, flags);
|
||||
return work_done;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user