mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
tcp: Apply device TSO segment limit earlier
Cache the device gso_max_segs in sock::sk_gso_max_segs and use it to limit the size of TSO skbs. This avoids the need to fall back to software GSO for local TCP senders. Signed-off-by: Ben Hutchings <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
7e6d06f0de
commit
1485348d24
5 changed files with 20 additions and 11 deletions
|
|
@ -811,7 +811,9 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now,
|
|||
old_size_goal + mss_now > xmit_size_goal)) {
|
||||
xmit_size_goal = old_size_goal;
|
||||
} else {
|
||||
tp->xmit_size_goal_segs = xmit_size_goal / mss_now;
|
||||
tp->xmit_size_goal_segs =
|
||||
min_t(u16, xmit_size_goal / mss_now,
|
||||
sk->sk_gso_max_segs);
|
||||
xmit_size_goal = tp->xmit_size_goal_segs * mss_now;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -291,7 +291,8 @@ bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
|
|||
left = tp->snd_cwnd - in_flight;
|
||||
if (sk_can_gso(sk) &&
|
||||
left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
|
||||
left * tp->mss_cache < sk->sk_gso_max_size)
|
||||
left * tp->mss_cache < sk->sk_gso_max_size &&
|
||||
left < sk->sk_gso_max_segs)
|
||||
return true;
|
||||
return left <= tcp_max_tso_deferred_mss(tp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1522,21 +1522,21 @@ static void tcp_cwnd_validate(struct sock *sk)
|
|||
* when we would be allowed to send the split-due-to-Nagle skb fully.
|
||||
*/
|
||||
static unsigned int tcp_mss_split_point(const struct sock *sk, const struct sk_buff *skb,
|
||||
unsigned int mss_now, unsigned int cwnd)
|
||||
unsigned int mss_now, unsigned int max_segs)
|
||||
{
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
u32 needed, window, cwnd_len;
|
||||
u32 needed, window, max_len;
|
||||
|
||||
window = tcp_wnd_end(tp) - TCP_SKB_CB(skb)->seq;
|
||||
cwnd_len = mss_now * cwnd;
|
||||
max_len = mss_now * max_segs;
|
||||
|
||||
if (likely(cwnd_len <= window && skb != tcp_write_queue_tail(sk)))
|
||||
return cwnd_len;
|
||||
if (likely(max_len <= window && skb != tcp_write_queue_tail(sk)))
|
||||
return max_len;
|
||||
|
||||
needed = min(skb->len, window);
|
||||
|
||||
if (cwnd_len <= needed)
|
||||
return cwnd_len;
|
||||
if (max_len <= needed)
|
||||
return max_len;
|
||||
|
||||
return needed - needed % mss_now;
|
||||
}
|
||||
|
|
@ -1765,7 +1765,8 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
|
|||
limit = min(send_win, cong_win);
|
||||
|
||||
/* If a full-sized TSO skb can be sent, do it. */
|
||||
if (limit >= sk->sk_gso_max_size)
|
||||
if (limit >= min_t(unsigned int, sk->sk_gso_max_size,
|
||||
sk->sk_gso_max_segs * tp->mss_cache))
|
||||
goto send_now;
|
||||
|
||||
/* Middle in queue won't get any more data, full sendable already? */
|
||||
|
|
@ -1999,7 +2000,9 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
|
|||
limit = mss_now;
|
||||
if (tso_segs > 1 && !tcp_urg_mode(tp))
|
||||
limit = tcp_mss_split_point(sk, skb, mss_now,
|
||||
cwnd_quota);
|
||||
min_t(unsigned int,
|
||||
cwnd_quota,
|
||||
sk->sk_gso_max_segs));
|
||||
|
||||
if (skb->len > limit &&
|
||||
unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))
|
||||
|
|
|
|||
Loading…
Reference in a new issue