mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
- Retransmit just one segment on initiation of SACK recovery.
Remove the SACK "initburst" sysctl. - Fix bugs in SACK dupack and partialack handling that can cause large bursts while in SACK recovery. Submitted by: Mohan Srinivasan
This commit is contained in:
parent
a8127ebb5d
commit
8db456bf17
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=141928
@ -159,12 +159,6 @@ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
|
||||
&tcp_reass_overflows, 0,
|
||||
"Global number of TCP Segment Reassembly Queue Overflows");
|
||||
|
||||
static int tcp_sack_recovery_initburst = 3;
|
||||
SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO,
|
||||
initburst, CTLFLAG_RW,
|
||||
&tcp_sack_recovery_initburst, 0,
|
||||
"Initial Number of Rexmits when sack recovery is set up");
|
||||
|
||||
struct inpcbhead tcb;
|
||||
#define tcb6 tcb /* for KAME src sync over BSD*'s */
|
||||
struct inpcbinfo tcbinfo;
|
||||
@ -1870,14 +1864,10 @@ tcp_input(m, off0)
|
||||
if (tp->sack_enable) {
|
||||
tcpstat.tcps_sack_recovery_episode++;
|
||||
tp->sack_newdata = tp->snd_nxt;
|
||||
tp->snd_cwnd =
|
||||
tp->t_maxseg * tcp_sack_recovery_initburst;
|
||||
tp->snd_cwnd = tp->t_maxseg;
|
||||
(void) tcp_output(tp);
|
||||
tp->snd_cwnd +=
|
||||
tp->snd_ssthresh;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
tp->snd_nxt = th->th_ack;
|
||||
tp->snd_cwnd = tp->t_maxseg;
|
||||
(void) tcp_output(tp);
|
||||
|
@ -159,12 +159,6 @@ SYSCTL_INT(_net_inet_tcp_reass, OID_AUTO, overflows, CTLFLAG_RD,
|
||||
&tcp_reass_overflows, 0,
|
||||
"Global number of TCP Segment Reassembly Queue Overflows");
|
||||
|
||||
static int tcp_sack_recovery_initburst = 3;
|
||||
SYSCTL_INT(_net_inet_tcp_sack, OID_AUTO,
|
||||
initburst, CTLFLAG_RW,
|
||||
&tcp_sack_recovery_initburst, 0,
|
||||
"Initial Number of Rexmits when sack recovery is set up");
|
||||
|
||||
struct inpcbhead tcb;
|
||||
#define tcb6 tcb /* for KAME src sync over BSD*'s */
|
||||
struct inpcbinfo tcbinfo;
|
||||
@ -1870,14 +1864,10 @@ tcp_input(m, off0)
|
||||
if (tp->sack_enable) {
|
||||
tcpstat.tcps_sack_recovery_episode++;
|
||||
tp->sack_newdata = tp->snd_nxt;
|
||||
tp->snd_cwnd =
|
||||
tp->t_maxseg * tcp_sack_recovery_initburst;
|
||||
tp->snd_cwnd = tp->t_maxseg;
|
||||
(void) tcp_output(tp);
|
||||
tp->snd_cwnd +=
|
||||
tp->snd_ssthresh;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
tp->snd_nxt = th->th_ack;
|
||||
tp->snd_cwnd = tp->t_maxseg;
|
||||
(void) tcp_output(tp);
|
||||
|
@ -481,9 +481,14 @@ tcp_free_sackholes(struct tcpcb *tp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks for partial ack. If partial ack arrives, turn off retransmission
|
||||
* timer, deflate the window, do not clear tp->t_dupacks, and return 1.
|
||||
* If the ack advances at least to tp->snd_recover, return 0.
|
||||
* Partial ack handling within a sack recovery episode.
|
||||
* Keeping this very simple for now. When a partial ack
|
||||
* is received, force snd_cwnd to a value that will allow
|
||||
* the sender to transmit no more than 2 segments.
|
||||
* If necessary, a better scheme can be adopted at a
|
||||
* later point, but for now, the goal is to prevent the
|
||||
* sender from bursting a large amount of data in the midst
|
||||
* of sack recovery.
|
||||
*/
|
||||
void
|
||||
tcp_sack_partialack(tp, th)
|
||||
@ -491,28 +496,19 @@ tcp_sack_partialack(tp, th)
|
||||
struct tcphdr *th;
|
||||
{
|
||||
INP_LOCK_ASSERT(tp->t_inpcb);
|
||||
u_long ocwnd = tp->snd_cwnd;
|
||||
int sack_bytes_rexmt = 0;
|
||||
int num_segs = 1;
|
||||
int sack_bytes_rxmt = 0;
|
||||
|
||||
callout_stop(tp->tt_rexmt);
|
||||
tp->t_rtttime = 0;
|
||||
/*
|
||||
* Set cwnd so we can send one more segment (either rexmit based on
|
||||
* scoreboard or new segment). Set cwnd to the amount of data
|
||||
* rexmitted from scoreboard plus the amount of new data transmitted
|
||||
* in this sack recovery episode plus one segment.
|
||||
*/
|
||||
(void)tcp_sack_output(tp, &sack_bytes_rexmt);
|
||||
tp->snd_cwnd = sack_bytes_rexmt + (tp->snd_nxt - tp->sack_newdata) +
|
||||
tp->t_maxseg;
|
||||
/* send one or 2 segments based on how much new data was acked */
|
||||
if (((th->th_ack - tp->snd_una) / tp->t_maxseg) > 2)
|
||||
num_segs = 2;
|
||||
(void)tcp_sack_output(tp, &sack_bytes_rxmt);
|
||||
tp->snd_cwnd = sack_bytes_rxmt + (tp->snd_nxt - tp->sack_newdata) +
|
||||
num_segs * tp->t_maxseg;
|
||||
tp->t_flags |= TF_ACKNOW;
|
||||
(void) tcp_output(tp);
|
||||
tp->snd_cwnd = ocwnd;
|
||||
/*
|
||||
* Partial window deflation. Relies on fact that tp->snd_una
|
||||
* not updated yet.
|
||||
*/
|
||||
tp->snd_cwnd -= (th->th_ack - tp->snd_una - tp->t_maxseg);
|
||||
}
|
||||
|
||||
#ifdef TCP_SACK_DEBUG
|
||||
|
Loading…
Reference in New Issue
Block a user