diff options
| author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-03-18 17:56:43 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-03-18 17:56:43 -0800 |
| commit | 27cd7e0feb7d4e8ddc87296bf30ad0de3b19f4c0 (patch) | |
| tree | 43323e6369cc01fa82c09b97058c5e50a89e66a8 /net/core/dev.c | |
| parent | f319c80942729320e8725e61272dcd290d30fef6 (diff) | |
| parent | c4620fd637bc33f0c2efabd43586de03675336cd (diff) | |
Merge http://linux-sound.bkbits.net/linux-sound
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'net/core/dev.c')
| -rw-r--r-- | net/core/dev.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index b4418fb5eb25..201878db9853 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -76,6 +76,7 @@ #include <asm/system.h> #include <asm/bitops.h> #include <linux/config.h> +#include <linux/cpu.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -3131,6 +3132,52 @@ int unregister_netdevice(struct net_device *dev) return 0; } +#ifdef CONFIG_HOTPLUG_CPU +static int dev_cpu_callback(struct notifier_block *nfb, + unsigned long action, + void *ocpu) +{ + struct sk_buff **list_skb; + struct net_device **list_net; + struct sk_buff *skb; + unsigned int cpu, oldcpu = (unsigned long)ocpu; + struct softnet_data *sd, *oldsd; + + if (action != CPU_DEAD) + return NOTIFY_OK; + + local_irq_disable(); + cpu = smp_processor_id(); + sd = &per_cpu(softnet_data, cpu); + oldsd = &per_cpu(softnet_data, oldcpu); + + /* Find end of our completion_queue. */ + list_skb = &sd->completion_queue; + while (*list_skb) + list_skb = &(*list_skb)->next; + /* Append completion queue from offline CPU. */ + *list_skb = oldsd->completion_queue; + oldsd->completion_queue = NULL; + + /* Find end of our output_queue. */ + list_net = &sd->output_queue; + while (*list_net) + list_net = &(*list_net)->next_sched; + /* Append output queue from offline CPU. */ + *list_net = oldsd->output_queue; + oldsd->output_queue = NULL; + + raise_softirq_irqoff(NET_TX_SOFTIRQ); + local_irq_enable(); + + /* Process offline CPU's input_pkt_queue */ + while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) + netif_rx(skb); + + return NOTIFY_OK; +} +#endif /* CONFIG_HOTPLUG_CPU */ + /* * Initialize the DEV module. At boot time this walks the device list and @@ -3195,6 +3242,7 @@ static int __init net_dev_init(void) open_softirq(NET_TX_SOFTIRQ, net_tx_action, NULL); open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL); + hotcpu_notifier(dev_cpu_callback, 0); dst_init(); dev_mcast_init(); rc = 0; |
