goto out;
 out_err:
        /* make sure we wake any epoll edge trigger waiter */
-       if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 && err == -EAGAIN))
+       if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 &&
+                    err == -EAGAIN)) {
                sk->sk_write_space(sk);
+               tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED);
+       }
        return sk_stream_error(sk, flags, err);
 }
 
 out_err:
        err = sk_stream_error(sk, flags, err);
        /* make sure we wake any epoll edge trigger waiter */
-       if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 && err == -EAGAIN))
+       if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 &&
+                    err == -EAGAIN)) {
                sk->sk_write_space(sk);
+               tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED);
+       }
        release_sock(sk);
        return err;
 }
 
                /* pairs with tcp_poll() */
                smp_mb__after_atomic();
                if (sk->sk_socket &&
-                   test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+                   test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
                        tcp_new_space(sk);
+                       if (!test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+                               tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED);
+               }
        }
 }
 
 
                if (sysctl_tcp_slow_start_after_idle &&
                    (s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= inet_csk(sk)->icsk_rto)
                        tcp_cwnd_application_limited(sk);
+
+               /* The following conditions together indicate the starvation
+                * is caused by insufficient sender buffer:
+                * 1) just sent some data (see tcp_write_xmit)
+                * 2) not cwnd limited (this else condition)
+                * 3) no more data to send (null tcp_send_head )
+                * 4) application is hitting buffer limit (SOCK_NOSPACE)
+                */
+               if (!tcp_send_head(sk) && sk->sk_socket &&
+                   test_bit(SOCK_NOSPACE, &sk->sk_socket->flags) &&
+                   (1 << sk->sk_state) & (TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))
+                       tcp_chrono_start(sk, TCP_CHRONO_SNDBUF_LIMITED);
        }
 }