tcp: ensure tcp_sack_partialack does not inflate cwnd after RTO

The implicit assumption of snd_nxt always being larger than
snd_recover is not true after RTO. In that case, cwnd
would get inflated to ssthresh, which may be much larger
than the current pipe (data in flight).

Reviewed By:           tuexen, #transport
Sponsored by:          NetApp, Inc.
Differential Revision: https://reviews.freebsd.org/D43653
This commit is contained in:
Richard Scheffenegger 2024-02-08 19:56:27 +01:00
parent cf67576852
commit 23c4f23247

View file

@ -953,8 +953,17 @@ tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th, u_int *maxsegp)
/* Send one or 2 segments based on how much new data was acked. */
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 * maxseg);
if (V_tcp_do_newsack) {
tp->snd_cwnd = imax(tp->snd_nxt - th->th_ack +
tp->sackhint.sack_bytes_rexmit -
tp->sackhint.sacked_bytes -
tp->sackhint.lost_bytes, maxseg) +
num_segs * maxseg;
} else {
tp->snd_cwnd = (tp->sackhint.sack_bytes_rexmit +
imax(0, 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;