rxrpc: Fix RTT determination to use any ACK as a source
authorDavid Howells <dhowells@redhat.com>
Thu, 16 Nov 2023 13:12:58 +0000 (13:12 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 3 Dec 2023 06:33:02 +0000 (07:33 +0100)
[ Upstream commit 3798680f2fbbe0ca3ab6138b34e0d161c36497ee ]

Fix RTT determination to be able to use any type of ACK as the response
from which RTT can be calculated provided its ack.serial is non-zero and
matches the serial number of an outgoing DATA or ACK packet.  This
shouldn't be limited to REQUESTED-type ACKs as these can have other types
substituted for them for things like duplicate or out-of-order packets.

Fixes: 4700c4d80b7b ("rxrpc: Fix loss of RTT samples due to interposed ACK")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: linux-afs@lists.infradead.org
cc: netdev@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/trace/events/rxrpc.h
net/rxrpc/input.c

index 4c53a5e..f7e537f 100644 (file)
        E_(rxrpc_rtt_tx_ping,                   "PING")
 
 #define rxrpc_rtt_rx_traces \
-       EM(rxrpc_rtt_rx_cancel,                 "CNCL") \
+       EM(rxrpc_rtt_rx_other_ack,              "OACK") \
        EM(rxrpc_rtt_rx_obsolete,               "OBSL") \
        EM(rxrpc_rtt_rx_lost,                   "LOST") \
        EM(rxrpc_rtt_rx_ping_response,          "PONG") \
index 030d64f..3f9594d 100644 (file)
@@ -643,12 +643,8 @@ static void rxrpc_complete_rtt_probe(struct rxrpc_call *call,
                        clear_bit(i + RXRPC_CALL_RTT_PEND_SHIFT, &call->rtt_avail);
                        smp_mb(); /* Read data before setting avail bit */
                        set_bit(i, &call->rtt_avail);
-                       if (type != rxrpc_rtt_rx_cancel)
-                               rxrpc_peer_add_rtt(call, type, i, acked_serial, ack_serial,
-                                                  sent_at, resp_time);
-                       else
-                               trace_rxrpc_rtt_rx(call, rxrpc_rtt_rx_cancel, i,
-                                                  orig_serial, acked_serial, 0, 0);
+                       rxrpc_peer_add_rtt(call, type, i, acked_serial, ack_serial,
+                                          sent_at, resp_time);
                        matched = true;
                }
 
@@ -801,20 +797,21 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb)
                           summary.ack_reason, nr_acks);
        rxrpc_inc_stat(call->rxnet, stat_rx_acks[ack.reason]);
 
-       switch (ack.reason) {
-       case RXRPC_ACK_PING_RESPONSE:
-               rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial,
-                                        rxrpc_rtt_rx_ping_response);
-               break;
-       case RXRPC_ACK_REQUESTED:
-               rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial,
-                                        rxrpc_rtt_rx_requested_ack);
-               break;
-       default:
-               if (acked_serial != 0)
+       if (acked_serial != 0) {
+               switch (ack.reason) {
+               case RXRPC_ACK_PING_RESPONSE:
                        rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial,
-                                                rxrpc_rtt_rx_cancel);
-               break;
+                                                rxrpc_rtt_rx_ping_response);
+                       break;
+               case RXRPC_ACK_REQUESTED:
+                       rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial,
+                                                rxrpc_rtt_rx_requested_ack);
+                       break;
+               default:
+                       rxrpc_complete_rtt_probe(call, skb->tstamp, acked_serial, ack_serial,
+                                                rxrpc_rtt_rx_other_ack);
+                       break;
+               }
        }
 
        if (ack.reason == RXRPC_ACK_PING) {