Page MenuHomeFreeBSD

D39299.diff
No OneTemporary

D39299.diff

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
@@ -4048,7 +4048,8 @@
if (tp->t_fb->tfb_compute_pipe == NULL) {
return (tp->snd_max - tp->snd_una +
tp->sackhint.sack_bytes_rexmit -
- tp->sackhint.sacked_bytes);
+ tp->sackhint.sacked_bytes -
+ tp->sackhint.lost_bytes);
} else {
return((*tp->t_fb->tfb_compute_pipe)(tp));
}
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c
--- a/sys/netinet/tcp_sack.c
+++ b/sys/netinet/tcp_sack.c
@@ -555,6 +555,11 @@
int i, j, num_sack_blks, sack_changed;
int delivered_data, left_edge_delta;
+ tcp_seq loss_hiack = 0;
+ int loss_thresh = 0;
+ int loss_sblks = 0;
+ int notlost_bytes = 0;
+
INP_WLOCK_ASSERT(tptoinpcb(tp));
num_sack_blks = 0;
@@ -637,6 +642,7 @@
*/
tp->snd_fack = SEQ_MAX(tp->snd_una, th_ack);
tp->sackhint.sacked_bytes = 0; /* reset */
+ tp->sackhint.hole_bytes = 0;
}
/*
* In the while-loop below, incoming SACK blocks (sack_blocks[]) and
@@ -661,13 +667,17 @@
*/
if (((temp = TAILQ_LAST(&tp->snd_holes, sackhole_head)) != NULL) &&
SEQ_LEQ(tp->snd_fack,temp->end)) {
+ tp->sackhint.hole_bytes -= temp->end - temp->start;
temp->start = SEQ_MAX(tp->snd_fack, SEQ_MAX(tp->snd_una, th_ack));
temp->end = sblkp->start;
temp->rxmit = temp->start;
delivered_data += sblkp->end - sblkp->start;
+ tp->sackhint.hole_bytes += temp->end - temp->start;
+ KASSERT(tp->sackhint.hole_bytes >= 0,
+ ("sackhint hole bytes >= 0"));
tp->snd_fack = sblkp->end;
- sblkp--;
sack_changed = 1;
+ sblkp--;
} else {
/*
* Append a new SACK hole at the tail. If the
@@ -678,10 +688,11 @@
temp = tcp_sackhole_insert(tp, tp->snd_fack,sblkp->start,NULL);
if (temp != NULL) {
delivered_data += sblkp->end - sblkp->start;
+ tp->sackhint.hole_bytes += temp->end - temp->start;
tp->snd_fack = sblkp->end;
+ sack_changed = 1;
/* Go to the previous sack block. */
sblkp--;
- sack_changed = 1;
} else {
/*
* We failed to add a new hole based on the current
@@ -709,11 +720,29 @@
sack_changed = 1;
}
cur = TAILQ_LAST(&tp->snd_holes, sackhole_head); /* Last SACK hole. */
+ loss_hiack = tp->snd_fack;
+
/*
* Since the incoming sack blocks are sorted, we can process them
* making one sweep of the scoreboard.
*/
- while (sblkp >= sack_blocks && cur != NULL) {
+ while (cur != NULL) {
+ if (!(sblkp >= sack_blocks)) {
+ if (((loss_sblks >= tcprexmtthresh) ||
+ (loss_thresh > (tcprexmtthresh-1)*tp->t_maxseg)))
+ break;
+ loss_thresh += loss_hiack - cur->end;
+ loss_hiack = cur->start;
+ loss_sblks++;
+ if (!((loss_sblks >= tcprexmtthresh) ||
+ (loss_thresh > (tcprexmtthresh-1)*tp->t_maxseg))) {
+ notlost_bytes += cur->end - cur->start;
+ } else {
+ break;
+ }
+ cur = TAILQ_PREV(cur, sackhole_head, scblink);
+ continue;
+ }
if (SEQ_GEQ(sblkp->start, cur->end)) {
/*
* SACKs data beyond the current hole. Go to the
@@ -727,6 +756,12 @@
* SACKs data before the current hole. Go to the
* previous hole.
*/
+ loss_thresh += loss_hiack - cur->end;
+ loss_hiack = cur->start;
+ loss_sblks++;
+ if (!((loss_sblks >= tcprexmtthresh) ||
+ (loss_thresh > (tcprexmtthresh-1)*tp->t_maxseg)))
+ notlost_bytes += cur->end - cur->start;
cur = TAILQ_PREV(cur, sackhole_head, scblink);
continue;
}
@@ -742,6 +777,7 @@
delivered_data += (cur->end - cur->start);
temp = cur;
cur = TAILQ_PREV(cur, sackhole_head, scblink);
+ tp->sackhint.hole_bytes -= temp->end - temp->start;
tcp_sackhole_remove(tp, temp);
/*
* The sack block may ack all or part of the
@@ -752,6 +788,7 @@
} else {
/* Move start of hole forward. */
delivered_data += (sblkp->end - cur->start);
+ tp->sackhint.hole_bytes -= sblkp->end - cur->start;
cur->start = sblkp->end;
cur->rxmit = SEQ_MAX(cur->rxmit, cur->start);
}
@@ -760,6 +797,7 @@
if (SEQ_GEQ(sblkp->end, cur->end)) {
/* Move end of hole backward. */
delivered_data += (cur->end - sblkp->start);
+ tp->sackhint.hole_bytes -= cur->end - sblkp->start;
cur->end = sblkp->start;
cur->rxmit = SEQ_MIN(cur->rxmit, cur->end);
if ((tp->t_flags & TF_LRD) && SEQ_GEQ(cur->rxmit, cur->end))
@@ -778,6 +816,13 @@
(SEQ_MIN(temp->rxmit,
temp->end) - temp->start);
}
+ tp->sackhint.hole_bytes -= sblkp->end - sblkp->start;
+ loss_thresh += loss_hiack - temp->end;
+ loss_hiack = temp->start;
+ loss_sblks++;
+ if (!((loss_sblks >= tcprexmtthresh) ||
+ (loss_thresh > (tcprexmtthresh-1)*tp->t_maxseg)))
+ notlost_bytes += temp->end - temp->start;
cur->end = sblkp->start;
cur->rxmit = SEQ_MIN(cur->rxmit,
cur->end);
@@ -794,11 +839,25 @@
* we're done with the sack block or the sack hole.
* Accordingly, we advance one or the other.
*/
- if (SEQ_LEQ(sblkp->start, cur->start))
+ if (SEQ_LEQ(sblkp->start, cur->start)) {
+ loss_thresh += loss_hiack - cur->end;
+ loss_hiack = cur->start;
+ loss_sblks++;
+ if (!((loss_sblks >= tcprexmtthresh) ||
+ (loss_thresh > (tcprexmtthresh-1)*tp->t_maxseg)))
+ notlost_bytes += cur->end - cur->start;
cur = TAILQ_PREV(cur, sackhole_head, scblink);
- else
+ } else {
sblkp--;
+ }
}
+
+ KASSERT(!(TAILQ_EMPTY(&tp->snd_holes) && (tp->sackhint.hole_bytes != 0)),
+ ("SACK scoreboard empty, but accounting non-zero\n"));
+
+ KASSERT(notlost_bytes <= tp->sackhint.hole_bytes,
+ ("SACK: more bytes marked notlost than in scoreboard holes"));
+
if (!(to->to_flags & TOF_SACK))
/*
* If this ACK did not contain any
@@ -811,6 +870,7 @@
sack_changed = 0;
tp->sackhint.delivered_data = delivered_data;
tp->sackhint.sacked_bytes += delivered_data - left_edge_delta;
+ tp->sackhint.lost_bytes = tp->sackhint.hole_bytes - notlost_bytes;
KASSERT((delivered_data >= 0), ("delivered_data < 0"));
KASSERT((tp->sackhint.sacked_bytes >= 0), ("sacked_bytes < 0"));
return (sack_changed);
@@ -845,6 +905,7 @@
void
tcp_sack_partialack(struct tcpcb *tp, struct tcphdr *th)
{
+ struct sackhole *temp;
int num_segs = 1;
u_int maxseg = tcp_maxseg(tp);
@@ -891,8 +952,10 @@
highdata = SEQ_MIN(highdata, tp->snd_recover);
if (th->th_ack != highdata) {
tp->snd_fack = th->th_ack;
- (void)tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack,
- highdata - maxseg), highdata, NULL);
+ if ((temp = tcp_sackhole_insert(tp, SEQ_MAX(th->th_ack,
+ highdata - maxseg), highdata, NULL)) != NULL)
+ tp->sackhint.hole_bytes += temp->end -
+ temp->start;
}
}
(void) tcp_output(tp);
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -128,6 +128,8 @@
uint32_t recover_fs; /* Flight Size at the start of Loss recovery */
uint32_t prr_delivered; /* Total bytes delivered using PRR */
uint32_t prr_out; /* Bytes sent during IN_RECOVERY */
+ uint32_t hole_bytes; /* current number of bytes in scoreboard holes */
+ uint32_t lost_bytes; /* number of rfc6675 IsLost() bytes */
};
#define SEGQ_EMPTY(tp) TAILQ_EMPTY(&(tp)->t_segq)

File Metadata

Mime Type
text/plain
Expires
Tue, Jan 28, 8:19 AM (4 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16262392
Default Alt Text
D39299.diff (7 KB)

Event Timeline