Wed Sep 2 15:08:46 2020 UTC ()
Fix fast path for uni directional transfers
pure ACK case:

drag snd_wl2 along so only newer
ACKs can update the window size.
also avoids the state where snd_wl2
is eventually larger than th_ack and thus
blocking the window update mechanism and
the connection gets stuck for a loooong
time in the zero sized send window state.

see PR/kern 55567

ok thorpej@, also found in FreeBSD


(kardel)
diff -r1.418 -r1.419 src/sys/netinet/tcp_input.c

cvs diff -r1.418 -r1.419 src/sys/netinet/tcp_input.c (expand / switch to unified diff)

--- src/sys/netinet/tcp_input.c 2020/07/06 18:49:12 1.418
+++ src/sys/netinet/tcp_input.c 2020/09/02 15:08:46 1.419
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tcp_input.c,v 1.418 2020/07/06 18:49:12 christos Exp $ */ 1/* $NetBSD: tcp_input.c,v 1.419 2020/09/02 15:08:46 kardel Exp $ */
2 2
3/* 3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -138,27 +138,27 @@ @@ -138,27 +138,27 @@
138 */ 138 */
139 139
140/* 140/*
141 * TODO list for SYN cache stuff: 141 * TODO list for SYN cache stuff:
142 * 142 *
143 * Find room for a "state" field, which is needed to keep a 143 * Find room for a "state" field, which is needed to keep a
144 * compressed state for TIME_WAIT TCBs. It's been noted already 144 * compressed state for TIME_WAIT TCBs. It's been noted already
145 * that this is fairly important for very high-volume web and 145 * that this is fairly important for very high-volume web and
146 * mail servers, which use a large number of short-lived 146 * mail servers, which use a large number of short-lived
147 * connections. 147 * connections.
148 */ 148 */
149 149
150#include <sys/cdefs.h> 150#include <sys/cdefs.h>
151__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.418 2020/07/06 18:49:12 christos Exp $"); 151__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.419 2020/09/02 15:08:46 kardel Exp $");
152 152
153#ifdef _KERNEL_OPT 153#ifdef _KERNEL_OPT
154#include "opt_inet.h" 154#include "opt_inet.h"
155#include "opt_ipsec.h" 155#include "opt_ipsec.h"
156#include "opt_inet_csum.h" 156#include "opt_inet_csum.h"
157#include "opt_tcp_debug.h" 157#include "opt_tcp_debug.h"
158#endif 158#endif
159 159
160#include <sys/param.h> 160#include <sys/param.h>
161#include <sys/systm.h> 161#include <sys/systm.h>
162#include <sys/malloc.h> 162#include <sys/malloc.h>
163#include <sys/mbuf.h> 163#include <sys/mbuf.h>
164#include <sys/protosw.h> 164#include <sys/protosw.h>
@@ -1887,26 +1887,39 @@ after_listen: @@ -1887,26 +1887,39 @@ after_listen:
1887 nd6_hint(tp); 1887 nd6_hint(tp);
1888 1888
1889 if (acked > (tp->t_lastoff - tp->t_inoff)) 1889 if (acked > (tp->t_lastoff - tp->t_inoff))
1890 tp->t_lastm = NULL; 1890 tp->t_lastm = NULL;
1891 sbdrop(&so->so_snd, acked); 1891 sbdrop(&so->so_snd, acked);
1892 tp->t_lastoff -= acked; 1892 tp->t_lastoff -= acked;
1893 1893
1894 icmp_check(tp, th, acked); 1894 icmp_check(tp, th, acked);
1895 1895
1896 tp->snd_una = th->th_ack; 1896 tp->snd_una = th->th_ack;
1897 tp->snd_fack = tp->snd_una; 1897 tp->snd_fack = tp->snd_una;
1898 if (SEQ_LT(tp->snd_high, tp->snd_una)) 1898 if (SEQ_LT(tp->snd_high, tp->snd_una))
1899 tp->snd_high = tp->snd_una; 1899 tp->snd_high = tp->snd_una;
 1900 /*
 1901 * drag snd_wl2 along so only newer
 1902 * ACKs can update the window size.
 1903 * also avoids the state where snd_wl2
 1904 * is eventually larger than th_ack and thus
 1905 * blocking the window update mechanism and
 1906 * the connection gets stuck for a loooong
 1907 * time in the zero sized send window state.
 1908 *
 1909 * see PR/kern 55567
 1910 */
 1911 tp->snd_wl2 = tp->snd_una;
 1912
1900 m_freem(m); 1913 m_freem(m);
1901 1914
1902 /* 1915 /*
1903 * If all outstanding data are acked, stop 1916 * If all outstanding data are acked, stop
1904 * retransmit timer, otherwise restart timer 1917 * retransmit timer, otherwise restart timer
1905 * using current (possibly backed-off) value. 1918 * using current (possibly backed-off) value.
1906 * If process is waiting for space, 1919 * If process is waiting for space,
1907 * wakeup/selnotify/signal. If data 1920 * wakeup/selnotify/signal. If data
1908 * are ready to send, let tcp_output 1921 * are ready to send, let tcp_output
1909 * decide between more output or persist. 1922 * decide between more output or persist.
1910 */ 1923 */
1911 if (tp->snd_una == tp->snd_max) 1924 if (tp->snd_una == tp->snd_max)
1912 TCP_TIMER_DISARM(tp, TCPT_REXMT); 1925 TCP_TIMER_DISARM(tp, TCPT_REXMT);