forked from mirrors/linux
		
	net: annotate sk->sk_rcvlowat lockless reads
sock_rcvlowat() or int_sk_rcvlowat() might be called without the socket lock for example from tcp_poll(). Use READ_ONCE() to document the fact that other cpus might change sk->sk_rcvlowat under us and avoid KCSAN splats. Use WRITE_ONCE() on write sides too. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
This commit is contained in:
		
							parent
							
								
									8265792bf8
								
							
						
					
					
						commit
						eac66402d1
					
				
					 5 changed files with 7 additions and 5 deletions
				
			
		|  | @ -2271,7 +2271,9 @@ static inline long sock_sndtimeo(const struct sock *sk, bool noblock) | |||
| 
 | ||||
| static inline int sock_rcvlowat(const struct sock *sk, int waitall, int len) | ||||
| { | ||||
| 	return (waitall ? len : min_t(int, sk->sk_rcvlowat, len)) ? : 1; | ||||
| 	int v = waitall ? len : min_t(int, READ_ONCE(sk->sk_rcvlowat), len); | ||||
| 
 | ||||
| 	return v ?: 1; | ||||
| } | ||||
| 
 | ||||
| /* Alas, with timeout socket operations are not restartable.
 | ||||
|  |  | |||
|  | @ -4274,7 +4274,7 @@ BPF_CALL_5(bpf_setsockopt, struct bpf_sock_ops_kern *, bpf_sock, | |||
| 		case SO_RCVLOWAT: | ||||
| 			if (val < 0) | ||||
| 				val = INT_MAX; | ||||
| 			sk->sk_rcvlowat = val ? : 1; | ||||
| 			WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); | ||||
| 			break; | ||||
| 		case SO_MARK: | ||||
| 			if (sk->sk_mark != val) { | ||||
|  |  | |||
|  | @ -974,7 +974,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, | |||
| 		if (sock->ops->set_rcvlowat) | ||||
| 			ret = sock->ops->set_rcvlowat(sk, val); | ||||
| 		else | ||||
| 			sk->sk_rcvlowat = val ? : 1; | ||||
| 			WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); | ||||
| 		break; | ||||
| 
 | ||||
| 	case SO_RCVTIMEO_OLD: | ||||
|  |  | |||
|  | @ -1699,7 +1699,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val) | |||
| 	else | ||||
| 		cap = sock_net(sk)->ipv4.sysctl_tcp_rmem[2] >> 1; | ||||
| 	val = min(val, cap); | ||||
| 	sk->sk_rcvlowat = val ? : 1; | ||||
| 	WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); | ||||
| 
 | ||||
| 	/* Check if we need to signal EPOLLIN right now */ | ||||
| 	tcp_data_ready(sk); | ||||
|  |  | |||
|  | @ -554,7 +554,7 @@ META_COLLECTOR(int_sk_rcvlowat) | |||
| 		*err = -1; | ||||
| 		return; | ||||
| 	} | ||||
| 	dst->value = sk->sk_rcvlowat; | ||||
| 	dst->value = READ_ONCE(sk->sk_rcvlowat); | ||||
| } | ||||
| 
 | ||||
| META_COLLECTOR(int_sk_rcvtimeo) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eric Dumazet
						Eric Dumazet