git: 3eeb22cb8194 - main - tcp: clean scoreboard when releasing the socket buffer
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 10 Feb 2024 09:33:59 UTC
The branch main has been updated by rscheff:
URL: https://cgit.FreeBSD.org/src/commit/?id=3eeb22cb819409b49296ecb0acbd453671168313
commit 3eeb22cb819409b49296ecb0acbd453671168313
Author: Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2024-02-10 09:16:08 +0000
Commit: Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2024-02-10 09:20:00 +0000
tcp: clean scoreboard when releasing the socket buffer
The SACK scoreboard is conceptually an extention of the socket
buffer. Remove it when the socket buffer goes away with
soisdisconnected(). Verify that this is also the expected
state in tcp_discardcb().
PR: 276761
Reviewed by: glebius, tuexen, #transport
Sponsored by: NetApp, Inc.
Differential Revision: https://reviews.freebsd.org/D43805
---
sys/netinet/tcp_input.c | 1 +
sys/netinet/tcp_subr.c | 5 ++---
sys/netinet/tcp_timewait.c | 1 +
sys/netinet/tcp_usrreq.c | 1 +
4 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index afcda60137ec..b3201750c1e6 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -3022,6 +3022,7 @@ process_ACK:
* we'll hang forever.
*/
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
+ tcp_free_sackholes(tp);
soisdisconnected(so);
tcp_timer_activate(tp, TT_2MSL,
(tcp_fast_finwait2_recycle ?
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index be38280aef0a..6043a3d458e5 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -2383,6 +2383,7 @@ tcp_discardcb(struct tcpcb *tp)
#endif
INP_WLOCK_ASSERT(inp);
+ MPASS(TAILQ_EMPTY(&tp->snd_holes));
tcp_timer_stop(tp);
@@ -2394,9 +2395,6 @@ tcp_discardcb(struct tcpcb *tp)
if (tp->t_flags & TF_TOE)
tcp_offload_detach(tp);
#endif
-
- tcp_free_sackholes(tp);
-
#ifdef TCPPCAP
/* Free the TCP PCAP queues. */
tcp_pcap_drain(&(tp->t_inpkts));
@@ -2531,6 +2529,7 @@ tcp_close(struct tcpcb *tp)
if (tp->t_state != TCPS_CLOSED)
tcp_state_change(tp, TCPS_CLOSED);
KASSERT(inp->inp_socket != NULL, ("tcp_close: inp_socket NULL"));
+ tcp_free_sackholes(tp);
soisdisconnected(so);
if (inp->inp_flags & INP_SOCKREF) {
inp->inp_flags &= ~INP_SOCKREF;
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 328f8fe84a8c..266556274e18 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -119,6 +119,7 @@ tcp_twstart(struct tcpcb *tp)
"(inp->inp_flags & INP_DROPPED) != 0"));
tcp_state_change(tp, TCPS_TIME_WAIT);
+ tcp_free_sackholes(tp);
soisdisconnected(inp->inp_socket);
if (tp->t_flags & TF_ACKNOW)
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index ccd6a6149dae..a283d308801f 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -2777,6 +2777,7 @@ tcp_usrclosed(struct tcpcb *tp)
if (tp->t_acktime == 0)
tp->t_acktime = ticks;
if (tp->t_state >= TCPS_FIN_WAIT_2) {
+ tcp_free_sackholes(tp);
soisdisconnected(tptosocket(tp));
/* Prevent the connection hanging in FIN_WAIT_2 forever. */
if (tp->t_state == TCPS_FIN_WAIT_2) {