diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -3022,6 +3022,7 @@ * 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 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2383,8 +2383,8 @@ #endif INP_WLOCK_ASSERT(inp); - - tcp_timer_stop(tp); + MPASS(!callout_active(&tp->t_callout)); + MPASS(TAILQ_EMPTY(&tp->snd_holes)); /* free the reassembly queue, if any */ tcp_reass_flush(tp); @@ -2394,9 +2394,6 @@ 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)); @@ -2524,6 +2521,7 @@ tcp_fastopen_decrement_counter(tp->t_tfo_pending); tp->t_tfo_pending = NULL; } + tcp_timer_stop(tp); if (tp->t_fb->tfb_tcp_timer_stop_all != NULL) tp->t_fb->tfb_tcp_timer_stop_all(tp); in_pcbdrop(inp); @@ -2531,6 +2529,7 @@ 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_timer.c b/sys/netinet/tcp_timer.c --- a/sys/netinet/tcp_timer.c +++ b/sys/netinet/tcp_timer.c @@ -907,6 +907,7 @@ #endif INP_WLOCK_ASSERT(inp); + MPASS(tp->t_state > TCPS_CLOSED); if (delta > 0) { what = TT_STARTING; diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -119,6 +119,7 @@ "(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 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -2777,6 +2777,7 @@ 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) {