Stop sending tiny new data segments during SACK recovery

Consider the currently in-use TCP options when
calculating the amount of new data to be injected during
SACK loss recovery. That addresses the effect that very small
(new) segments could be injected on partial ACKs while
still performing a SACK loss recovery.

Reported by:	Liang Tian
Reviewed by:	tuexen, chengc_netapp.com
MFC after:	2 weeks
Sponsored by:	NetApp, Inc.
Differential Revision:	https://reviews.freebsd.org/D26446
This commit is contained in:
Richard Scheffenegger 2020-10-09 12:44:56 +00:00
parent 868aabb470
commit 4b72ae16ed
2 changed files with 4 additions and 4 deletions

View File

@ -336,7 +336,7 @@ tcp_output(struct tcpcb *tp)
sendalot = 1;
TCPSTAT_INC(tcps_sack_rexmits);
TCPSTAT_ADD(tcps_sack_rexmit_bytes,
min(len, tp->t_maxseg));
min(len, tcp_maxseg(tp)));
}
}
after_sack_rexmit:
@ -858,7 +858,6 @@ tcp_output(struct tcpcb *tp)
if (flags & TH_SYN)
to.to_flags |= TOF_SACKPERM;
else if (TCPS_HAVEESTABLISHED(tp->t_state) &&
(tp->t_flags & TF_SACK_PERMIT) &&
tp->rcv_numsacks > 0) {
to.to_flags |= TOF_SACK;
to.to_nsacks = tp->rcv_numsacks;

View File

@ -787,15 +787,16 @@ void
tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th)
{
int num_segs = 1;
u_int maxseg = tcp_maxseg(tp);
INP_WLOCK_ASSERT(tp->t_inpcb);
tcp_timer_activate(tp, TT_REXMT, 0);
tp->t_rtttime = 0;
/* Send one or 2 segments based on how much new data was acked. */
if ((BYTES_THIS_ACK(tp, th) / tp->t_maxseg) >= 2)
if ((BYTES_THIS_ACK(tp, th) / maxseg) >= 2)
num_segs = 2;
tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit +
(tp->snd_nxt - tp->snd_recover) + num_segs * tp->t_maxseg);
(tp->snd_nxt - tp->snd_recover) + num_segs * maxseg);
if (tp->snd_cwnd > tp->snd_ssthresh)
tp->snd_cwnd = tp->snd_ssthresh;
tp->t_flags |= TF_ACKNOW;