Page MenuHomeFreeBSD

D28822.id84703.diff
No OneTemporary

D28822.id84703.diff

Index: sys/netinet/tcp_input.c
===================================================================
--- sys/netinet/tcp_input.c
+++ sys/netinet/tcp_input.c
@@ -153,11 +153,6 @@
&VNET_NAME(drop_synfin), 0,
"Drop TCP packets with SYN+FIN set");
-VNET_DEFINE(int, tcp_do_prr_conservative) = 0;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_prr_conservative, CTLFLAG_VNET | CTLFLAG_RW,
- &VNET_NAME(tcp_do_prr_conservative), 0,
- "Do conservative Proportional Rate Reduction");
-
VNET_DEFINE(int, tcp_do_prr) = 1;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, do_prr, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(tcp_do_prr), 1,
@@ -2597,13 +2592,14 @@
tp->snd_ssthresh, tp->sackhint.recover_fs) -
tp->sackhint.sack_bytes_rexmit;
} else {
- if (V_tcp_do_prr_conservative)
- limit = tp->sackhint.prr_delivered -
- tp->sackhint.sack_bytes_rexmit;
- else
- limit = imax(tp->sackhint.prr_delivered -
- tp->sackhint.sack_bytes_rexmit,
- del_data) + maxseg;
+ /*
+ * PRR 6937bis heuristic:
+ * Up here we deal with duplicate ACKs,
+ * which by definition do not advance snd_una.
+ * Therefore be always conservative.
+ */
+ limit = tp->sackhint.prr_delivered -
+ tp->sackhint.sack_bytes_rexmit;
snd_cnt = imin(tp->snd_ssthresh - pipe, limit);
}
snd_cnt = imax(snd_cnt, 0) / maxseg;
@@ -2811,7 +2807,7 @@
if (SEQ_LT(th->th_ack, tp->snd_recover)) {
if (tp->t_flags & TF_SACK_PERMIT)
if (V_tcp_do_prr && to.to_flags & TOF_SACK)
- tcp_prr_partialack(tp, th);
+ tcp_prr_partialack(tp, th, sack_changed);
else
tcp_sack_partialack(tp, th);
else
@@ -3940,7 +3936,7 @@
}
void
-tcp_prr_partialack(struct tcpcb *tp, struct tcphdr *th)
+tcp_prr_partialack(struct tcpcb *tp, struct tcphdr *th, int sack_changed)
{
int snd_cnt = 0, limit = 0, del_data = 0, pipe = 0;
int maxseg = tcp_maxseg(tp);
@@ -3971,7 +3967,17 @@
tp->snd_ssthresh, tp->sackhint.recover_fs) -
tp->sackhint.sack_bytes_rexmit;
} else {
- if (V_tcp_do_prr_conservative)
+ /*
+ * PRR 6937bis heuristic:
+ * - A partial ack without SACK block beneath snd_recover
+ * indicates further loss. This case is not handled here,
+ * but in tcp_sack_partialack, to send a rescue
+ * retransmissions.
+ * - An SACK scoreboard update adding a new hole indicates
+ * further loss, so be conservative and send at most one
+ * segment.
+ */
+ if (sack_changed == 2)
limit = tp->sackhint.prr_delivered -
tp->sackhint.sack_bytes_rexmit;
else
Index: sys/netinet/tcp_sack.c
===================================================================
--- sys/netinet/tcp_sack.c
+++ sys/netinet/tcp_sack.c
@@ -533,7 +533,8 @@
* Process cumulative ACK and the TCP SACK option to update the scoreboard.
* tp->snd_holes is an ordered list of holes (oldest to newest, in terms of
* the sequence space).
- * Returns 1 if incoming ACK has previously unknown SACK information,
+ * Returns 2 if incoming ACK indicates ongoing loss (hole split, new hole),
+ * 1 if incoming ACK has previously unknown SACK information,
* 0 otherwise.
*/
int
@@ -639,7 +640,7 @@
tp->snd_fack = sblkp->end;
/* Go to the previous sack block. */
sblkp--;
- sack_changed = 1;
+ sack_changed = 2;
} else {
/*
* We failed to add a new hole based on the current
@@ -656,7 +657,12 @@
SEQ_LT(tp->snd_fack, sblkp->end)) {
delivered_data += sblkp->end - tp->snd_fack;
tp->snd_fack = sblkp->end;
- sack_changed = 1;
+ /*
+ * While the Scoreboard didn't change in
+ * size, we only ended up here because
+ * some SACK data had to be dismissed.
+ */
+ sack_changed = 2;
}
}
} else if (SEQ_LT(tp->snd_fack, sblkp->end)) {
@@ -725,6 +731,7 @@
*/
temp = tcp_sackhole_insert(tp, sblkp->end,
cur->end, cur);
+ sack_changed = 2;
if (temp != NULL) {
if (SEQ_GT(cur->rxmit, temp->rxmit)) {
temp->rxmit = cur->rxmit;
Index: sys/netinet/tcp_var.h
===================================================================
--- sys/netinet/tcp_var.h
+++ sys/netinet/tcp_var.h
@@ -869,7 +869,6 @@
VNET_DECLARE(struct inpcbinfo, tcbinfo);
#define V_tcp_do_prr VNET(tcp_do_prr)
-#define V_tcp_do_prr_conservative VNET(tcp_do_prr_conservative)
#define V_tcp_do_newcwv VNET(tcp_do_newcwv)
#define V_drop_synfin VNET(drop_synfin)
#define V_path_mtu_discovery VNET(path_mtu_discovery)
@@ -1063,7 +1062,7 @@
void tcp_clean_sackreport(struct tcpcb *tp);
void tcp_sack_adjust(struct tcpcb *tp);
struct sackhole *tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt);
-void tcp_prr_partialack(struct tcpcb *, struct tcphdr *);
+void tcp_prr_partialack(struct tcpcb *, struct tcphdr *, int);
void tcp_sack_partialack(struct tcpcb *, struct tcphdr *);
void tcp_free_sackholes(struct tcpcb *tp);
int tcp_newreno(struct tcpcb *, struct tcphdr *);

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 13, 1:23 PM (10 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27628618
Default Alt Text
D28822.id84703.diff (4 KB)

Event Timeline