net: tcp: add sysctl_tcp_wnd_shrink

Add the 'sysctl_tcp_wnd_shrink' to control the enable/disable of TCP
window shrink. By default, it is disabled.

Signed-off-by: Menglong Dong <imagedong@tencent.com>
This commit is contained in:
Menglong Dong 2023-05-09 19:52:58 +08:00 committed by Jianping Liu
parent e1bf1991a5
commit ed011e007b
5 changed files with 32 additions and 8 deletions

View File

@ -255,6 +255,7 @@ extern int sysctl_tcp_synack_rto_interval;
extern int sysctl_tcp_rto_min;
extern int sysctl_tcp_rto_max;
extern int sysctl_tcp_proc_sched;
extern int sysctl_tcp_wnd_shrink;
#define TCP_RACK_LOSS_DETECTION 0x1 /* Use RACK to detect losses */
#define TCP_RACK_STATIC_REO_WND 0x2 /* Use static RACK reo wnd */
@ -1853,6 +1854,9 @@ static inline bool tcp_probe0_needed(const struct sock *sk)
if (__tcp_probe0_needed(sk))
return true;
if (!sysctl_tcp_wnd_shrink)
return false;
/* for the window shrink case */
return tcp_rtx_overflow(sk);
}

View File

@ -713,6 +713,15 @@ static struct ctl_table ipv4_table[] = {
.proc_handler = proc_dointvec_minmax,
.extra1 = &four
},
{
.procname = "tcp_wnd_shrink",
.data = &sysctl_tcp_wnd_shrink,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE
},
{ }
};

View File

@ -288,6 +288,11 @@ EXPORT_SYMBOL(sysctl_tcp_mem);
atomic_long_t tcp_memory_allocated; /* Current allocated memory. */
EXPORT_SYMBOL(tcp_memory_allocated);
#ifdef CONFIG_TCP_WND_SHRINK
int sysctl_tcp_wnd_shrink;
EXPORT_SYMBOL(sysctl_tcp_wnd_shrink);
#endif
#if IS_ENABLED(CONFIG_SMC)
DEFINE_STATIC_KEY_FALSE(tcp_have_smc);
EXPORT_SYMBOL(tcp_have_smc);

View File

@ -3035,7 +3035,8 @@ static void tcp_set_xmit_timer(struct sock *sk)
* not needed to schedule the RTO. The normal probe0 can't reach
* here, so it must be window-shrink probe0 case here.
*/
if (icsk->icsk_pending == ICSK_TIME_PROBE0)
if (sysctl_tcp_wnd_shrink &&
icsk->icsk_pending == ICSK_TIME_PROBE0)
return;
#endif
@ -3327,6 +3328,9 @@ static void tcp_ack_probe_shrink(struct sock *sk)
struct inet_connection_sock *icsk = inet_csk(sk);
unsigned long when;
if (!sysctl_tcp_wnd_shrink)
return;
if (tcp_rtx_overflow(sk)) {
when = tcp_probe0_when(sk, TCP_RTO_MAX);
@ -4871,6 +4875,14 @@ queue_and_out:
sk_forced_mem_schedule(sk, skb->truesize);
else if (tcp_try_rmem_schedule(sk, skb, skb->truesize)) {
#ifdef CONFIG_TCP_WND_SHRINK
if (sysctl_tcp_wnd_shrink)
goto do_wnd_shrink;
#endif
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRCVQDROP);
sk->sk_data_ready(sk);
goto drop;
#ifdef CONFIG_TCP_WND_SHRINK
do_wnd_shrink:
if (sock_flag(sk, SOCK_NO_MEM)) {
NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPRCVQDROP);
@ -4879,10 +4891,6 @@ queue_and_out:
}
sk_forced_mem_schedule(sk, skb->truesize);
sock_set_flag(sk, SOCK_NO_MEM);
#else
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPRCVQDROP);
sk->sk_data_ready(sk);
goto drop;
#endif
}
@ -4924,9 +4932,7 @@ out_of_window:
NET_INC_DROPSTATS(sock_net(sk), LINUX_MIB_TCPOOWDROP);
tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
inet_csk_schedule_ack(sk);
#ifndef CONFIG_TCP_WND_SHRINK
drop:
#endif
tcp_drop(sk, skb);
return;
}

View File

@ -302,7 +302,7 @@ static u16 tcp_select_window(struct sock *sk)
}
#ifdef CONFIG_TCP_WND_SHRINK
if (sock_flag(sk, SOCK_NO_MEM)) {
if (sysctl_tcp_wnd_shrink && sock_flag(sk, SOCK_NO_MEM)) {
if (sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 2))
sock_reset_flag(sk, SOCK_NO_MEM);
else