Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108690242
D39299.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D39299.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D39299: tcp: include RFC6675 IsLost() in pipe calculation
Attached
Detach File
Event Timeline
Log In to Comment