Re: [PATCH net v2 1/2] netpoll: use a raw lock for the deferred transmit queue

From: Karl Mehltretter

Date: Thu Oct 01 2026 - 19:31:25 EST


On Thu, Oct 01, 2026 at 09:48:19AM +0100, Sebastian Andrzej Siewior wrote:
> On 2026-09-30 21:21:02 [+0200], Karl Mehltretter wrote:
> > netpoll_send_skb() calls __netpoll_send_skb() with hard interrupts
> > disabled. When direct transmission cannot complete, the latter queues
> > the skb with skb_queue_tail(). The sk_buff_head lock may sleep on
> > PREEMPT_RT:
> >
> > BUG: sleeping function called from invalid context
> > in_atomic(): 0, irqs_disabled(): 1, non_block: 0
> > rt_spin_lock
> > skb_queue_tail
> > netpoll_send_skb
>
> How is this possible? netpoll is only used by netconsole right? And this
> is CON_NBCON so it only prints threaded. What is the missing piece?
>

The call is from the NBCON printer thread, but netpoll_send_skb()
explicitly disables hard interrupts around __netpoll_send_skb():

local_irq_save(flags);
ret = __netpoll_send_skb(np, skb);
local_irq_restore(flags);

When direct transmission cannot complete, __netpoll_send_skb() calls
skb_queue_tail() before interrupts are restored. Its spinlock can sleep
on PREEMPT_RT despite the caller being a thread.

The deferred skb is later handled by queue_process(), a workqueue
callback. Its requeue path has the same IRQ-disabled locking:

local_irq_save(flags);
[...]
HARD_TX_LOCK(dev, txq, smp_processor_id());
if (netif_xmit_frozen_or_stopped(txq) ||
!dev_xmit_complete(netpoll_start_xmit(skb, dev, txq))) {
skb_queue_head(&npinfo->txq, skb);
HARD_TX_UNLOCK(dev, txq);
local_irq_restore(flags);
[...]
}

Thanks,
Karl