]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
rxrpc: Fix the rxrpc_connection attend queue handling
authorDavid Howells <dhowells@redhat.com>
Mon, 3 Feb 2025 11:03:04 +0000 (11:03 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 4 Feb 2025 14:30:28 +0000 (15:30 +0100)
The rxrpc_connection attend queue is never used because conn::attend_link
is never initialised and so is always NULL'd out and thus always appears to
be busy.  This requires the following fix:

 (1) Fix this the attend queue problem by initialising conn::attend_link.

And, consequently, two further fixes for things masked by the above bug:

 (2) Fix rxrpc_input_conn_event() to handle being invoked with a NULL
     sk_buff pointer - something that can now happen with the above change.

 (3) Fix the RXRPC_SKB_MARK_SERVICE_CONN_SECURED message to carry a pointer
     to the connection and a ref on it.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Simon Horman <horms@kernel.org>
cc: linux-afs@lists.infradead.org
cc: netdev@vger.kernel.org
Fixes: f2cce89a074e ("rxrpc: Implement a mechanism to send an event notification to a connection")
Link: https://patch.msgid.link/20250203110307.7265-3-dhowells@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/trace/events/rxrpc.h
net/rxrpc/conn_event.c
net/rxrpc/conn_object.c

index 2f119d18a061fe6706456e629ccfdf5282bf98be..cad50d91077efa06c202e6ff9b308ccaa9699f01 100644 (file)
        EM(rxrpc_conn_get_conn_input,           "GET inp-conn") \
        EM(rxrpc_conn_get_idle,                 "GET idle    ") \
        EM(rxrpc_conn_get_poke_abort,           "GET pk-abort") \
+       EM(rxrpc_conn_get_poke_secured,         "GET secured ") \
        EM(rxrpc_conn_get_poke_timer,           "GET poke    ") \
        EM(rxrpc_conn_get_service_conn,         "GET svc-conn") \
        EM(rxrpc_conn_new_client,               "NEW client  ") \
index 713e04394ceb7b9768fd43e450d118ff69e64a63..74bb49b936cd49947dc3f35e02d587b9bfc734fb 100644 (file)
@@ -272,6 +272,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn,
                         * we've already received the packet, put it on the
                         * front of the queue.
                         */
+                       sp->conn = rxrpc_get_connection(conn, rxrpc_conn_get_poke_secured);
                        skb->mark = RXRPC_SKB_MARK_SERVICE_CONN_SECURED;
                        rxrpc_get_skb(skb, rxrpc_skb_get_conn_secured);
                        skb_queue_head(&conn->local->rx_queue, skb);
@@ -437,14 +438,16 @@ void rxrpc_input_conn_event(struct rxrpc_connection *conn, struct sk_buff *skb)
        if (test_and_clear_bit(RXRPC_CONN_EV_ABORT_CALLS, &conn->events))
                rxrpc_abort_calls(conn);
 
-       switch (skb->mark) {
-       case RXRPC_SKB_MARK_SERVICE_CONN_SECURED:
-               if (conn->state != RXRPC_CONN_SERVICE)
-                       break;
+       if (skb) {
+               switch (skb->mark) {
+               case RXRPC_SKB_MARK_SERVICE_CONN_SECURED:
+                       if (conn->state != RXRPC_CONN_SERVICE)
+                               break;
 
-               for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
-                       rxrpc_call_is_secure(conn->channels[loop].call);
-               break;
+                       for (loop = 0; loop < RXRPC_MAXCALLS; loop++)
+                               rxrpc_call_is_secure(conn->channels[loop].call);
+                       break;
+               }
        }
 
        /* Process delayed ACKs whose time has come. */
index 7eba4d7d9a38027d067377eaca80eae3944f873a..2f1fd1e2e7e488a7aa8579956114312d44952312 100644 (file)
@@ -67,6 +67,7 @@ struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *rxnet,
                INIT_WORK(&conn->destructor, rxrpc_clean_up_connection);
                INIT_LIST_HEAD(&conn->proc_link);
                INIT_LIST_HEAD(&conn->link);
+               INIT_LIST_HEAD(&conn->attend_link);
                mutex_init(&conn->security_lock);
                mutex_init(&conn->tx_data_alloc_lock);
                skb_queue_head_init(&conn->rx_queue);