aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJarek Poplawski <jarkao2@gmail.com>2008-09-07 21:41:21 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-07 21:41:21 -0400
commite8a83e10d7dfe5d0841062780769b30f65417e15 (patch)
treebc7069b34bb3173970ec06690323a1ab0f89ff56 /net
parente3b802ba885b54f4050164c3cfd9e0ba9c73173a (diff)
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.c7
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)
1991 spin_unlock(root_lock); 1991 spin_unlock(root_lock);
1992 } else { 1992 } else {
1993 if (!test_bit(__QDISC_STATE_DEACTIVATED, 1993 if (!test_bit(__QDISC_STATE_DEACTIVATED,
1994 &q->state)) 1994 &q->state)) {
1995 __netif_reschedule(q); 1995 __netif_reschedule(q);
1996 } else {
1997 smp_mb__before_clear_bit();
1998 clear_bit(__QDISC_STATE_SCHED,
1999 &q->state);
2000 }
1996 } 2001 }
1997 } 2002 }
1998 } 2003 }