Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=0621ed2e4edbe2f6f83dafbf85eecefae7aaf2e8
Commit:     0621ed2e4edbe2f6f83dafbf85eecefae7aaf2e8
Parent:     59eecdfb166f6846ae356ddc744abed5820ad965
Author:     Patrick McHardy <[EMAIL PROTECTED]>
AuthorDate: Sat Jul 14 20:49:26 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Sat Jul 14 20:49:26 2007 -0700

    [NET_SCHED]: Revert "avoid transmit softirq on watchdog wakeup" optimization
    
    As noticed by Ranko Zivojnovic <[EMAIL PROTECTED]>, 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: Patrick McHardy <[EMAIL PROTECTED]>
    Acked-by: Ranko Zivojnovic <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/sched/sch_api.c |    6 +-----
 1 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index d92ea26..4fd0bec 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -278,11 +278,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer 
*timer)
 
        wd->qdisc->flags &= ~TCQ_F_THROTTLED;
        smp_wmb();
-       if (spin_trylock(&dev->queue_lock)) {
-               qdisc_run(dev);
-               spin_unlock(&dev->queue_lock);
-       } else
-               netif_schedule(dev);
+       netif_schedule(dev);
 
        return HRTIMER_NORESTART;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to