mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 00:53:34 +02:00
Merge branch 'tcp-user_mss-and-tcp_maxseg-series'
Eric Dumazet says: ==================== tcp: user_mss and TCP_MAXSEG series Annotate data-races around tp->rx_opt.user_mss and make TCP_MAXSEG lockless. ==================== Link: https://patch.msgid.link/20250821141901.18839-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
718d6e8669
|
|
@ -951,6 +951,7 @@ static unsigned int chtls_select_mss(const struct chtls_sock *csk,
|
|||
struct tcp_sock *tp;
|
||||
unsigned int mss;
|
||||
struct sock *sk;
|
||||
u16 user_mss;
|
||||
|
||||
mss = ntohs(req->tcpopt.mss);
|
||||
sk = csk->sk;
|
||||
|
|
@ -969,8 +970,9 @@ static unsigned int chtls_select_mss(const struct chtls_sock *csk,
|
|||
tcpoptsz += round_up(TCPOLEN_TIMESTAMP, 4);
|
||||
|
||||
tp->advmss = dst_metric_advmss(dst);
|
||||
if (USER_MSS(tp) && tp->advmss > USER_MSS(tp))
|
||||
tp->advmss = USER_MSS(tp);
|
||||
user_mss = USER_MSS(tp);
|
||||
if (user_mss && tp->advmss > user_mss)
|
||||
tp->advmss = user_mss;
|
||||
if (tp->advmss > pmtu - iphdrsz)
|
||||
tp->advmss = pmtu - iphdrsz;
|
||||
if (mss && tp->advmss > mss)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct deferred_skb_cb {
|
|||
|
||||
#define SND_WSCALE(tp) ((tp)->rx_opt.snd_wscale)
|
||||
#define RCV_WSCALE(tp) ((tp)->rx_opt.rcv_wscale)
|
||||
#define USER_MSS(tp) ((tp)->rx_opt.user_mss)
|
||||
#define USER_MSS(tp) (READ_ONCE((tp)->rx_opt.user_mss))
|
||||
#define TS_RECENT_STAMP(tp) ((tp)->rx_opt.ts_recent_stamp)
|
||||
#define WSCALE_OK(tp) ((tp)->rx_opt.wscale_ok)
|
||||
#define TSTAMP_OK(tp) ((tp)->rx_opt.tstamp_ok)
|
||||
|
|
|
|||
|
|
@ -3760,7 +3760,7 @@ int tcp_sock_set_maxseg(struct sock *sk, int val)
|
|||
if (val && (val < TCP_MIN_MSS || val > MAX_TCP_WINDOW))
|
||||
return -EINVAL;
|
||||
|
||||
tcp_sk(sk)->rx_opt.user_mss = val;
|
||||
WRITE_ONCE(tcp_sk(sk)->rx_opt.user_mss, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3890,15 +3890,13 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
|
|||
WRITE_ONCE(inet_csk(sk)->icsk_delack_max, delack_max);
|
||||
return 0;
|
||||
}
|
||||
case TCP_MAXSEG:
|
||||
return tcp_sock_set_maxseg(sk, val);
|
||||
}
|
||||
|
||||
sockopt_lock_sock(sk);
|
||||
|
||||
switch (optname) {
|
||||
case TCP_MAXSEG:
|
||||
err = tcp_sock_set_maxseg(sk, val);
|
||||
break;
|
||||
|
||||
case TCP_NODELAY:
|
||||
__tcp_sock_set_nodelay(sk, val);
|
||||
break;
|
||||
|
|
@ -4383,6 +4381,7 @@ int do_tcp_getsockopt(struct sock *sk, int level,
|
|||
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct net *net = sock_net(sk);
|
||||
int user_mss;
|
||||
int val, len;
|
||||
|
||||
if (copy_from_sockptr(&len, optlen, sizeof(int)))
|
||||
|
|
@ -4396,9 +4395,10 @@ int do_tcp_getsockopt(struct sock *sk, int level,
|
|||
switch (optname) {
|
||||
case TCP_MAXSEG:
|
||||
val = tp->mss_cache;
|
||||
if (tp->rx_opt.user_mss &&
|
||||
user_mss = READ_ONCE(tp->rx_opt.user_mss);
|
||||
if (user_mss &&
|
||||
((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)))
|
||||
val = tp->rx_opt.user_mss;
|
||||
val = user_mss;
|
||||
if (tp->repair)
|
||||
val = tp->rx_opt.mss_clamp;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -6297,7 +6297,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
|
|||
u16 mss = tp->rx_opt.mss_clamp, try_exp = 0;
|
||||
bool syn_drop = false;
|
||||
|
||||
if (mss == tp->rx_opt.user_mss) {
|
||||
if (mss == READ_ONCE(tp->rx_opt.user_mss)) {
|
||||
struct tcp_options_received opt;
|
||||
|
||||
/* Get original SYNACK MSS value if user MSS sets mss_clamp */
|
||||
|
|
@ -7117,7 +7117,7 @@ u16 tcp_get_syncookie_mss(struct request_sock_ops *rsk_ops,
|
|||
return 0;
|
||||
}
|
||||
|
||||
mss = tcp_parse_mss_option(th, tp->rx_opt.user_mss);
|
||||
mss = tcp_parse_mss_option(th, READ_ONCE(tp->rx_opt.user_mss));
|
||||
if (!mss)
|
||||
mss = af_ops->mss_clamp;
|
||||
|
||||
|
|
@ -7131,7 +7131,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
|
|||
{
|
||||
struct tcp_fastopen_cookie foc = { .len = -1 };
|
||||
struct tcp_options_received tmp_opt;
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
struct net *net = sock_net(sk);
|
||||
struct sock *fastopen_sk = NULL;
|
||||
struct request_sock *req;
|
||||
|
|
@ -7182,7 +7182,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops,
|
|||
|
||||
tcp_clear_options(&tmp_opt);
|
||||
tmp_opt.mss_clamp = af_ops->mss_clamp;
|
||||
tmp_opt.user_mss = tp->rx_opt.user_mss;
|
||||
tmp_opt.user_mss = READ_ONCE(tp->rx_opt.user_mss);
|
||||
tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0,
|
||||
want_cookie ? NULL : &foc);
|
||||
|
||||
|
|
|
|||
|
|
@ -3890,6 +3890,7 @@ static void tcp_connect_init(struct sock *sk)
|
|||
const struct dst_entry *dst = __sk_dst_get(sk);
|
||||
struct tcp_sock *tp = tcp_sk(sk);
|
||||
__u8 rcv_wscale;
|
||||
u16 user_mss;
|
||||
u32 rcv_wnd;
|
||||
|
||||
/* We'll fix this up when we get a response from the other end.
|
||||
|
|
@ -3902,8 +3903,9 @@ static void tcp_connect_init(struct sock *sk)
|
|||
tcp_ao_connect_init(sk);
|
||||
|
||||
/* If user gave his TCP_MAXSEG, record it to clamp */
|
||||
if (tp->rx_opt.user_mss)
|
||||
tp->rx_opt.mss_clamp = tp->rx_opt.user_mss;
|
||||
user_mss = READ_ONCE(tp->rx_opt.user_mss);
|
||||
if (user_mss)
|
||||
tp->rx_opt.mss_clamp = user_mss;
|
||||
tp->max_window = 0;
|
||||
tcp_mtup_init(sk);
|
||||
tcp_sync_mss(sk, dst_mtu(dst));
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user