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) | 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.
 | /* 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: | 		case SO_RCVLOWAT: | ||||||
| 			if (val < 0) | 			if (val < 0) | ||||||
| 				val = INT_MAX; | 				val = INT_MAX; | ||||||
| 			sk->sk_rcvlowat = val ? : 1; | 			WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); | ||||||
| 			break; | 			break; | ||||||
| 		case SO_MARK: | 		case SO_MARK: | ||||||
| 			if (sk->sk_mark != val) { | 			if (sk->sk_mark != val) { | ||||||
|  |  | ||||||
|  | @ -974,7 +974,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, | ||||||
| 		if (sock->ops->set_rcvlowat) | 		if (sock->ops->set_rcvlowat) | ||||||
| 			ret = sock->ops->set_rcvlowat(sk, val); | 			ret = sock->ops->set_rcvlowat(sk, val); | ||||||
| 		else | 		else | ||||||
| 			sk->sk_rcvlowat = val ? : 1; | 			WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
| 	case SO_RCVTIMEO_OLD: | 	case SO_RCVTIMEO_OLD: | ||||||
|  |  | ||||||
|  | @ -1699,7 +1699,7 @@ int tcp_set_rcvlowat(struct sock *sk, int val) | ||||||
| 	else | 	else | ||||||
| 		cap = sock_net(sk)->ipv4.sysctl_tcp_rmem[2] >> 1; | 		cap = sock_net(sk)->ipv4.sysctl_tcp_rmem[2] >> 1; | ||||||
| 	val = min(val, cap); | 	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 */ | 	/* Check if we need to signal EPOLLIN right now */ | ||||||
| 	tcp_data_ready(sk); | 	tcp_data_ready(sk); | ||||||
|  |  | ||||||
|  | @ -554,7 +554,7 @@ META_COLLECTOR(int_sk_rcvlowat) | ||||||
| 		*err = -1; | 		*err = -1; | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	dst->value = sk->sk_rcvlowat; | 	dst->value = READ_ONCE(sk->sk_rcvlowat); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| META_COLLECTOR(int_sk_rcvtimeo) | META_COLLECTOR(int_sk_rcvtimeo) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Eric Dumazet
						Eric Dumazet