mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
net: usb: cdc_ncm: don't enable BHs in tx_fixup under netpoll
netpoll holds the txq lock and calls ndo_start_xmit() with IRQs off but
BHs on. The spin_unlock_bh() in cdc_ncm_tx_fixup() then runs pending
softirqs. If one of them transmits, it spins on the txq lock that
netpoll holds. With netconsole on a cdc_ncm device this ends in a soft
or hard lockup.
Every caller of cdc_ncm_tx_fixup() holds the txq lock with BHs or IRQs
off, so the softirq user of ctx->mtx cannot interrupt it. Use plain
spin_lock().
Fixes: c84ff1d6df ("cdc_ncm: reduce driver latency in the data path")
Reported-by: Mikkel Eskildsen <mke@visotia.com>
Closes: https://lore.kernel.org/netdev/PRAP189MB185019A5A8D411482BB6E0CDA9982@PRAP189MB1850.EURP189.PROD.OUTLOOK.COM/
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20261024-cdc-ncm-netpoll-v3-1-6284ca03f967@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
9e2ba4a177
commit
108ca34cf4
|
|
@ -1535,14 +1535,17 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
|
|||
if (ctx == NULL)
|
||||
goto error;
|
||||
|
||||
spin_lock_bh(&ctx->mtx);
|
||||
/* BHs or IRQs are always off here. netpoll only disables IRQs, and
|
||||
* spin_unlock_bh() would then run softirqs with the txq lock held.
|
||||
*/
|
||||
spin_lock(&ctx->mtx);
|
||||
|
||||
if (ctx->is_ndp16)
|
||||
skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN));
|
||||
else
|
||||
skb_out = cdc_ncm_fill_tx_frame(dev, skb, cpu_to_le32(USB_CDC_NCM_NDP32_NOCRC_SIGN));
|
||||
|
||||
spin_unlock_bh(&ctx->mtx);
|
||||
spin_unlock(&ctx->mtx);
|
||||
return skb_out;
|
||||
|
||||
error:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user