aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2023-07-20 20:47:50 +0200
committerJakub Kicinski <kuba@kernel.org>2023-07-24 16:36:05 -0700
commitb8dc6d6ce93142ccd4c976003bb6c25d63aac2ce (patch)
tree647b7513486333643f7ce38ba7b4561a9ac952ef /include/net/tcp.h
parent004a04b97bbcbb630421e44aadfe675fe6b4c460 (diff)
downloadlinux-b8dc6d6ce93142ccd4c976003bb6c25d63aac2ce.tar.gz
mptcp: fix rcv buffer auto-tuning
The MPTCP code uses the assumption that the tcp_win_from_space() helper does not use any TCP-specific field, and thus works correctly operating on an MPTCP socket. The commit dfa2f0483360 ("tcp: get rid of sysctl_tcp_adv_win_scale") broke such assumption, and as a consequence most MPTCP connections stall on zero-window event due to auto-tuning changing the rcv buffer size quite randomly. Address the issue syncing again the MPTCP auto-tuning code with the TCP one. To achieve that, factor out the windows size logic in socket independent helpers, and reuse them in mptcp_rcv_space_adjust(). The MPTCP level scaling_ratio is selected as the minimum one from the all the subflows, as a worst-case estimate. Fixes: dfa2f0483360 ("tcp: get rid of sysctl_tcp_adv_win_scale") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Co-developed-by: Matthieu Baerts <matthieu.baerts@tessares.net> Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net> Reviewed-by: Eric Dumazet <edumazet@google.com> Acked-by: Soheil Hassas Yeganeh <soheil@google.com> Link: https://lore.kernel.org/r/20230720-upstream-net-next-20230720-mptcp-fix-rcv-buffer-auto-tuning-v1-1-175ef12b8380@tessares.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h20
1 files changed, 15 insertions, 5 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index d17cb8ab4c48c..6ebf54992ffee 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1430,22 +1430,32 @@ void tcp_select_initial_window(const struct sock *sk, int __space,
__u32 *window_clamp, int wscale_ok,
__u8 *rcv_wscale, __u32 init_rcv_wnd);
-static inline int tcp_win_from_space(const struct sock *sk, int space)
+static inline int __tcp_win_from_space(u8 scaling_ratio, int space)
{
- s64 scaled_space = (s64)space * tcp_sk(sk)->scaling_ratio;
+ s64 scaled_space = (s64)space * scaling_ratio;
return scaled_space >> TCP_RMEM_TO_WIN_SCALE;
}
-/* inverse of tcp_win_from_space() */
-static inline int tcp_space_from_win(const struct sock *sk, int win)
+static inline int tcp_win_from_space(const struct sock *sk, int space)
+{
+ return __tcp_win_from_space(tcp_sk(sk)->scaling_ratio, space);
+}
+
+/* inverse of __tcp_win_from_space() */
+static inline int __tcp_space_from_win(u8 scaling_ratio, int win)
{
u64 val = (u64)win << TCP_RMEM_TO_WIN_SCALE;
- do_div(val, tcp_sk(sk)->scaling_ratio);
+ do_div(val, scaling_ratio);
return val;
}
+static inline int tcp_space_from_win(const struct sock *sk, int win)
+{
+ return __tcp_space_from_win(tcp_sk(sk)->scaling_ratio, win);
+}
+
static inline void tcp_scaling_ratio_init(struct sock *sk)
{
/* Assume a conservative default of 1200 bytes of payload per 4K page.