Skip to content

Commit 2c17d27

Browse files
Julian Anastasovdavem330
authored andcommitted
net: call rcu_read_lock early in process_backlog
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_enable on_each_cpu for flush_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 Fixes: 6e583ce ("net: eliminate refcounting in backlog queue") Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: Stephen Hemminger <stephen@networkplumber.org> Signed-off-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e9e4dd3 commit 2c17d27

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

net/core/dev.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3774,8 +3774,6 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
37743774

37753775
pt_prev = NULL;
37763776

3777-
rcu_read_lock();
3778-
37793777
another_round:
37803778
skb->skb_iif = skb->dev->ifindex;
37813779

@@ -3785,7 +3783,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
37853783
skb->protocol == cpu_to_be16(ETH_P_8021AD)) {
37863784
skb = skb_vlan_untag(skb);
37873785
if (unlikely(!skb))
3788-
goto unlock;
3786+
goto out;
37893787
}
37903788

37913789
#ifdef CONFIG_NET_CLS_ACT
@@ -3815,10 +3813,10 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
38153813
if (static_key_false(&ingress_needed)) {
38163814
skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
38173815
if (!skb)
3818-
goto unlock;
3816+
goto out;
38193817

38203818
if (nf_ingress(skb, &pt_prev, &ret, orig_dev) < 0)
3821-
goto unlock;
3819+
goto out;
38223820
}
38233821
#endif
38243822
#ifdef CONFIG_NET_CLS_ACT
@@ -3836,7 +3834,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
38363834
if (vlan_do_receive(&skb))
38373835
goto another_round;
38383836
else if (unlikely(!skb))
3839-
goto unlock;
3837+
goto out;
38403838
}
38413839

38423840
rx_handler = rcu_dereference(skb->dev->rx_handler);
@@ -3848,7 +3846,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
38483846
switch (rx_handler(&skb)) {
38493847
case RX_HANDLER_CONSUMED:
38503848
ret = NET_RX_SUCCESS;
3851-
goto unlock;
3849+
goto out;
38523850
case RX_HANDLER_ANOTHER:
38533851
goto another_round;
38543852
case RX_HANDLER_EXACT:
@@ -3902,8 +3900,7 @@ static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
39023900
ret = NET_RX_DROP;
39033901
}
39043902

3905-
unlock:
3906-
rcu_read_unlock();
3903+
out:
39073904
return ret;
39083905
}
39093906

@@ -3934,29 +3931,30 @@ static int __netif_receive_skb(struct sk_buff *skb)
39343931

39353932
static int netif_receive_skb_internal(struct sk_buff *skb)
39363933
{
3934+
int ret;
3935+
39373936
net_timestamp_check(netdev_tstamp_prequeue, skb);
39383937

39393938
if (skb_defer_rx_timestamp(skb))
39403939
return NET_RX_SUCCESS;
39413940

3941+
rcu_read_lock();
3942+
39423943
#ifdef CONFIG_RPS
39433944
if (static_key_false(&rps_needed)) {
39443945
struct rps_dev_flow voidflow, *rflow = &voidflow;
3945-
int cpu, ret;
3946-
3947-
rcu_read_lock();
3948-
3949-
cpu = get_rps_cpu(skb->dev, skb, &rflow);
3946+
int cpu = get_rps_cpu(skb->dev, skb, &rflow);
39503947

39513948
if (cpu >= 0) {
39523949
ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
39533950
rcu_read_unlock();
39543951
return ret;
39553952
}
3956-
rcu_read_unlock();
39573953
}
39583954
#endif
3959-
return __netif_receive_skb(skb);
3955+
ret = __netif_receive_skb(skb);
3956+
rcu_read_unlock();
3957+
return ret;
39603958
}
39613959

39623960
/**
@@ -4501,8 +4499,10 @@ static int process_backlog(struct napi_struct *napi, int quota)
45014499
struct sk_buff *skb;
45024500

45034501
while ((skb = __skb_dequeue(&sd->process_queue))) {
4502+
rcu_read_lock();
45044503
local_irq_enable();
45054504
__netif_receive_skb(skb);
4505+
rcu_read_unlock();
45064506
local_irq_disable();
45074507
input_queue_head_incr(sd);
45084508
if (++work >= quota) {

0 commit comments

Comments
 (0)