mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 05:31:15 +00:00
tcp: fix cwnd limited checking to improve congestion control
Yuchung discovered tcp_is_cwnd_limited() was returning false in slow start phase even if the application filled the socket write queue. All congestion modules take into account tcp_is_cwnd_limited() before increasing cwnd, so this behavior limits slow start from probing the bandwidth at full speed. The problem is that even if write queue is full (aka we are _not_ application limited), cwnd can be under utilized if TSO should auto defer or TCP Small queues decided to hold packets. So the in_flight can be kept to smaller value, and we can get to the point tcp_is_cwnd_limited() returns false. With TCP Small Queues and FQ/pacing, this issue is more visible. We fix this by having tcp_cwnd_validate(), which is supposed to track such things, take into account unsent_segs, the number of segs that we are not sending at the moment due to TSO or TSQ, but intend to send real soon. Then when we are cwnd-limited, remember this fact while we are processing the window of ACKs that comes back. For example, suppose we have a brand new connection with cwnd=10; we are in slow start, and we send a flight of 9 packets. By the time we have received ACKs for all 9 packets we want our cwnd to be 18. We implement this by setting tp->lsnd_pending to 9, and considering ourselves to be cwnd-limited while cwnd is less than twice tp->lsnd_pending (2*9 -> 18). This makes tcp_is_cwnd_limited() more understandable, by removing the GSO/TSO kludge, that tried to work around the issue. Note the in_flight parameter can be removed in a followup cleanup patch. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4e8bbb819d
commit
e114a710aa
4 changed files with 36 additions and 28 deletions
|
@ -276,26 +276,6 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* RFC2861 Check whether we are limited by application or congestion window
|
||||
* This is the inverse of cwnd check in tcp_tso_should_defer
|
||||
*/
|
||||
bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
|
||||
{
|
||||
const struct tcp_sock *tp = tcp_sk(sk);
|
||||
u32 left;
|
||||
|
||||
if (in_flight >= tp->snd_cwnd)
|
||||
return true;
|
||||
|
||||
left = tp->snd_cwnd - in_flight;
|
||||
if (sk_can_gso(sk) &&
|
||||
left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd &&
|
||||
left < tp->xmit_size_goal_segs)
|
||||
return true;
|
||||
return left <= tcp_max_tso_deferred_mss(tp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tcp_is_cwnd_limited);
|
||||
|
||||
/* Slow start is used when congestion window is no greater than the slow start
|
||||
* threshold. We base on RFC2581 and also handle stretch ACKs properly.
|
||||
* We do not implement RFC3465 Appropriate Byte Counting (ABC) per se but
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue