summaryrefslogtreecommitdiff
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-01-26 11:02:59 +0100
committerThomas Gleixner <tglx@linutronix.de>2015-01-26 11:02:59 +0100
commit64c96a57b73397415eafa4ac2020ea7d99d7168c (patch)
treee71719d174d22aab6362858d383c292149ec8ae9 /net/core/dev.c
parente2e64a932556cdfae455497dbe94a8db151fc9fa (diff)
parent26bc420b59a38e4e6685a73345a0def461136dce (diff)
Merge branch 'linus' into irq/core
Reason: Pull in upstream fixes on which new patches depend on.
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 683d493aa1bf..171420e75b03 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7072,10 +7072,20 @@ static int dev_cpu_callback(struct notifier_block *nfb,
oldsd->output_queue = NULL;
oldsd->output_queue_tailp = &oldsd->output_queue;
}
- /* Append NAPI poll list from offline CPU. */
- if (!list_empty(&oldsd->poll_list)) {
- list_splice_init(&oldsd->poll_list, &sd->poll_list);
- raise_softirq_irqoff(NET_RX_SOFTIRQ);
+ /* Append NAPI poll list from offline CPU, with one exception :
+ * process_backlog() must be called by cpu owning percpu backlog.
+ * We properly handle process_queue & input_pkt_queue later.
+ */
+ while (!list_empty(&oldsd->poll_list)) {
+ struct napi_struct *napi = list_first_entry(&oldsd->poll_list,
+ struct napi_struct,
+ poll_list);
+
+ list_del_init(&napi->poll_list);
+ if (napi->poll == process_backlog)
+ napi->state = 0;
+ else
+ ____napi_schedule(sd, napi);
}
raise_softirq_irqoff(NET_TX_SOFTIRQ);
@@ -7086,7 +7096,7 @@ static int dev_cpu_callback(struct notifier_block *nfb,
netif_rx_internal(skb);
input_queue_head_incr(oldsd);
}
- while ((skb = __skb_dequeue(&oldsd->input_pkt_queue))) {
+ while ((skb = skb_dequeue(&oldsd->input_pkt_queue))) {
netif_rx_internal(skb);
input_queue_head_incr(oldsd);
}