mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 12:14:10 +08:00
rxrpc: Fix missing locking causing hanging calls
[ Upstream commitfc9de52de3
] 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:9d35d880e0
("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
faa530f004
commit
b1fdb0bb3b
@ -287,6 +287,7 @@
|
|||||||
EM(rxrpc_call_see_input, "SEE input ") \
|
EM(rxrpc_call_see_input, "SEE input ") \
|
||||||
EM(rxrpc_call_see_release, "SEE release ") \
|
EM(rxrpc_call_see_release, "SEE release ") \
|
||||||
EM(rxrpc_call_see_userid_exists, "SEE u-exists") \
|
EM(rxrpc_call_see_userid_exists, "SEE u-exists") \
|
||||||
|
EM(rxrpc_call_see_waiting_call, "SEE q-conn ") \
|
||||||
E_(rxrpc_call_see_zap, "SEE zap ")
|
E_(rxrpc_call_see_zap, "SEE zap ")
|
||||||
|
|
||||||
#define rxrpc_txqueue_traces \
|
#define rxrpc_txqueue_traces \
|
||||||
|
@ -516,6 +516,7 @@ void rxrpc_connect_client_calls(struct rxrpc_local *local)
|
|||||||
|
|
||||||
spin_lock(&local->client_call_lock);
|
spin_lock(&local->client_call_lock);
|
||||||
list_move_tail(&call->wait_link, &bundle->waiting_calls);
|
list_move_tail(&call->wait_link, &bundle->waiting_calls);
|
||||||
|
rxrpc_see_call(call, rxrpc_call_see_waiting_call);
|
||||||
spin_unlock(&local->client_call_lock);
|
spin_unlock(&local->client_call_lock);
|
||||||
|
|
||||||
if (rxrpc_bundle_has_space(bundle))
|
if (rxrpc_bundle_has_space(bundle))
|
||||||
@ -586,7 +587,10 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call
|
|||||||
_debug("call is waiting");
|
_debug("call is waiting");
|
||||||
ASSERTCMP(call->call_id, ==, 0);
|
ASSERTCMP(call->call_id, ==, 0);
|
||||||
ASSERT(!test_bit(RXRPC_CALL_EXPOSED, &call->flags));
|
ASSERT(!test_bit(RXRPC_CALL_EXPOSED, &call->flags));
|
||||||
|
/* May still be on ->new_client_calls. */
|
||||||
|
spin_lock(&local->client_call_lock);
|
||||||
list_del_init(&call->wait_link);
|
list_del_init(&call->wait_link);
|
||||||
|
spin_unlock(&local->client_call_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user