diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-09-07 18:41:21 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-09-07 18:41:21 -0700 |
commit | e8a83e10d7dfe5d0841062780769b30f65417e15 (patch) | |
tree | bc7069b34bb3173970ec06690323a1ab0f89ff56 /net | |
parent | e3b802ba885b54f4050164c3cfd9e0ba9c73173a (diff) | |
download | linux-e8a83e10d7dfe5d0841062780769b30f65417e15.tar.bz2 |
pkt_sched: Fix qdisc state in net_tx_action()
net_tx_action() can skip __QDISC_STATE_SCHED bit clearing while qdisc
is neither ran nor rescheduled, which may cause endless loop in
dev_deactivate().
Reported-by: Denys Fedoryshchenko <denys@visp.net.lb>
Tested-by: Denys Fedoryshchenko <denys@visp.net.lb>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 60c51f765887..e719ed29310f 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1991,8 +1991,13 @@ static void net_tx_action(struct softirq_action *h) spin_unlock(root_lock); } else { if (!test_bit(__QDISC_STATE_DEACTIVATED, - &q->state)) + &q->state)) { __netif_reschedule(q); + } else { + smp_mb__before_clear_bit(); + clear_bit(__QDISC_STATE_SCHED, + &q->state); + } } } } |