pkt_sched: Fix qdisc state in net_tx_action()
authorJarek Poplawski <jarkao2@gmail.com>
Mon, 8 Sep 2008 01:41:21 +0000 (18:41 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 8 Sep 2008 01:41:21 +0000 (18:41 -0700)
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>
net/core/dev.c

index 60c51f7658870257571ee9455f95bb48888b4398..e719ed29310ff5695c347db907a6311aa79e36c5 100644 (file)
@@ -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);
+                               }
                        }
                }
        }