aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/tcp.h
diff options
context:
space:
mode:
authorSoheil Hassas Yeganeh <soheil@google.com>2016-09-19 23:39:15 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-21 00:23:00 -0400
commitd7722e8570fc0f1e003cee7cf37694041828918b (patch)
tree8118e0e16e57723d6a9cb3601eb6cc626d657b23 /include/net/tcp.h
parentb9f64820fb226a4e8ab10591f46cecd91ca56b30 (diff)
tcp: track application-limited rate samples
This commit adds code to track whether the delivery rate represented by each rate_sample was limited by the application. Upon each transmit, we store in the is_app_limited field in the skb a boolean bit indicating whether there is a known "bubble in the pipe": a point in the rate sample interval where the sender was application-limited, and did not transmit even though the cwnd and pacing rate allowed it. This logic marks the flow app-limited on a write if *all* of the following are true: 1) There is less than 1 MSS of unsent data in the write queue available to transmit. 2) There is no packet in the sender's queues (e.g. in fq or the NIC tx queue). 3) The connection is not limited by cwnd. 4) There are no lost packets to retransmit. The tcp_rate_check_app_limited() code in tcp_rate.c determines whether the connection is application-limited at the moment. If the flow is application-limited, it sets the tp->app_limited field. If the flow is application-limited then that means there is effectively a "bubble" of silence in the pipe now, and this silence will be reflected in a lower bandwidth sample for any rate samples from now until we get an ACK indicating this bubble has exited the pipe: specifically, until we get an ACK for the next packet we transmit. When we send every skb we record in scb->tx.is_app_limited whether the resulting rate sample will be application-limited. The code in tcp_rate_gen() checks to see when it is safe to mark all known application-limited bubbles of silence as having exited the pipe. It does this by checking to see when the delivered count moves past the tp->app_limited marker. At this point it zeroes the tp->app_limited marker, as all known bubbles are out of the pipe. We make room for the tx.is_app_limited bit in the skb by borrowing a bit from the in_flight field used by NV to record the number of bytes in flight. The receive window in the TCP header is 16 bits, and the max receive window scaling shift factor is 14 (RFC 1323). So the max receive window offered by the TCP protocol is 2^(16+14) = 2^30. So we only need 30 bits for the tx.in_flight used by NV. Signed-off-by: Van Jacobson <vanj@google.com> Signed-off-by: Neal Cardwell <ncardwell@google.com> Signed-off-by: Yuchung Cheng <ycheng@google.com> Signed-off-by: Nandita Dukkipati <nanditad@google.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Soheil Hassas Yeganeh <soheil@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r--include/net/tcp.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h
index b261c892605a..a69ed7f0030c 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -764,7 +764,9 @@ struct tcp_skb_cb {
764 union { 764 union {
765 struct { 765 struct {
766 /* There is space for up to 24 bytes */ 766 /* There is space for up to 24 bytes */
767 __u32 in_flight;/* Bytes in flight when packet sent */ 767 __u32 in_flight:30,/* Bytes in flight at transmit */
768 is_app_limited:1, /* cwnd not fully used? */
769 unused:1;
768 /* pkts S/ACKed so far upon tx of skb, incl retrans: */ 770 /* pkts S/ACKed so far upon tx of skb, incl retrans: */
769 __u32 delivered; 771 __u32 delivered;
770 /* start of send pipeline phase */ 772 /* start of send pipeline phase */
@@ -883,6 +885,7 @@ struct rate_sample {
883 int losses; /* number of packets marked lost upon ACK */ 885 int losses; /* number of packets marked lost upon ACK */
884 u32 acked_sacked; /* number of packets newly (S)ACKed upon ACK */ 886 u32 acked_sacked; /* number of packets newly (S)ACKed upon ACK */
885 u32 prior_in_flight; /* in flight before this ACK */ 887 u32 prior_in_flight; /* in flight before this ACK */
888 bool is_app_limited; /* is sample from packet with bubble in pipe? */
886 bool is_retrans; /* is sample from retransmission? */ 889 bool is_retrans; /* is sample from retransmission? */
887}; 890};
888 891
@@ -978,6 +981,7 @@ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb,
978 struct rate_sample *rs); 981 struct rate_sample *rs);
979void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, 982void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost,
980 struct skb_mstamp *now, struct rate_sample *rs); 983 struct skb_mstamp *now, struct rate_sample *rs);
984void tcp_rate_check_app_limited(struct sock *sk);
981 985
982/* These functions determine how the current flow behaves in respect of SACK 986/* These functions determine how the current flow behaves in respect of SACK
983 * handling. SACK is negotiated with the peer, and therefore it can vary 987 * handling. SACK is negotiated with the peer, and therefore it can vary