Skip to content

Commit fc9de52

Browse files
dhowellskuba-moo
authored andcommitted
rxrpc: Fix missing locking causing hanging calls
If a call gets aborted (e.g. because kafs saw a signal) between it being queued for connection and the I/O thread picking up the call, the abort will be prioritised over the connection and it will be removed from local->new_client_calls by rxrpc_disconnect_client_call() without a lock being held. This may cause other calls on the list to disappear if a race occurs. Fix this by taking the client_call_lock when removing a call from whatever list its ->wait_link happens to be on. Signed-off-by: David Howells <dhowells@redhat.com> cc: linux-afs@lists.infradead.org Reported-by: Marc Dionne <marc.dionne@auristor.com> Fixes: 9d35d88 ("rxrpc: Move client call connection to the I/O thread") Link: https://patch.msgid.link/726660.1730898202@warthog.procyon.org.uk Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent de88df0 commit fc9de52

File tree

2 files changed

+5
-0
lines changed

2 files changed

+5
-0
lines changed

include/trace/events/rxrpc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@
287287
EM(rxrpc_call_see_input, "SEE input ") \
288288
EM(rxrpc_call_see_release, "SEE release ") \
289289
EM(rxrpc_call_see_userid_exists, "SEE u-exists") \
290+
EM(rxrpc_call_see_waiting_call, "SEE q-conn ") \
290291
E_(rxrpc_call_see_zap, "SEE zap ")
291292

292293
#define rxrpc_txqueue_traces \

net/rxrpc/conn_client.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ void rxrpc_connect_client_calls(struct rxrpc_local *local)
516516

517517
spin_lock(&local->client_call_lock);
518518
list_move_tail(&call->wait_link, &bundle->waiting_calls);
519+
rxrpc_see_call(call, rxrpc_call_see_waiting_call);
519520
spin_unlock(&local->client_call_lock);
520521

521522
if (rxrpc_bundle_has_space(bundle))
@@ -586,7 +587,10 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call
586587
_debug("call is waiting");
587588
ASSERTCMP(call->call_id, ==, 0);
588589
ASSERT(!test_bit(RXRPC_CALL_EXPOSED, &call->flags));
590+
/* May still be on ->new_client_calls. */
591+
spin_lock(&local->client_call_lock);
589592
list_del_init(&call->wait_link);
593+
spin_unlock(&local->client_call_lock);
590594
return;
591595
}
592596

0 commit comments

Comments
 (0)