From patchwork Sat Sep 17 17:35:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Neal Cardwell X-Patchwork-Id: 671244 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3sbzqT0hYdz9s2Q for ; Sun, 18 Sep 2016 03:37:09 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b=WNX3RSlH; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754449AbcIQRgm (ORCPT ); Sat, 17 Sep 2016 13:36:42 -0400 Received: from mail-qt0-f182.google.com ([209.85.216.182]:36838 "EHLO mail-qt0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754226AbcIQRg0 (ORCPT ); Sat, 17 Sep 2016 13:36:26 -0400 Received: by mail-qt0-f182.google.com with SMTP id l91so55917077qte.3 for ; Sat, 17 Sep 2016 10:36:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=02cSRlE+mdUrl2uvwGw5Jwpqq6tLEMk0ixD8H5vy1BM=; b=WNX3RSlH4A7m7SoWgvQmDyzhsrg4vsdn7iZvEZVwK/MyQuY2a7pZeaaB3mmDld3Ble HhhsM5KUk7SbBndG2ouZ0z1707IlLAsG+S8vwUnrmDdJpib7HzCAVCLWKlPz8hgDZUz4 8cxpQRNoPfjDlbAI+FdmsxbDjQ0C5xpY0oFI9DaokqlnCT42RsVtOCL12mpgoJnWu6Dq HUZUuxHc+8/g7o2iqYBWzbEHApvONh+taXb+QtNrFQtJnd6yMOtBgJsuJUng2RczP9f8 clBVtkO6zimxWtP/M9+gEiZ/F45WZWTY883pO67mgDKHrgDq2LO9zRgi1aG/XwR/iqvQ 1XTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=02cSRlE+mdUrl2uvwGw5Jwpqq6tLEMk0ixD8H5vy1BM=; b=H67njEf14ewNm56h75rhUba0YtOFibBbZwR+saizMXOeeCBRGPfR3RECn4uVEoElGs IGwHkpQBtAFOs7XZbIIhgn/VnPkQwDTRhAeiMB335X/djvO9Nr2OUfube/wvg7UH8IMV QBxv4BK8lWQsP72XSSmsEYLi0qXQzJTB9OdaHrBrsyPTLMD+qgdHReiaRWuRCD593K2s MG2fZkQB9VaqXpGQ0SDuqxSPrCKD8mVhb3lnQhe/fbjtrZMQsDiy+c5WpGAWFYI20aVv 1yJIKcqiSPQfluTbD+3dx9PXkxUb4vs6ljdBwmqowUdh9OOROINxMLOH+WA7WNkVjmHV OWng== X-Gm-Message-State: AE9vXwMmG65MlBpg1FUaLqP85fVBzEcApAqzK5qS8qiEWO2BO4uK/U44kwOlfmSod7JvGN7T X-Received: by 10.237.52.2 with SMTP id w2mr8282333qtd.112.1474133785412; Sat, 17 Sep 2016 10:36:25 -0700 (PDT) Received: from joy.nyc.corp.google.com ([100.101.230.104]) by smtp.gmail.com with ESMTPSA id t21sm8068625qkg.4.2016.09.17.10.36.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 17 Sep 2016 10:36:24 -0700 (PDT) From: Neal Cardwell To: David Miller Cc: netdev@vger.kernel.org, Yuchung Cheng , Van Jacobson , Neal Cardwell , Nandita Dukkipati , Eric Dumazet , Soheil Hassas Yeganeh Subject: [PATCH v2 net-next 09/16] tcp: export data delivery rate Date: Sat, 17 Sep 2016 13:35:42 -0400 Message-Id: <1474133749-12895-10-git-send-email-ncardwell@google.com> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1474133749-12895-1-git-send-email-ncardwell@google.com> References: <1474133749-12895-1-git-send-email-ncardwell@google.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Yuchung Cheng 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 Signed-off-by: Neal Cardwell Signed-off-by: Yuchung Cheng Signed-off-by: Nandita Dukkipati Signed-off-by: Eric Dumazet Signed-off-by: Soheil Hassas Yeganeh --- include/linux/tcp.h | 5 ++++- include/uapi/linux/tcp.h | 3 +++ net/ipv4/tcp.c | 11 ++++++++++- net/ipv4/tcp_rate.c | 12 +++++++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index fdcd00f..a17ae7b 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -213,7 +213,8 @@ struct tcp_sock { u8 reord; /* reordering detected */ } rack; u16 advmss; /* Advertised MSS */ - u8 unused; + u8 rate_app_limited:1, /* rate_{delivered,interval_us} limited? */ + unused:7; u8 nonagle : 4,/* Disable Nagle algorithm? */ thin_lto : 1,/* Use linear timeouts for thin streams */ thin_dupack : 1,/* Fast retransmit on first dupack */ @@ -271,6 +272,8 @@ struct tcp_sock { u32 app_limited; /* limited until "delivered" reaches this val */ struct skb_mstamp first_tx_mstamp; /* start of window send phase */ struct skb_mstamp delivered_mstamp; /* time we reached "delivered" */ + u32 rate_delivered; /* saved rate sample: packets delivered */ + u32 rate_interval_us; /* saved rate sample: time elapsed */ u32 rcv_wnd; /* Current receiver window */ u32 write_seq; /* Tail(+1) of data held in tcp send buffer */ diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h index 482898f..73ac0db 100644 --- a/include/uapi/linux/tcp.h +++ b/include/uapi/linux/tcp.h @@ -167,6 +167,7 @@ struct tcp_info { __u8 tcpi_backoff; __u8 tcpi_options; __u8 tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4; + __u8 tcpi_delivery_rate_app_limited:1; __u32 tcpi_rto; __u32 tcpi_ato; @@ -211,6 +212,8 @@ struct tcp_info { __u32 tcpi_min_rtt; __u32 tcpi_data_segs_in; /* RFC4898 tcpEStatsDataSegsIn */ __u32 tcpi_data_segs_out; /* RFC4898 tcpEStatsDataSegsOut */ + + __u64 tcpi_delivery_rate; }; /* for TCP_MD5SIG socket option */ diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0327a44..46b05b2 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2695,7 +2695,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) { const struct tcp_sock *tp = tcp_sk(sk); /* iff sk_type == SOCK_STREAM */ const struct inet_connection_sock *icsk = inet_csk(sk); - u32 now = tcp_time_stamp; + u32 now = tcp_time_stamp, intv; unsigned int start; int notsent_bytes; u64 rate64; @@ -2785,6 +2785,15 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_min_rtt = tcp_min_rtt(tp); info->tcpi_data_segs_in = tp->data_segs_in; info->tcpi_data_segs_out = tp->data_segs_out; + + info->tcpi_delivery_rate_app_limited = tp->rate_app_limited ? 1 : 0; + rate = READ_ONCE(tp->rate_delivered); + intv = READ_ONCE(tp->rate_interval_us); + if (rate && intv) { + rate64 = (u64)rate * tp->mss_cache * USEC_PER_SEC; + do_div(rate64, intv); + put_unaligned(rate64, &info->tcpi_delivery_rate); + } } EXPORT_SYMBOL_GPL(tcp_get_info); diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c index 52ff84b..9be1581 100644 --- a/net/ipv4/tcp_rate.c +++ b/net/ipv4/tcp_rate.c @@ -149,12 +149,22 @@ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, * for connections suffer heavy or prolonged losses. */ if (unlikely(rs->interval_us < tcp_min_rtt(tp))) { - rs->interval_us = -1; if (!rs->is_retrans) pr_debug("tcp rate: %ld %d %u %u %u\n", rs->interval_us, rs->delivered, inet_csk(sk)->icsk_ca_state, tp->rx_opt.sack_ok, tcp_min_rtt(tp)); + rs->interval_us = -1; + return; + } + + /* Record the last non-app-limited or the highest app-limited bw */ + if (!rs->is_app_limited || + ((u64)rs->delivered * tp->rate_interval_us >= + (u64)tp->rate_delivered * rs->interval_us)) { + tp->rate_delivered = rs->delivered; + tp->rate_interval_us = rs->interval_us; + tp->rate_app_limited = rs->is_app_limited; } }