diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 20c9440ab85e..0f0c1c9829a1 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1269,6 +1269,9 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
1269 | if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window)) | 1269 | if (before(TCP_SKB_CB(ack_skb)->ack_seq, prior_snd_una - tp->max_window)) |
1270 | return 0; | 1270 | return 0; |
1271 | 1271 | ||
1272 | if (!tp->packets_out) | ||
1273 | goto out; | ||
1274 | |||
1272 | /* SACK fastpath: | 1275 | /* SACK fastpath: |
1273 | * if the only SACK change is the increase of the end_seq of | 1276 | * if the only SACK change is the increase of the end_seq of |
1274 | * the first block then only apply that SACK block | 1277 | * the first block then only apply that SACK block |
@@ -1515,6 +1518,8 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ | |||
1515 | (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) | 1518 | (!tp->frto_highmark || after(tp->snd_una, tp->frto_highmark))) |
1516 | tcp_update_reordering(sk, tp->fackets_out - reord, 0); | 1519 | tcp_update_reordering(sk, tp->fackets_out - reord, 0); |
1517 | 1520 | ||
1521 | out: | ||
1522 | |||
1518 | #if FASTRETRANS_DEBUG > 0 | 1523 | #if FASTRETRANS_DEBUG > 0 |
1519 | BUG_TRAP((int)tp->sacked_out >= 0); | 1524 | BUG_TRAP((int)tp->sacked_out >= 0); |
1520 | BUG_TRAP((int)tp->lost_out >= 0); | 1525 | BUG_TRAP((int)tp->lost_out >= 0); |
@@ -1669,6 +1674,9 @@ void tcp_enter_frto(struct sock *sk) | |||
1669 | } | 1674 | } |
1670 | tcp_verify_left_out(tp); | 1675 | tcp_verify_left_out(tp); |
1671 | 1676 | ||
1677 | /* Too bad if TCP was application limited */ | ||
1678 | tp->snd_cwnd = min(tp->snd_cwnd, tcp_packets_in_flight(tp) + 1); | ||
1679 | |||
1672 | /* Earlier loss recovery underway (see RFC4138; Appendix B). | 1680 | /* Earlier loss recovery underway (see RFC4138; Appendix B). |
1673 | * The last condition is necessary at least in tp->frto_counter case. | 1681 | * The last condition is necessary at least in tp->frto_counter case. |
1674 | */ | 1682 | */ |
@@ -1701,6 +1709,8 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) | |||
1701 | tcp_for_write_queue(skb, sk) { | 1709 | tcp_for_write_queue(skb, sk) { |
1702 | if (skb == tcp_send_head(sk)) | 1710 | if (skb == tcp_send_head(sk)) |
1703 | break; | 1711 | break; |
1712 | |||
1713 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; | ||
1704 | /* | 1714 | /* |
1705 | * Count the retransmission made on RTO correctly (only when | 1715 | * Count the retransmission made on RTO correctly (only when |
1706 | * waiting for the first ACK and did not get it)... | 1716 | * waiting for the first ACK and did not get it)... |
@@ -1714,7 +1724,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag) | |||
1714 | } else { | 1724 | } else { |
1715 | if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS) | 1725 | if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS) |
1716 | tp->undo_marker = 0; | 1726 | tp->undo_marker = 0; |
1717 | TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); | 1727 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; |
1718 | } | 1728 | } |
1719 | 1729 | ||
1720 | /* Don't lost mark skbs that were fwd transmitted after RTO */ | 1730 | /* Don't lost mark skbs that were fwd transmitted after RTO */ |
@@ -3103,11 +3113,11 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) | |||
3103 | /* See if we can take anything off of the retransmit queue. */ | 3113 | /* See if we can take anything off of the retransmit queue. */ |
3104 | flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); | 3114 | flag |= tcp_clean_rtx_queue(sk, &seq_rtt, prior_fackets); |
3105 | 3115 | ||
3116 | if (tp->frto_counter) | ||
3117 | frto_cwnd = tcp_process_frto(sk, flag); | ||
3106 | /* Guarantee sacktag reordering detection against wrap-arounds */ | 3118 | /* Guarantee sacktag reordering detection against wrap-arounds */ |
3107 | if (before(tp->frto_highmark, tp->snd_una)) | 3119 | if (before(tp->frto_highmark, tp->snd_una)) |
3108 | tp->frto_highmark = 0; | 3120 | tp->frto_highmark = 0; |
3109 | if (tp->frto_counter) | ||
3110 | frto_cwnd = tcp_process_frto(sk, flag); | ||
3111 | 3121 | ||
3112 | if (tcp_ack_is_dubious(sk, flag)) { | 3122 | if (tcp_ack_is_dubious(sk, flag)) { |
3113 | /* Advance CWND, if state allows this. */ | 3123 | /* Advance CWND, if state allows this. */ |