• Patrick McHardy's avatar
    [NET_SCHED]: Revert "avoid transmit softirq on watchdog wakeup" optimization · 0621ed2e
    Patrick McHardy authored
    As noticed by Ranko Zivojnovic <ranko@spidernet.net>, calling qdisc_run
    from the timer handler can result in deadlock:
    
    > CPU#0
    >
    > qdisc_watchdog() fires and gets dev->queue_lock
    > qdisc_run()...qdisc_restart()...
    > -> releases dev->queue_lock and enters dev_hard_start_xmit()
    >
    > CPU#1
    >
    > tc del qdisc dev ...
    > qdisc_graft()...dev_graft_qdisc()...dev_deactivate()...
    > -> grabs dev->queue_lock ...
    >
    > qdisc_reset()...{cbq,hfsc,htb,netem,tbf}_reset()...qdisc_watchdog_cancel()...
    > -> hrtimer_cancel() - waiting for the qdisc_watchdog() to exit, while still
    >		        holding dev->queue_lock
    >
    > CPU#0
    >
    > dev_hard_start_xmit() returns ...
    > -> wants to get dev->queue_lock(!)
    >
    > DEADLOCK!
    
    The entire optimization is a bit questionable IMO, it moves potentially
    large parts of NET_TX_SOFTIRQ work to TIMER_SOFTIRQ/HRTIMER_SOFTIRQ,
    which kind of defeats the separation of them.
    Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
    Acked-by: default avatarRanko Zivojnovic <ranko@spidernet.net>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0621ed2e
sch_api.c 28.8 KB