|
@@ -1904,7 +1904,9 @@ static int tso_fragment(struct sock *sk, enum tcp_queue tcp_queue,
|
|
|
* This algorithm is from John Heffner.
|
|
|
*/
|
|
|
static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
|
|
|
- bool *is_cwnd_limited, u32 max_segs)
|
|
|
+ bool *is_cwnd_limited,
|
|
|
+ bool *is_rwnd_limited,
|
|
|
+ u32 max_segs)
|
|
|
{
|
|
|
const struct inet_connection_sock *icsk = inet_csk(sk);
|
|
|
u32 age, send_win, cong_win, limit, in_flight;
|
|
@@ -1912,9 +1914,6 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
|
|
|
struct sk_buff *head;
|
|
|
int win_divisor;
|
|
|
|
|
|
- if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
|
|
|
- goto send_now;
|
|
|
-
|
|
|
if (icsk->icsk_ca_state >= TCP_CA_Recovery)
|
|
|
goto send_now;
|
|
|
|
|
@@ -1973,10 +1972,27 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb,
|
|
|
if (age < (tp->srtt_us >> 4))
|
|
|
goto send_now;
|
|
|
|
|
|
- /* Ok, it looks like it is advisable to defer. */
|
|
|
+ /* Ok, it looks like it is advisable to defer.
|
|
|
+ * Three cases are tracked :
|
|
|
+ * 1) We are cwnd-limited
|
|
|
+ * 2) We are rwnd-limited
|
|
|
+ * 3) We are application limited.
|
|
|
+ */
|
|
|
+ if (cong_win < send_win) {
|
|
|
+ if (cong_win <= skb->len) {
|
|
|
+ *is_cwnd_limited = true;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (send_win <= skb->len) {
|
|
|
+ *is_rwnd_limited = true;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if (cong_win < send_win && cong_win <= skb->len)
|
|
|
- *is_cwnd_limited = true;
|
|
|
+ /* If this packet won't get more data, do not wait. */
|
|
|
+ if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
|
|
|
+ goto send_now;
|
|
|
|
|
|
return true;
|
|
|
|
|
@@ -2356,11 +2372,8 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
|
|
} else {
|
|
|
if (!push_one &&
|
|
|
tcp_tso_should_defer(sk, skb, &is_cwnd_limited,
|
|
|
- max_segs)) {
|
|
|
- if (!is_cwnd_limited)
|
|
|
- is_rwnd_limited = true;
|
|
|
+ &is_rwnd_limited, max_segs))
|
|
|
break;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
limit = mss_now;
|