diff options
author | Changli Gao <xiaosuo@gmail.com> | 2010-04-26 19:06:24 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-27 17:32:12 -0400 |
commit | a9cbd588fdb71ea415754c885e2f9f03e6bf1ba0 (patch) | |
tree | 68506bd4299f34b3ed31b76eb575e79c61e198fb | |
parent | bb611874650cff942a7466b456a791e8bfa641e7 (diff) |
net: reimplement softnet_data.output_queue as a FIFO queue
reimplement softnet_data.output_queue as a FIFO queue to keep the
fairness among the qdiscs rescheduled.
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
----
include/linux/netdevice.h | 1 +
net/core/dev.c | 22 ++++++++++++----------
2 files changed, 13 insertions(+), 10 deletions(-)
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | net/core/dev.c | 22 |
2 files changed, 13 insertions, 10 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 3c5ed5f5274e..c04ca246395d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1385,6 +1385,7 @@ static inline int unregister_gifconf(unsigned int family) | |||
1385 | */ | 1385 | */ |
1386 | struct softnet_data { | 1386 | struct softnet_data { |
1387 | struct Qdisc *output_queue; | 1387 | struct Qdisc *output_queue; |
1388 | struct Qdisc **output_queue_tailp; | ||
1388 | struct list_head poll_list; | 1389 | struct list_head poll_list; |
1389 | struct sk_buff *completion_queue; | 1390 | struct sk_buff *completion_queue; |
1390 | 1391 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 4d43f1a80f74..3d314919a2cf 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1557,8 +1557,9 @@ static inline void __netif_reschedule(struct Qdisc *q) | |||
1557 | 1557 | ||
1558 | local_irq_save(flags); | 1558 | local_irq_save(flags); |
1559 | sd = &__get_cpu_var(softnet_data); | 1559 | sd = &__get_cpu_var(softnet_data); |
1560 | q->next_sched = sd->output_queue; | 1560 | q->next_sched = NULL; |
1561 | sd->output_queue = q; | 1561 | *sd->output_queue_tailp = q; |
1562 | sd->output_queue_tailp = &q->next_sched; | ||
1562 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 1563 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
1563 | local_irq_restore(flags); | 1564 | local_irq_restore(flags); |
1564 | } | 1565 | } |
@@ -2529,6 +2530,7 @@ static void net_tx_action(struct softirq_action *h) | |||
2529 | local_irq_disable(); | 2530 | local_irq_disable(); |
2530 | head = sd->output_queue; | 2531 | head = sd->output_queue; |
2531 | sd->output_queue = NULL; | 2532 | sd->output_queue = NULL; |
2533 | sd->output_queue_tailp = &sd->output_queue; | ||
2532 | local_irq_enable(); | 2534 | local_irq_enable(); |
2533 | 2535 | ||
2534 | while (head) { | 2536 | while (head) { |
@@ -5594,7 +5596,6 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
5594 | void *ocpu) | 5596 | void *ocpu) |
5595 | { | 5597 | { |
5596 | struct sk_buff **list_skb; | 5598 | struct sk_buff **list_skb; |
5597 | struct Qdisc **list_net; | ||
5598 | struct sk_buff *skb; | 5599 | struct sk_buff *skb; |
5599 | unsigned int cpu, oldcpu = (unsigned long)ocpu; | 5600 | unsigned int cpu, oldcpu = (unsigned long)ocpu; |
5600 | struct softnet_data *sd, *oldsd; | 5601 | struct softnet_data *sd, *oldsd; |
@@ -5615,13 +5616,13 @@ static int dev_cpu_callback(struct notifier_block *nfb, | |||
5615 | *list_skb = oldsd->completion_queue; | 5616 | *list_skb = oldsd->completion_queue; |
5616 | oldsd->completion_queue = NULL; | 5617 | oldsd->completion_queue = NULL; |
5617 | 5618 | ||
5618 | /* Find end of our output_queue. */ | ||
5619 | list_net = &sd->output_queue; | ||
5620 | while (*list_net) | ||
5621 | list_net = &(*list_net)->next_sched; | ||
5622 | /* Append output queue from offline CPU. */ | 5619 | /* Append output queue from offline CPU. */ |
5623 | *list_net = oldsd->output_queue; | 5620 | if (oldsd->output_queue) { |
5624 | oldsd->output_queue = NULL; | 5621 | *sd->output_queue_tailp = oldsd->output_queue; |
5622 | sd->output_queue_tailp = oldsd->output_queue_tailp; | ||
5623 | oldsd->output_queue = NULL; | ||
5624 | oldsd->output_queue_tailp = &oldsd->output_queue; | ||
5625 | } | ||
5625 | 5626 | ||
5626 | raise_softirq_irqoff(NET_TX_SOFTIRQ); | 5627 | raise_softirq_irqoff(NET_TX_SOFTIRQ); |
5627 | local_irq_enable(); | 5628 | local_irq_enable(); |
@@ -5851,7 +5852,8 @@ static int __init net_dev_init(void) | |||
5851 | skb_queue_head_init(&sd->input_pkt_queue); | 5852 | skb_queue_head_init(&sd->input_pkt_queue); |
5852 | sd->completion_queue = NULL; | 5853 | sd->completion_queue = NULL; |
5853 | INIT_LIST_HEAD(&sd->poll_list); | 5854 | INIT_LIST_HEAD(&sd->poll_list); |
5854 | 5855 | sd->output_queue = NULL; | |
5856 | sd->output_queue_tailp = &sd->output_queue; | ||
5855 | #ifdef CONFIG_RPS | 5857 | #ifdef CONFIG_RPS |
5856 | sd->csd.func = rps_trigger_softirq; | 5858 | sd->csd.func = rps_trigger_softirq; |
5857 | sd->csd.info = sd; | 5859 | sd->csd.info = sd; |