aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 20847de991ea..f9181a133462 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1402,12 +1402,13 @@ static void tcp_cwnd_application_limited(struct sock *sk)
1402 tp->snd_cwnd_stamp = tcp_time_stamp; 1402 tp->snd_cwnd_stamp = tcp_time_stamp;
1403} 1403}
1404 1404
1405/* Congestion window validation. (RFC2861) */ 1405static void tcp_cwnd_validate(struct sock *sk, u32 unsent_segs)
1406static void tcp_cwnd_validate(struct sock *sk)
1407{ 1406{
1408 struct tcp_sock *tp = tcp_sk(sk); 1407 struct tcp_sock *tp = tcp_sk(sk);
1409 1408
1410 if (tp->packets_out >= tp->snd_cwnd) { 1409 tp->lsnd_pending = tp->packets_out + unsent_segs;
1410
1411 if (tcp_is_cwnd_limited(sk, 0)) {
1411 /* Network is feed fully. */ 1412 /* Network is feed fully. */
1412 tp->snd_cwnd_used = 0; 1413 tp->snd_cwnd_used = 0;
1413 tp->snd_cwnd_stamp = tcp_time_stamp; 1414 tp->snd_cwnd_stamp = tcp_time_stamp;
@@ -1880,7 +1881,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
1880{ 1881{
1881 struct tcp_sock *tp = tcp_sk(sk); 1882 struct tcp_sock *tp = tcp_sk(sk);
1882 struct sk_buff *skb; 1883 struct sk_buff *skb;
1883 unsigned int tso_segs, sent_pkts; 1884 unsigned int tso_segs, sent_pkts, unsent_segs = 0;
1884 int cwnd_quota; 1885 int cwnd_quota;
1885 int result; 1886 int result;
1886 1887
@@ -1924,7 +1925,7 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
1924 break; 1925 break;
1925 } else { 1926 } else {
1926 if (!push_one && tcp_tso_should_defer(sk, skb)) 1927 if (!push_one && tcp_tso_should_defer(sk, skb))
1927 break; 1928 goto compute_unsent_segs;
1928 } 1929 }
1929 1930
1930 /* TCP Small Queues : 1931 /* TCP Small Queues :
@@ -1949,8 +1950,14 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
1949 * there is no smp_mb__after_set_bit() yet 1950 * there is no smp_mb__after_set_bit() yet
1950 */ 1951 */
1951 smp_mb__after_clear_bit(); 1952 smp_mb__after_clear_bit();
1952 if (atomic_read(&sk->sk_wmem_alloc) > limit) 1953 if (atomic_read(&sk->sk_wmem_alloc) > limit) {
1954 u32 unsent_bytes;
1955
1956compute_unsent_segs:
1957 unsent_bytes = tp->write_seq - tp->snd_nxt;
1958 unsent_segs = DIV_ROUND_UP(unsent_bytes, mss_now);
1953 break; 1959 break;
1960 }
1954 } 1961 }
1955 1962
1956 limit = mss_now; 1963 limit = mss_now;
@@ -1990,7 +1997,7 @@ repair:
1990 /* Send one loss probe per tail loss episode. */ 1997 /* Send one loss probe per tail loss episode. */
1991 if (push_one != 2) 1998 if (push_one != 2)
1992 tcp_schedule_loss_probe(sk); 1999 tcp_schedule_loss_probe(sk);
1993 tcp_cwnd_validate(sk); 2000 tcp_cwnd_validate(sk, unsent_segs);
1994 return false; 2001 return false;
1995 } 2002 }
1996 return (push_one == 2) || (!tp->packets_out && tcp_send_head(sk)); 2003 return (push_one == 2) || (!tp->packets_out && tcp_send_head(sk));