aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@helsinki.fi>2010-10-13 21:42:30 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-17 16:46:33 -0400
commit1fdb936101637c91819efea47e921bb592e07e34 (patch)
treec713564e117225a2af79479a0ed82d277a54e41d /net/ipv4/tcp_input.c
parentf3e85df845a5da60fc461cf49537435b1d07cf6d (diff)
tcp: sack lost marking fixes
When only fast rexmit should be done, tcp_mark_head_lost marks L too far. Also, sacked_upto below 1 is perfectly valid number, the packets == 0 then needs to be trapped elsewhere. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e4fbdae066d5..ee0df4817498 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2495,7 +2495,7 @@ static void tcp_timeout_skbs(struct sock *sk)
2495/* Mark head of queue up as lost. With RFC3517 SACK, the packets is 2495/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
2496 * is against sacked "cnt", otherwise it's against facked "cnt" 2496 * is against sacked "cnt", otherwise it's against facked "cnt"
2497 */ 2497 */
2498static void tcp_mark_head_lost(struct sock *sk, int packets) 2498static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
2499{ 2499{
2500 struct tcp_sock *tp = tcp_sk(sk); 2500 struct tcp_sock *tp = tcp_sk(sk);
2501 struct sk_buff *skb; 2501 struct sk_buff *skb;
@@ -2503,13 +2503,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
2503 int err; 2503 int err;
2504 unsigned int mss; 2504 unsigned int mss;
2505 2505
2506 if (packets == 0)
2507 return;
2508
2509 WARN_ON(packets > tp->packets_out); 2506 WARN_ON(packets > tp->packets_out);
2510 if (tp->lost_skb_hint) { 2507 if (tp->lost_skb_hint) {
2511 skb = tp->lost_skb_hint; 2508 skb = tp->lost_skb_hint;
2512 cnt = tp->lost_cnt_hint; 2509 cnt = tp->lost_cnt_hint;
2510 /* Head already handled? */
2511 if (mark_head && skb != tcp_write_queue_head(sk))
2512 return;
2513 } else { 2513 } else {
2514 skb = tcp_write_queue_head(sk); 2514 skb = tcp_write_queue_head(sk);
2515 cnt = 0; 2515 cnt = 0;
@@ -2544,6 +2544,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
2544 } 2544 }
2545 2545
2546 tcp_skb_mark_lost(tp, skb); 2546 tcp_skb_mark_lost(tp, skb);
2547
2548 if (mark_head)
2549 break;
2547 } 2550 }
2548 tcp_verify_left_out(tp); 2551 tcp_verify_left_out(tp);
2549} 2552}
@@ -2555,17 +2558,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
2555 struct tcp_sock *tp = tcp_sk(sk); 2558 struct tcp_sock *tp = tcp_sk(sk);
2556 2559
2557 if (tcp_is_reno(tp)) { 2560 if (tcp_is_reno(tp)) {
2558 tcp_mark_head_lost(sk, 1); 2561 tcp_mark_head_lost(sk, 1, 1);
2559 } else if (tcp_is_fack(tp)) { 2562 } else if (tcp_is_fack(tp)) {
2560 int lost = tp->fackets_out - tp->reordering; 2563 int lost = tp->fackets_out - tp->reordering;
2561 if (lost <= 0) 2564 if (lost <= 0)
2562 lost = 1; 2565 lost = 1;
2563 tcp_mark_head_lost(sk, lost); 2566 tcp_mark_head_lost(sk, lost, 0);
2564 } else { 2567 } else {
2565 int sacked_upto = tp->sacked_out - tp->reordering; 2568 int sacked_upto = tp->sacked_out - tp->reordering;
2566 if (sacked_upto < fast_rexmit) 2569 if (sacked_upto >= 0)
2567 sacked_upto = fast_rexmit; 2570 tcp_mark_head_lost(sk, sacked_upto, 0);
2568 tcp_mark_head_lost(sk, sacked_upto); 2571 else if (fast_rexmit)
2572 tcp_mark_head_lost(sk, 1, 1);
2569 } 2573 }
2570 2574
2571 tcp_timeout_skbs(sk); 2575 tcp_timeout_skbs(sk);
@@ -2971,7 +2975,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
2971 before(tp->snd_una, tp->high_seq) && 2975 before(tp->snd_una, tp->high_seq) &&
2972 icsk->icsk_ca_state != TCP_CA_Open && 2976 icsk->icsk_ca_state != TCP_CA_Open &&
2973 tp->fackets_out > tp->reordering) { 2977 tp->fackets_out > tp->reordering) {
2974 tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); 2978 tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
2975 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); 2979 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS);
2976 } 2980 }
2977 2981