aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2007-11-11 00:20:59 -0500
committerDavid S. Miller <davem@davemloft.net>2007-11-11 00:20:59 -0500
commit8dd71c5d28cd88d4400e7f474986e799e39aff37 (patch)
treebf40818d0f79b579c20ab0273e7a5730352d442c
parent9e4505c459440a41fd466451cf840dec5c957eeb (diff)
[TCP]: Consider GSO while counting reord in sacktag
Reordering detection fails to take account that the reordered skb may have pcount larger than 1. In such case the lowest of them had the largest reordering, the old formula used the highest of them which is pcount - 1 packets less reordered. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/tcp_input.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index ca9590f4f520..0f757578f3bd 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1403,8 +1403,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1403 if (in_sack < 0) 1403 if (in_sack < 0)
1404 break; 1404 break;
1405 1405
1406 fack_count += tcp_skb_pcount(skb);
1407
1408 sacked = TCP_SKB_CB(skb)->sacked; 1406 sacked = TCP_SKB_CB(skb)->sacked;
1409 1407
1410 /* Account D-SACK for retransmitted packet. */ 1408 /* Account D-SACK for retransmitted packet. */
@@ -1427,11 +1425,14 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1427 } 1425 }
1428 1426
1429 /* Nothing to do; acked frame is about to be dropped. */ 1427 /* Nothing to do; acked frame is about to be dropped. */
1428 fack_count += tcp_skb_pcount(skb);
1430 continue; 1429 continue;
1431 } 1430 }
1432 1431
1433 if (!in_sack) 1432 if (!in_sack) {
1433 fack_count += tcp_skb_pcount(skb);
1434 continue; 1434 continue;
1435 }
1435 1436
1436 if (!(sacked&TCPCB_SACKED_ACKED)) { 1437 if (!(sacked&TCPCB_SACKED_ACKED)) {
1437 if (sacked & TCPCB_SACKED_RETRANS) { 1438 if (sacked & TCPCB_SACKED_RETRANS) {
@@ -1480,6 +1481,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1480 flag |= FLAG_DATA_SACKED; 1481 flag |= FLAG_DATA_SACKED;
1481 tp->sacked_out += tcp_skb_pcount(skb); 1482 tp->sacked_out += tcp_skb_pcount(skb);
1482 1483
1484 fack_count += tcp_skb_pcount(skb);
1483 if (fack_count > tp->fackets_out) 1485 if (fack_count > tp->fackets_out)
1484 tp->fackets_out = fack_count; 1486 tp->fackets_out = fack_count;
1485 1487
@@ -1490,6 +1492,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1490 } else { 1492 } else {
1491 if (dup_sack && (sacked&TCPCB_RETRANS)) 1493 if (dup_sack && (sacked&TCPCB_RETRANS))
1492 reord = min(fack_count, reord); 1494 reord = min(fack_count, reord);
1495
1496 fack_count += tcp_skb_pcount(skb);
1493 } 1497 }
1494 1498
1495 /* D-SACK. We can detect redundant retransmission 1499 /* D-SACK. We can detect redundant retransmission
@@ -1515,7 +1519,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
1515 1519
1516 if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss && 1520 if ((reord < tp->fackets_out) && icsk->icsk_ca_state != TCP_CA_Loss &&
1517 (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) 1521 (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark)))
1518 tcp_update_reordering(sk, ((tp->fackets_out + 1) - reord), 0); 1522 tcp_update_reordering(sk, tp->fackets_out - reord, 0);
1519 1523
1520#if FASTRETRANS_DEBUG > 0 1524#if FASTRETRANS_DEBUG > 0
1521 BUG_TRAP((int)tp->sacked_out >= 0); 1525 BUG_TRAP((int)tp->sacked_out >= 0);