aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJarek Poplawski <jarkao2@gmail.com>2008-08-18 00:54:43 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-18 00:54:43 -0400
commitdef82a1db1fdc4f861c77009e2ee86870c3743b0 (patch)
treeda2164c77beda2d5b0b4083969e8a2eeff837ff5 /net/core
parenta9312ae89324438b0edc554eb36c3ec6bf927d04 (diff)
net: Change handling of the __QDISC_STATE_SCHED flag in net_tx_action().
Change handling of the __QDISC_STATE_SCHED flag in net_tx_action() to enable proper control in dev_deactivate(). Now, if this flag is seen as unset under root_lock means a qdisc can't be netif_scheduled. Signed-off-by: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d9e31f63ade..819f0175bdc 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1339,19 +1339,23 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
1339} 1339}
1340 1340
1341 1341
1342void __netif_schedule(struct Qdisc *q) 1342static inline void __netif_reschedule(struct Qdisc *q)
1343{ 1343{
1344 if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) { 1344 struct softnet_data *sd;
1345 struct softnet_data *sd; 1345 unsigned long flags;
1346 unsigned long flags;
1347 1346
1348 local_irq_save(flags); 1347 local_irq_save(flags);
1349 sd = &__get_cpu_var(softnet_data); 1348 sd = &__get_cpu_var(softnet_data);
1350 q->next_sched = sd->output_queue; 1349 q->next_sched = sd->output_queue;
1351 sd->output_queue = q; 1350 sd->output_queue = q;
1352 raise_softirq_irqoff(NET_TX_SOFTIRQ); 1351 raise_softirq_irqoff(NET_TX_SOFTIRQ);
1353 local_irq_restore(flags); 1352 local_irq_restore(flags);
1354 } 1353}
1354
1355void __netif_schedule(struct Qdisc *q)
1356{
1357 if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state))
1358 __netif_reschedule(q);
1355} 1359}
1356EXPORT_SYMBOL(__netif_schedule); 1360EXPORT_SYMBOL(__netif_schedule);
1357 1361
@@ -1980,15 +1984,15 @@ static void net_tx_action(struct softirq_action *h)
1980 1984
1981 head = head->next_sched; 1985 head = head->next_sched;
1982 1986
1983 smp_mb__before_clear_bit();
1984 clear_bit(__QDISC_STATE_SCHED, &q->state);
1985
1986 root_lock = qdisc_lock(q); 1987 root_lock = qdisc_lock(q);
1987 if (spin_trylock(root_lock)) { 1988 if (spin_trylock(root_lock)) {
1989 smp_mb__before_clear_bit();
1990 clear_bit(__QDISC_STATE_SCHED,
1991 &q->state);
1988 qdisc_run(q); 1992 qdisc_run(q);
1989 spin_unlock(root_lock); 1993 spin_unlock(root_lock);
1990 } else { 1994 } else {
1991 __netif_schedule(q); 1995 __netif_reschedule(q);
1992 } 1996 }
1993 } 1997 }
1994 } 1998 }