diff options
author | Jarek Poplawski <jarkao2@gmail.com> | 2008-08-18 00:54:43 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-18 00:54:43 -0400 |
commit | def82a1db1fdc4f861c77009e2ee86870c3743b0 (patch) | |
tree | da2164c77beda2d5b0b4083969e8a2eeff837ff5 /net/core/dev.c | |
parent | a9312ae89324438b0edc554eb36c3ec6bf927d04 (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/dev.c')
-rw-r--r-- | net/core/dev.c | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index d9e31f63aded..819f0175bdc9 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 | ||
1342 | void __netif_schedule(struct Qdisc *q) | 1342 | static 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 | |||
1355 | void __netif_schedule(struct Qdisc *q) | ||
1356 | { | ||
1357 | if (!test_and_set_bit(__QDISC_STATE_SCHED, &q->state)) | ||
1358 | __netif_reschedule(q); | ||
1355 | } | 1359 | } |
1356 | EXPORT_SYMBOL(__netif_schedule); | 1360 | EXPORT_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 | } |