net: annotate accesses to sk->sk_incoming_cpu
This socket field can be read and written by concurrent cpus. Use READ_ONCE() and WRITE_ONCE() annotations to document this, and avoid some compiler 'optimizations'. KCSAN reported : BUG: KCSAN: data-race in tcp_v4_rcv / tcp_v4_rcv write to 0xffff88812220763c of 4 bytes by interrupt on cpu 0: sk_incoming_cpu_update include/net/sock.h:953 [inline] tcp_v4_rcv+0x1b3c/0x1bb0 net/ipv4/tcp_ipv4.c:1934 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 napi_poll net/core/dev.c:6392 [inline] net_rx_action+0x3ae/0xa90 net/core/dev.c:6460 __do_softirq+0x115/0x33f kernel/softirq.c:292 do_softirq_own_stack+0x2a/0x40 arch/x86/entry/entry_64.S:1082 do_softirq.part.0+0x6b/0x80 kernel/softirq.c:337 do_softirq kernel/softirq.c:329 [inline] __local_bh_enable_ip+0x76/0x80 kernel/softirq.c:189 read to 0xffff88812220763c of 4 bytes by interrupt on cpu 1: sk_incoming_cpu_update include/net/sock.h:952 [inline] tcp_v4_rcv+0x181a/0x1bb0 net/ipv4/tcp_ipv4.c:1934 ip_protocol_deliver_rcu+0x4d/0x420 net/ipv4/ip_input.c:204 ip_local_deliver_finish+0x110/0x140 net/ipv4/ip_input.c:231 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_local_deliver+0x133/0x210 net/ipv4/ip_input.c:252 dst_input include/net/dst.h:442 [inline] ip_rcv_finish+0x121/0x160 net/ipv4/ip_input.c:413 NF_HOOK include/linux/netfilter.h:305 [inline] NF_HOOK include/linux/netfilter.h:299 [inline] ip_rcv+0x18f/0x1a0 net/ipv4/ip_input.c:523 __netif_receive_skb_one_core+0xa7/0xe0 net/core/dev.c:5010 __netif_receive_skb+0x37/0xf0 net/core/dev.c:5124 process_backlog+0x1d3/0x420 net/core/dev.c:5955 napi_poll net/core/dev.c:6392 [inline] net_rx_action+0x3ae/0xa90 net/core/dev.c:6460 __do_softirq+0x115/0x33f kernel/softirq.c:292 run_ksoftirqd+0x46/0x60 kernel/softirq.c:603 smpboot_thread_fn+0x37d/0x4a0 kernel/smpboot.c:165 Reported by Kernel Concurrency Sanitizer on: CPU: 1 PID: 16 Comm: ksoftirqd/1 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b7265a0df8
commit
7170a97774
|
@ -954,8 +954,8 @@ static inline void sk_incoming_cpu_update(struct sock *sk)
|
|||
{
|
||||
int cpu = raw_smp_processor_id();
|
||||
|
||||
if (unlikely(sk->sk_incoming_cpu != cpu))
|
||||
sk->sk_incoming_cpu = cpu;
|
||||
if (unlikely(READ_ONCE(sk->sk_incoming_cpu) != cpu))
|
||||
WRITE_ONCE(sk->sk_incoming_cpu, cpu);
|
||||
}
|
||||
|
||||
static inline void sock_rps_record_flow_hash(__u32 hash)
|
||||
|
|
|
@ -1127,7 +1127,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
|
|||
break;
|
||||
}
|
||||
case SO_INCOMING_CPU:
|
||||
sk->sk_incoming_cpu = val;
|
||||
WRITE_ONCE(sk->sk_incoming_cpu, val);
|
||||
break;
|
||||
|
||||
case SO_CNX_ADVICE:
|
||||
|
@ -1476,7 +1476,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
|||
break;
|
||||
|
||||
case SO_INCOMING_CPU:
|
||||
v.val = sk->sk_incoming_cpu;
|
||||
v.val = READ_ONCE(sk->sk_incoming_cpu);
|
||||
break;
|
||||
|
||||
case SO_MEMINFO:
|
||||
|
|
|
@ -240,7 +240,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
|
|||
return -1;
|
||||
|
||||
score = sk->sk_family == PF_INET ? 2 : 1;
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
|
||||
score++;
|
||||
}
|
||||
return score;
|
||||
|
|
|
@ -388,7 +388,7 @@ static int compute_score(struct sock *sk, struct net *net,
|
|||
return -1;
|
||||
score += 4;
|
||||
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
|
||||
score++;
|
||||
return score;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ static inline int compute_score(struct sock *sk, struct net *net,
|
|||
return -1;
|
||||
|
||||
score = 1;
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
|
||||
score++;
|
||||
}
|
||||
return score;
|
||||
|
|
|
@ -135,7 +135,7 @@ static int compute_score(struct sock *sk, struct net *net,
|
|||
return -1;
|
||||
score++;
|
||||
|
||||
if (sk->sk_incoming_cpu == raw_smp_processor_id())
|
||||
if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id())
|
||||
score++;
|
||||
|
||||
return score;
|
||||
|
|
Loading…
Reference in New Issue