summaryrefslogtreecommitdiff
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-18 17:56:43 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-03-18 17:56:43 -0800
commit27cd7e0feb7d4e8ddc87296bf30ad0de3b19f4c0 (patch)
tree43323e6369cc01fa82c09b97058c5e50a89e66a8 /net/core/dev.c
parentf319c80942729320e8725e61272dcd290d30fef6 (diff)
parentc4620fd637bc33f0c2efabd43586de03675336cd (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.c48
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;