This patch implements the TLP restart modification (TLPR). When data is ACKed, and TLP's PTO timer is restarted, the time elapsed since the last outstanding segment was transmitted is subtracted from the calculated RTO value to not unnecessarily delay loss probes.
Signed-off-by: Per Hurtig <per.hur...@kau.se> --- include/net/tcp.h | 2 +- net/ipv4/tcp_input.c | 2 +- net/ipv4/tcp_output.c | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index bf98768..8ac4118 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -566,7 +566,7 @@ void tcp_push_one(struct sock *, unsigned int mss_now); void tcp_send_ack(struct sock *sk); void tcp_send_delayed_ack(struct sock *sk); void tcp_send_loss_probe(struct sock *sk); -bool tcp_schedule_loss_probe(struct sock *sk); +bool tcp_schedule_loss_probe(struct sock *sk, bool restart); /* tcp_input.c */ void tcp_resume_early_retransmit(struct sock *sk); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 66e0425..28d3b21 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3655,7 +3655,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) } if (icsk->icsk_pending == ICSK_TIME_RETRANS) - tcp_schedule_loss_probe(sk); + tcp_schedule_loss_probe(sk, true); tcp_update_pacing_rate(sk); return 1; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index cb7ca56..752db3d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -2135,7 +2135,7 @@ repair: /* Send one loss probe per tail loss episode. */ if (push_one != 2) - tcp_schedule_loss_probe(sk); + tcp_schedule_loss_probe(sk, false); is_cwnd_limited |= (tcp_packets_in_flight(tp) >= tp->snd_cwnd); tcp_cwnd_validate(sk, is_cwnd_limited); return false; @@ -2143,10 +2143,11 @@ repair: return !tp->packets_out && tcp_send_head(sk); } -bool tcp_schedule_loss_probe(struct sock *sk) +bool tcp_schedule_loss_probe(struct sock *sk, bool restart) { struct inet_connection_sock *icsk = inet_csk(sk); struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb = tcp_write_queue_head(sk); u32 timeout, tlp_time_stamp, rto_time_stamp; u32 rtt = usecs_to_jiffies(tp->srtt_us >> 3); @@ -2186,6 +2187,13 @@ bool tcp_schedule_loss_probe(struct sock *sk) if (tp->packets_out == 1) timeout = max_t(u32, timeout, (rtt + (rtt >> 1) + TCP_DELACK_MAX)); + if (sysctl_tcp_timer_restart > 1 && restart && skb) { + const u32 rto_time_stamp = tcp_skb_timestamp(skb); + s32 delta = (s32)(tcp_time_stamp - rto_time_stamp); + + if (delta > 0 && timeout > delta) + timeout -= delta; + } timeout = max_t(u32, timeout, msecs_to_jiffies(10)); /* If RTO is shorter, just schedule TLP in its place. */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html