Patch "net: call rcu_read_lock early in process_backlog" has been added to the 3.14-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
net: call rcu_read_lock early in process_backlog
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
net-call-rcu_read_lock-early-in-process_backlog.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Sat Sep 26 11:19:08 PDT 2015
From: Julian Anastasov <[email protected]>
Date: Thu, 9 Jul 2015 09:59:10 +0300
Subject: net: call rcu_read_lock early in process_backlog
From: Julian Anastasov <[email protected]>
[ Upstream commit 2c17d27c36dcce2b6bf689f41a46b9e909877c21 ]
Incoming packet should be either in backlog queue or in RCU read-side section. Otherwise, the final sequence of flush_backlog() and synchronize_net() may miss packets that can run without device reference:
CPU 1 CPU 2
skb->dev: no reference
process_backlog:__skb_dequeue
process_backlog:local_irq_enableon_each_cpu forflush_backlog => IPI(hardirq): flush_backlog
- packet not found in backlog
CPU delayed ...synchronize_net
- no ongoing RCU
read-side sections
netdev_run_todo,rcu_barrier: no
ongoing callbacks
__netif_receive_skb_core:rcu_read_lock
- too late
free dev
process packet for freed dev
--- net/core/dev.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-)
net/core/dev.c +14 -15
@@ -3554,8 +3554,6 @@ static int __netif_receive_skb_core(stru pt_prev =NULL ; -rcu_read_lock (); - another_round: skb->skb_iif = skb->dev->ifindex;
@@ -3565,7 +3563,7 @@ another_round: skb->protocol == cpu_to_be16(ETH_P_8021AD)) { skb =skb_vlan_untag (skb);if (unlikely (!skb)) - goto unlock; + goto out; }#ifdef CONFIG_NET_CLS_ACT
@@ -3590,7 +3588,7 @@ skip_taps:#ifdef CONFIG_NET_CLS_ACT skb =handle_ing (skb, &pt_prev, &ret, orig_dev);if (!skb) - goto unlock; + goto out; ncls:#endif
@@ -3605,7 +3603,7 @@ ncls:if (vlan_do_receive (&skb)) goto another_round;else if (unlikely (!skb)) - goto unlock; + goto out; } rx_handler =rcu_dereference (skb->dev->rx_handler);
@@ -3617,7 +3615,7 @@ ncls:switch (rx_handler (&skb)) {case RX_HANDLER_CONSUMED : ret =NET_RX_SUCCESS ; - goto unlock; + goto out;case RX_HANDLER_ANOTHER : goto another_round;case RX_HANDLER_EXACT :
@@ -3669,8 +3667,6 @@ drop: ret =NET_RX_DROP ; } -unlock: -rcu_read_unlock (); out:return ret; }
@@ -3702,29 +3698,30 @@ static int __netif_receive_skb(struct skstatic int netif_receive_skb_internal (struct sk_buff *skb) { +int ret; +net_timestamp_check (netdev_tstamp_prequeue, skb);if (skb_defer_rx_timestamp (skb))return NET_RX_SUCCESS ; +rcu_read_lock (); +#ifdef CONFIG_RPS if (static_key_false (&rps_needed)) {struct rps_dev_flow voidflow, *rflow = &voidflow; -int cpu, ret; - -rcu_read_lock (); - - cpu =get_rps_cpu (skb->dev, skb, &rflow); +int cpu =get_rps_cpu (skb->dev, skb, &rflow);if (cpu >=0 ) { ret =enqueue_to_backlog (skb, cpu, &rflow->last_qtail);rcu_read_unlock ();return ret; } -rcu_read_unlock (); }#endif -return __netif_receive_skb (skb); + ret =__netif_receive_skb (skb); +rcu_read_unlock (); +return ret; }/**
@@ -4185,8 +4182,10 @@ static int process_backlog(struct napi_sunsigned int qlen;while ((skb =__skb_dequeue (&sd->process_queue))) { +rcu_read_lock ();local_irq_enable ();__netif_receive_skb (skb); +rcu_read_unlock ();local_irq_disable ();input_queue_head_incr (sd);if (++work >= quota) {
Patches currently in stable-queue which might be from [email protected] are
queue-3.14/net-call-rcu_read_lock-early-in-process_backlog.patch queue-3.14/net-do-not-process-device-backlog-during-unregistration.patch