diff options
Diffstat (limited to 'net/ipv4/tcp.c')
| -rw-r--r-- | net/ipv4/tcp.c | 57 | 
1 files changed, 30 insertions, 27 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index e03e08745308..8ed52e1e3c99 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -3291,7 +3291,7 @@ int tcp_sock_set_syncnt(struct sock *sk, int val)  		return -EINVAL;  	lock_sock(sk); -	inet_csk(sk)->icsk_syn_retries = val; +	WRITE_ONCE(inet_csk(sk)->icsk_syn_retries, val);  	release_sock(sk);  	return 0;  } @@ -3300,7 +3300,7 @@ EXPORT_SYMBOL(tcp_sock_set_syncnt);  void tcp_sock_set_user_timeout(struct sock *sk, u32 val)  {  	lock_sock(sk); -	inet_csk(sk)->icsk_user_timeout = val; +	WRITE_ONCE(inet_csk(sk)->icsk_user_timeout, val);  	release_sock(sk);  }  EXPORT_SYMBOL(tcp_sock_set_user_timeout); @@ -3312,7 +3312,8 @@ int tcp_sock_set_keepidle_locked(struct sock *sk, int val)  	if (val < 1 || val > MAX_TCP_KEEPIDLE)  		return -EINVAL; -	tp->keepalive_time = val * HZ; +	/* Paired with WRITE_ONCE() in keepalive_time_when() */ +	WRITE_ONCE(tp->keepalive_time, val * HZ);  	if (sock_flag(sk, SOCK_KEEPOPEN) &&  	    !((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) {  		u32 elapsed = keepalive_time_elapsed(tp); @@ -3344,7 +3345,7 @@ int tcp_sock_set_keepintvl(struct sock *sk, int val)  		return -EINVAL;  	lock_sock(sk); -	tcp_sk(sk)->keepalive_intvl = val * HZ; +	WRITE_ONCE(tcp_sk(sk)->keepalive_intvl, val * HZ);  	release_sock(sk);  	return 0;  } @@ -3356,7 +3357,8 @@ int tcp_sock_set_keepcnt(struct sock *sk, int val)  		return -EINVAL;  	lock_sock(sk); -	tcp_sk(sk)->keepalive_probes = val; +	/* Paired with READ_ONCE() in keepalive_probes() */ +	WRITE_ONCE(tcp_sk(sk)->keepalive_probes, val);  	release_sock(sk);  	return 0;  } @@ -3558,19 +3560,19 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,  		if (val < 1 || val > MAX_TCP_KEEPINTVL)  			err = -EINVAL;  		else -			tp->keepalive_intvl = val * HZ; +			WRITE_ONCE(tp->keepalive_intvl, val * HZ);  		break;  	case TCP_KEEPCNT:  		if (val < 1 || val > MAX_TCP_KEEPCNT)  			err = -EINVAL;  		else -			tp->keepalive_probes = val; +			WRITE_ONCE(tp->keepalive_probes, val);  		break;  	case TCP_SYNCNT:  		if (val < 1 || val > MAX_TCP_SYNCNT)  			err = -EINVAL;  		else -			icsk->icsk_syn_retries = val; +			WRITE_ONCE(icsk->icsk_syn_retries, val);  		break;  	case TCP_SAVE_SYN: @@ -3583,18 +3585,18 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,  	case TCP_LINGER2:  		if (val < 0) -			tp->linger2 = -1; +			WRITE_ONCE(tp->linger2, -1);  		else if (val > TCP_FIN_TIMEOUT_MAX / HZ) -			tp->linger2 = TCP_FIN_TIMEOUT_MAX; +			WRITE_ONCE(tp->linger2, TCP_FIN_TIMEOUT_MAX);  		else -			tp->linger2 = val * HZ; +			WRITE_ONCE(tp->linger2, val * HZ);  		break;  	case TCP_DEFER_ACCEPT:  		/* Translate value in seconds to number of retransmits */ -		icsk->icsk_accept_queue.rskq_defer_accept = -			secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, -					TCP_RTO_MAX / HZ); +		WRITE_ONCE(icsk->icsk_accept_queue.rskq_defer_accept, +			   secs_to_retrans(val, TCP_TIMEOUT_INIT / HZ, +					   TCP_RTO_MAX / HZ));  		break;  	case TCP_WINDOW_CLAMP: @@ -3618,7 +3620,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,  		if (val < 0)  			err = -EINVAL;  		else -			icsk->icsk_user_timeout = val; +			WRITE_ONCE(icsk->icsk_user_timeout, val);  		break;  	case TCP_FASTOPEN: @@ -3656,13 +3658,13 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,  		if (!tp->repair)  			err = -EPERM;  		else -			tp->tsoffset = val - tcp_time_stamp_raw(); +			WRITE_ONCE(tp->tsoffset, val - tcp_time_stamp_raw());  		break;  	case TCP_REPAIR_WINDOW:  		err = tcp_repair_set_window(tp, optval, optlen);  		break;  	case TCP_NOTSENT_LOWAT: -		tp->notsent_lowat = val; +		WRITE_ONCE(tp->notsent_lowat, val);  		sk->sk_write_space(sk);  		break;  	case TCP_INQ: @@ -3674,7 +3676,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,  	case TCP_TX_DELAY:  		if (val)  			tcp_enable_tx_delay(); -		tp->tcp_tx_delay = val; +		WRITE_ONCE(tp->tcp_tx_delay, val);  		break;  	default:  		err = -ENOPROTOOPT; @@ -3991,17 +3993,18 @@ int do_tcp_getsockopt(struct sock *sk, int level,  		val = keepalive_probes(tp);  		break;  	case TCP_SYNCNT: -		val = icsk->icsk_syn_retries ? : +		val = READ_ONCE(icsk->icsk_syn_retries) ? :  			READ_ONCE(net->ipv4.sysctl_tcp_syn_retries);  		break;  	case TCP_LINGER2: -		val = tp->linger2; +		val = READ_ONCE(tp->linger2);  		if (val >= 0)  			val = (val ? : READ_ONCE(net->ipv4.sysctl_tcp_fin_timeout)) / HZ;  		break;  	case TCP_DEFER_ACCEPT: -		val = retrans_to_secs(icsk->icsk_accept_queue.rskq_defer_accept, -				      TCP_TIMEOUT_INIT / HZ, TCP_RTO_MAX / HZ); +		val = READ_ONCE(icsk->icsk_accept_queue.rskq_defer_accept); +		val = retrans_to_secs(val, TCP_TIMEOUT_INIT / HZ, +				      TCP_RTO_MAX / HZ);  		break;  	case TCP_WINDOW_CLAMP:  		val = tp->window_clamp; @@ -4138,11 +4141,11 @@ int do_tcp_getsockopt(struct sock *sk, int level,  		break;  	case TCP_USER_TIMEOUT: -		val = icsk->icsk_user_timeout; +		val = READ_ONCE(icsk->icsk_user_timeout);  		break;  	case TCP_FASTOPEN: -		val = icsk->icsk_accept_queue.fastopenq.max_qlen; +		val = READ_ONCE(icsk->icsk_accept_queue.fastopenq.max_qlen);  		break;  	case TCP_FASTOPEN_CONNECT: @@ -4154,14 +4157,14 @@ int do_tcp_getsockopt(struct sock *sk, int level,  		break;  	case TCP_TX_DELAY: -		val = tp->tcp_tx_delay; +		val = READ_ONCE(tp->tcp_tx_delay);  		break;  	case TCP_TIMESTAMP: -		val = tcp_time_stamp_raw() + tp->tsoffset; +		val = tcp_time_stamp_raw() + READ_ONCE(tp->tsoffset);  		break;  	case TCP_NOTSENT_LOWAT: -		val = tp->notsent_lowat; +		val = READ_ONCE(tp->notsent_lowat);  		break;  	case TCP_INQ:  		val = tp->recvmsg_inq;  |