From 1adddaf9643a3572de22e73e95f2a6c29b4636d5 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson Date: Sat, 18 Jun 2011 11:58:57 +0100 Subject: [PATCH] rx: Add Karn-style backoffs to RX retransmits When we retransmit a packet, we may be doing so because the RTT of the connection has grown dramatically larger than earlier within the call. However, RX doesn't permit all ACKs to retransmitted packets to be counted within the RTT calculation. So, adopt the same approach as Karn developed for TCP, and as described in detail in RFC2988. When a retransmit event occurs, backoff the connection RTT by doubling its value, and hold at this doubled value until either another retransmit occurs (in which case we back off again, up to a predetermined ceiling), or we receive an ACK packet which we can use within the RTT calculation, in which case we drop back down to the newly measured value. This change replaces the per-packet backoff strategy originally implemented in RX (which, whilst allowing resent packets more chance of arriving, doesn't help with computing a correct RTT). Reviewed-on: http://gerrit.openafs.org/4865 Reviewed-by: Derrick Brashear Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman Tested-by: BuildBot (cherry picked from commit 0118fb5387e656e515d78d48497a48f1e04a1152) Change-Id: I697eac14f9b4be5c8726f0386e516cb49995f665 Reviewed-on: http://gerrit.openafs.org/4937 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/rx/rx.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/rx/rx.c b/src/rx/rx.c index bdc1d44b6..538ce706f 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -5950,6 +5950,7 @@ rxi_Resend(struct rxevent *event, void *arg0, void *arg1, int istack) { struct rx_call *call = arg0; struct rx_packet *p, *nxp; + struct clock maxTimeout = { 60, 0 }; MUTEX_ENTER(&call->lock); /* Make sure that the event pointer is removed from the call @@ -5978,6 +5979,16 @@ rxi_Resend(struct rxevent *event, void *arg0, void *arg1, int istack) if (!(p->flags & RX_PKTFLAG_ACKED)) p->flags &= ~RX_PKTFLAG_SENT; } + + /* We're resending, so we double the timeout of the call. This will be + * dropped back down by the first successful ACK that we receive. + * + * We apply a maximum value here of 60 second + */ + clock_Add(&call->rto, &call->rto); + if (clock_Gt(&call->rto, &maxTimeout)) + call->rto = maxTimeout; + rxi_Start(call, istack); out: -- 2.39.5