cdc_mbim_tx_fixup() has the same spin_unlock_bh() as cdc_ncm_tx_fixup(). Under netpoll it runs pending softirqs while the txq lock is held, and a transmit from one of them spins on that lock. Use spin_lock_irqsave() as in cdc_ncm. Fixes: 9bf211a30b3f ("net: cdc_mbim: adding MBIM driver") Signed-off-by: Nicolai Buchwitz --- drivers/net/usb/cdc_mbim.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index a7010a0664c7d..7158716c1f106 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -223,6 +223,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb struct cdc_mbim_state *info = (void *)&dev->data; struct cdc_ncm_ctx *ctx = info->ctx; __le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN); + unsigned long irqflags; u16 tci = 0; bool is_ip; u8 *c; @@ -289,9 +290,10 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb } } - spin_lock_bh(&ctx->mtx); + /* IRQs are off and BHs on under netpoll, see cdc_ncm_tx_fixup() */ + spin_lock_irqsave(&ctx->mtx, irqflags); skb_out = cdc_ncm_fill_tx_frame(dev, skb, sign); - spin_unlock_bh(&ctx->mtx); + spin_unlock_irqrestore(&ctx->mtx, irqflags); return skb_out; error: -- 2.53.0