Merge branch 'net-usb-cdc_ncm-cdc_mbim-fix-netpoll-lockup-in-tx_fixup'

Nicolai Buchwitz says:

====================
net: usb: cdc_ncm/cdc_mbim: fix netpoll lockup in tx_fixup

Mikkel reported lockups with netconsole on a cdc_ncm device. Further
analysis showed that netpoll calls ndo_start_xmit() with IRQs off but
BHs on while holding the txq lock, and the spin_unlock_bh() in the
tx_fixup paths runs pending softirqs. A transmit from one of them then
spins on that txq lock.

Patch 1 fixes cdc_ncm. Mikkel tested the v2 version of it. Patch 2
fixes the same code in cdc_mbim and is untested.
====================

Link: https://patch.msgid.link/20261024-cdc-ncm-netpoll-v3-0-6284ca03f967@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-10-26 18:36:34 -07:00
commit 4dca97647a
2 changed files with 8 additions and 4 deletions

View File

@ -289,9 +289,10 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb
}
}
spin_lock_bh(&ctx->mtx);
/* BHs or IRQs are always off here, see cdc_ncm_tx_fixup() */
spin_lock(&ctx->mtx);
skb_out = cdc_ncm_fill_tx_frame(dev, skb, sign);
spin_unlock_bh(&ctx->mtx);
spin_unlock(&ctx->mtx);
return skb_out;
error:

View File

@ -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: