]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
rxrpc: Fix handling of received connection abort
authorDavid Howells <dhowells@redhat.com>
Wed, 4 Dec 2024 07:46:30 +0000 (07:46 +0000)
committerJakub Kicinski <kuba@kernel.org>
Mon, 9 Dec 2024 21:48:23 +0000 (13:48 -0800)
Fix the handling of a connection abort that we've received.  Though the
abort is at the connection level, it needs propagating to the calls on that
connection.  Whilst the propagation bit is performed, the calls aren't then
woken up to go and process their termination, and as no further input is
forthcoming, they just hang.

Also add some tracing for the logging of connection aborts.

Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20241204074710.990092-3-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/trace/events/rxrpc.h
net/rxrpc/conn_event.c

index d03e0bd8c028b56357220e8995a444bb66c584d0..27c23873c8811517495166c8fe8213494815d4a4 100644 (file)
 #define rxrpc_call_poke_traces \
        EM(rxrpc_call_poke_abort,               "Abort")        \
        EM(rxrpc_call_poke_complete,            "Compl")        \
+       EM(rxrpc_call_poke_conn_abort,          "Conn-abort")   \
        EM(rxrpc_call_poke_error,               "Error")        \
        EM(rxrpc_call_poke_idle,                "Idle")         \
        EM(rxrpc_call_poke_set_timeout,         "Set-timo")     \
        EM(rxrpc_call_see_activate_client,      "SEE act-clnt") \
        EM(rxrpc_call_see_connect_failed,       "SEE con-fail") \
        EM(rxrpc_call_see_connected,            "SEE connect ") \
+       EM(rxrpc_call_see_conn_abort,           "SEE conn-abt") \
        EM(rxrpc_call_see_disconnected,         "SEE disconn ") \
        EM(rxrpc_call_see_distribute_error,     "SEE dist-err") \
        EM(rxrpc_call_see_input,                "SEE input   ") \
@@ -981,6 +983,29 @@ TRACE_EVENT(rxrpc_rx_abort,
                      __entry->abort_code)
            );
 
+TRACE_EVENT(rxrpc_rx_conn_abort,
+           TP_PROTO(const struct rxrpc_connection *conn, const struct sk_buff *skb),
+
+           TP_ARGS(conn, skb),
+
+           TP_STRUCT__entry(
+                   __field(unsigned int,       conn)
+                   __field(rxrpc_serial_t,     serial)
+                   __field(u32,                abort_code)
+                            ),
+
+           TP_fast_assign(
+                   __entry->conn = conn->debug_id;
+                   __entry->serial = rxrpc_skb(skb)->hdr.serial;
+                   __entry->abort_code = skb->priority;
+                          ),
+
+           TP_printk("C=%08x ABORT %08x ac=%d",
+                     __entry->conn,
+                     __entry->serial,
+                     __entry->abort_code)
+           );
+
 TRACE_EVENT(rxrpc_rx_challenge,
            TP_PROTO(struct rxrpc_connection *conn, rxrpc_serial_t serial,
                     u32 version, u32 nonce, u32 min_level),
index 598b4ee389fc1ea92880ec27b7a2705f7b85e651..2a1396cd892f30aef1a6077c53b51f463392085b 100644 (file)
@@ -63,11 +63,12 @@ int rxrpc_abort_conn(struct rxrpc_connection *conn, struct sk_buff *skb,
 /*
  * Mark a connection as being remotely aborted.
  */
-static bool rxrpc_input_conn_abort(struct rxrpc_connection *conn,
+static void rxrpc_input_conn_abort(struct rxrpc_connection *conn,
                                   struct sk_buff *skb)
 {
-       return rxrpc_set_conn_aborted(conn, skb, skb->priority, -ECONNABORTED,
-                                     RXRPC_CALL_REMOTELY_ABORTED);
+       trace_rxrpc_rx_conn_abort(conn, skb);
+       rxrpc_set_conn_aborted(conn, skb, skb->priority, -ECONNABORTED,
+                              RXRPC_CALL_REMOTELY_ABORTED);
 }
 
 /*
@@ -202,11 +203,14 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn)
 
        for (i = 0; i < RXRPC_MAXCALLS; i++) {
                call = conn->channels[i].call;
-               if (call)
+               if (call) {
+                       rxrpc_see_call(call, rxrpc_call_see_conn_abort);
                        rxrpc_set_call_completion(call,
                                                  conn->completion,
                                                  conn->abort_code,
                                                  conn->error);
+                       rxrpc_poke_call(call, rxrpc_call_poke_conn_abort);
+               }
        }
 
        _leave("");