summaryrefslogtreecommitdiffstats
path: root/include/linux/tcp.h
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2014-04-30 11:58:13 -0700
committerDavid S. Miller <davem@davemloft.net>2014-05-02 17:54:35 -0400
commite114a710aa5058c0ba4aa1dfb105132aefeb5e04 (patch)
tree3d7c656358bbc5cd37f7c2a973923e6be6ced1d9 /include/linux/tcp.h
parent4e8bbb819d1594a01f91b1de83321f68d3e6e245 (diff)
downloadlinux-0-day-e114a710aa5058c0ba4aa1dfb105132aefeb5e04.tar.gz
linux-0-day-e114a710aa5058c0ba4aa1dfb105132aefeb5e04.tar.xz
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>
Diffstat (limited to 'include/linux/tcp.h')
-rw-r--r--include/linux/tcp.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/tcp.h b/include/linux/tcp.h
index 239946868142c..4e37c71ecd746 100644
--- a/include/linux/tcp.h
+++ b/include/linux/tcp.h
@@ -230,6 +230,7 @@ struct tcp_sock {
u32 snd_cwnd_clamp; /* Do not allow snd_cwnd to grow above this */
u32 snd_cwnd_used;
u32 snd_cwnd_stamp;
+ u32 lsnd_pending; /* packets inflight or unsent since last xmit */
u32 prior_cwnd; /* Congestion window at start of Recovery. */
u32 prr_delivered; /* Number of newly delivered packets to
* receiver in Recovery. */