aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/tcp.c11
-rw-r--r--net/ipv4/tcp_rate.c12
2 files changed, 21 insertions, 2 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
diff --git a/net/ipv4/tcp_rate.c b/net/ipv4/tcp_rate.c
index 52ff84be59ab..9be1581a5a08 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,
149 * for connections suffer heavy or prolonged losses. 149 * for connections suffer heavy or prolonged losses.
150 */ 150 */
151 if (unlikely(rs->interval_us < tcp_min_rtt(tp))) { 151 if (unlikely(rs->interval_us < tcp_min_rtt(tp))) {
152 rs->interval_us = -1;
153 if (!rs->is_retrans) 152 if (!rs->is_retrans)
154 pr_debug("tcp rate: %ld %d %u %u %u\n", 153 pr_debug("tcp rate: %ld %d %u %u %u\n",
155 rs->interval_us, rs->delivered, 154 rs->interval_us, rs->delivered,
156 inet_csk(sk)->icsk_ca_state, 155 inet_csk(sk)->icsk_ca_state,
157 tp->rx_opt.sack_ok, tcp_min_rtt(tp)); 156 tp->rx_opt.sack_ok, tcp_min_rtt(tp));
157 rs->interval_us = -1;
158 return;
159 }
160
161 /* Record the last non-app-limited or the highest app-limited bw */
162 if (!rs->is_app_limited ||
163 ((u64)rs->delivered * tp->rate_interval_us >=
164 (u64)tp->rate_delivered * rs->interval_us)) {
165 tp->rate_delivered = rs->delivered;
166 tp->rate_interval_us = rs->interval_us;
167 tp->rate_app_limited = rs->is_app_limited;
158 } 168 }
159} 169}
160 170