Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18684bb9 authored by David Howells's avatar David Howells Committed by Greg Kroah-Hartman
Browse files

rxrpc: Adjust retransmission backoff



[ Upstream commit 2c13c05c5ff4b9fc907b07f7311821910ebaaf8a ]

Improve retransmission backoff by only backing off when we retransmit data
packets rather than when we set the lost ack timer.

To this end:

 (1) In rxrpc_resend(), use rxrpc_get_rto_backoff() when setting the
     retransmission timer and only tell it that we are retransmitting if we
     actually have things to retransmit.

     Note that it's possible for the retransmission algorithm to race with
     the processing of a received ACK, so we may see no packets needing
     retransmission.

 (2) In rxrpc_send_data_packet(), don't bump the backoff when setting the
     ack_lost_at timer, as it may then get bumped twice.

With this, when looking at one particular packet, the retransmission
intervals were seen to be 1.5ms, 2ms, 3ms, 5ms, 9ms, 17ms, 33ms, 71ms,
136ms, 264ms, 544ms, 1.088s, 2.1s, 4.2s and 8.3s.

Fixes: c410bf01933e ("rxrpc: Fix the excessive initial retransmission timeout")
Suggested-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarMarc Dionne <marc.dionne@auristor.com>
Tested-by: default avatarMarc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://lore.kernel.org/r/164138117069.2023386.17446904856843997127.stgit@warthog.procyon.org.uk/


Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent f39027cb
Loading
Loading
Loading
Loading
+3 −5
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ static void rxrpc_congestion_timeout(struct rxrpc_call *call)
static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
{
	struct sk_buff *skb;
	unsigned long resend_at, rto_j;
	unsigned long resend_at;
	rxrpc_seq_t cursor, seq, top;
	ktime_t now, max_age, oldest, ack_ts;
	int ix;
@@ -165,10 +165,8 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)

	_enter("{%d,%d}", call->tx_hard_ack, call->tx_top);

	rto_j = call->peer->rto_j;

	now = ktime_get_real();
	max_age = ktime_sub(now, jiffies_to_usecs(rto_j));
	max_age = ktime_sub(now, jiffies_to_usecs(call->peer->rto_j));

	spin_lock_bh(&call->lock);

@@ -213,7 +211,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
	}

	resend_at = nsecs_to_jiffies(ktime_to_ns(ktime_sub(now, oldest)));
	resend_at += jiffies + rto_j;
	resend_at += jiffies + rxrpc_get_rto_backoff(call->peer, retrans);
	WRITE_ONCE(call->resend_at, resend_at);

	if (unacked)
+1 −1
Original line number Diff line number Diff line
@@ -426,7 +426,7 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct sk_buff *skb,
			if (call->peer->rtt_count > 1) {
				unsigned long nowj = jiffies, ack_lost_at;

				ack_lost_at = rxrpc_get_rto_backoff(call->peer, retrans);
				ack_lost_at = rxrpc_get_rto_backoff(call->peer, false);
				ack_lost_at += nowj;
				WRITE_ONCE(call->ack_lost_at, ack_lost_at);
				rxrpc_reduce_call_timer(call, ack_lost_at, nowj,