diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r-- | net/ipv4/tcp_input.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 366f63ae4d5c..7bac1fac065f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -105,6 +105,7 @@ int sysctl_tcp_abc __read_mostly; | |||
105 | #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ | 105 | #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ |
106 | #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ | 106 | #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ |
107 | #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ | 107 | #define FLAG_NONHEAD_RETRANS_ACKED 0x1000 /* Non-head rexmitted data was ACKed */ |
108 | #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ | ||
108 | 109 | ||
109 | #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) | 110 | #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) |
110 | #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) | 111 | #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) |
@@ -1918,18 +1919,15 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
1918 | tp->frto_counter = 0; | 1919 | tp->frto_counter = 0; |
1919 | } | 1920 | } |
1920 | 1921 | ||
1921 | static int tcp_check_sack_reneging(struct sock *sk) | 1922 | /* If ACK arrived pointing to a remembered SACK, it means that our |
1923 | * remembered SACKs do not reflect real state of receiver i.e. | ||
1924 | * receiver _host_ is heavily congested (or buggy). | ||
1925 | * | ||
1926 | * Do processing similar to RTO timeout. | ||
1927 | */ | ||
1928 | static int tcp_check_sack_reneging(struct sock *sk, int flag) | ||
1922 | { | 1929 | { |
1923 | struct sk_buff *skb; | 1930 | if (flag & FLAG_SACK_RENEGING) { |
1924 | |||
1925 | /* If ACK arrived pointing to a remembered SACK, | ||
1926 | * it means that our remembered SACKs do not reflect | ||
1927 | * real state of receiver i.e. | ||
1928 | * receiver _host_ is heavily congested (or buggy). | ||
1929 | * Do processing similar to RTO timeout. | ||
1930 | */ | ||
1931 | if ((skb = tcp_write_queue_head(sk)) != NULL && | ||
1932 | (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) { | ||
1933 | struct inet_connection_sock *icsk = inet_csk(sk); | 1931 | struct inet_connection_sock *icsk = inet_csk(sk); |
1934 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKRENEGING); | 1932 | NET_INC_STATS_BH(LINUX_MIB_TCPSACKRENEGING); |
1935 | 1933 | ||
@@ -2515,7 +2513,7 @@ tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) | |||
2515 | tp->prior_ssthresh = 0; | 2513 | tp->prior_ssthresh = 0; |
2516 | 2514 | ||
2517 | /* B. In all the states check for reneging SACKs. */ | 2515 | /* B. In all the states check for reneging SACKs. */ |
2518 | if (tp->sacked_out && tcp_check_sack_reneging(sk)) | 2516 | if (tcp_check_sack_reneging(sk, flag)) |
2519 | return; | 2517 | return; |
2520 | 2518 | ||
2521 | /* C. Process data loss notification, provided it is valid. */ | 2519 | /* C. Process data loss notification, provided it is valid. */ |
@@ -2852,6 +2850,9 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets) | |||
2852 | tcp_clear_all_retrans_hints(tp); | 2850 | tcp_clear_all_retrans_hints(tp); |
2853 | } | 2851 | } |
2854 | 2852 | ||
2853 | if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) | ||
2854 | flag |= FLAG_SACK_RENEGING; | ||
2855 | |||
2855 | if (flag & FLAG_ACKED) { | 2856 | if (flag & FLAG_ACKED) { |
2856 | const struct tcp_congestion_ops *ca_ops | 2857 | const struct tcp_congestion_ops *ca_ops |
2857 | = inet_csk(sk)->icsk_ca_ops; | 2858 | = inet_csk(sk)->icsk_ca_ops; |