]> Pileus Git - ~andy/linux/blobdiff - net/ipv4/tcp_output.c
rbd: drop an unsafe assertion
[~andy/linux] / net / ipv4 / tcp_output.c
index 03d26b85eab8520c552040f527d37323be91bd68..3be16727f058b191d305366f9cf5851f03c7c417 100644 (file)
@@ -698,7 +698,8 @@ static void tcp_tsq_handler(struct sock *sk)
        if ((1 << sk->sk_state) &
            (TCPF_ESTABLISHED | TCPF_FIN_WAIT1 | TCPF_CLOSING |
             TCPF_CLOSE_WAIT  | TCPF_LAST_ACK))
-               tcp_write_xmit(sk, tcp_current_mss(sk), 0, 0, GFP_ATOMIC);
+               tcp_write_xmit(sk, tcp_current_mss(sk), tcp_sk(sk)->nonagle,
+                              0, GFP_ATOMIC);
 }
 /*
  * One tasklet per cpu tries to send more skbs.
@@ -1904,7 +1905,15 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
 
                if (atomic_read(&sk->sk_wmem_alloc) > limit) {
                        set_bit(TSQ_THROTTLED, &tp->tsq_flags);
-                       break;
+                       /* It is possible TX completion already happened
+                        * before we set TSQ_THROTTLED, so we must
+                        * test again the condition.
+                        * We abuse smp_mb__after_clear_bit() because
+                        * there is no smp_mb__after_set_bit() yet
+                        */
+                       smp_mb__after_clear_bit();
+                       if (atomic_read(&sk->sk_wmem_alloc) > limit)
+                               break;
                }
 
                limit = mss_now;
@@ -1977,7 +1986,7 @@ bool tcp_schedule_loss_probe(struct sock *sk)
        /* Schedule a loss probe in 2*RTT for SACK capable connections
         * in Open state, that are either limited by cwnd or application.
         */
-       if (sysctl_tcp_early_retrans < 3 || !rtt || !tp->packets_out ||
+       if (sysctl_tcp_early_retrans < 3 || !tp->srtt || !tp->packets_out ||
            !tcp_is_sack(tp) || inet_csk(sk)->icsk_ca_state != TCP_CA_Open)
                return false;