aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp.c
diff options
context:
space:
mode:
authorYuchung Cheng <ycheng@google.com>2016-09-19 23:39:16 -0400
committerDavid S. Miller <davem@davemloft.net>2016-09-21 00:23:00 -0400
commiteb8329e0a04db0061f714f033b4454326ba147f4 (patch)
tree802808773223d2aeac8d207debf6fe66fac31d39 /net/ipv4/tcp.c
parentd7722e8570fc0f1e003cee7cf37694041828918b (diff)
tcp: export data delivery rate
This commit export two new fields in struct tcp_info: tcpi_delivery_rate: The most recent goodput, as measured by tcp_rate_gen(). If the socket is limited by the sending application (e.g., no data to send), it reports the highest measurement instead of the most recent. The unit is bytes per second (like other rate fields in tcp_info). tcpi_delivery_rate_app_limited: A boolean indicating if the goodput was measured when the socket's throughput was limited by the sending application. This delivery rate information can be useful for applications that want to know the current throughput the TCP connection is seeing, e.g. adaptive bitrate video streaming. It can also be very useful for debugging or troubleshooting. 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 'net/ipv4/tcp.c')
-rw-r--r--net/ipv4/tcp.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 2250f891f931..f253e5019d22 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2712,7 +2712,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
2712{ 2712{
2713 const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ 2713 const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */
2714 const struct inet_connection_sock *icsk = inet_csk(sk); 2714 const struct inet_connection_sock *icsk = inet_csk(sk);
2715 u32 now = tcp_time_stamp; 2715 u32 now = tcp_time_stamp, intv;
2716 unsigned int start; 2716 unsigned int start;
2717 int notsent_bytes; 2717 int notsent_bytes;
2718 u64 rate64; 2718 u64 rate64;
@@ -2802,6 +2802,15 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
2802 info->tcpi_min_rtt = tcp_min_rtt(tp); 2802 info->tcpi_min_rtt = tcp_min_rtt(tp);
2803 info->tcpi_data_segs_in = tp->data_segs_in; 2803 info->tcpi_data_segs_in = tp->data_segs_in;
2804 info->tcpi_data_segs_out = tp->data_segs_out; 2804 info->tcpi_data_segs_out = tp->data_segs_out;
2805
2806 info->tcpi_delivery_rate_app_limited = tp->rate_app_limited ? 1 : 0;
2807 rate = READ_ONCE(tp->rate_delivered);
2808 intv = READ_ONCE(tp->rate_interval_us);
2809 if (rate && intv) {
2810 rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC;
2811 do_div(rate64, intv);
2812 put_unaligned(rate64, &info->tcpi_delivery_rate);
2813 }
2805} 2814}
2806EXPORT_SYMBOL_GPL(tcp_get_info); 2815EXPORT_SYMBOL_GPL(tcp_get_info);
2807 2816