[PATCH net-next 27/32] rxrpc: Make the local endpoint hold a ref on a connected call

From: David Howells
Date: Tue Dec 06 2022 - 11:07:42 EST


Make the local endpoint and it's I/O thread hold a reference on a connected
call until that call is disconnected. Without this, we're reliant on
either the AF_RXRPC socket to hold a ref (which is dropped when the call is
released) or a queued work item to hold a ref (the work item is being
replaced with the I/O thread).

Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
cc: Marc Dionne <marc.dionne@xxxxxxxxxxxx>
cc: linux-afs@xxxxxxxxxxxxxxxxxxx
---

include/trace/events/rxrpc.h | 2 ++
net/rxrpc/conn_client.c | 4 ++++
2 files changed, 6 insertions(+)

diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h
index 4d5eb08025c0..81182efca327 100644
--- a/include/trace/events/rxrpc.h
+++ b/include/trace/events/rxrpc.h
@@ -257,6 +257,7 @@
E_(rxrpc_client_to_idle, "->Idle")

#define rxrpc_call_traces \
+ EM(rxrpc_call_get_io_thread, "GET iothread") \
EM(rxrpc_call_get_input, "GET input ") \
EM(rxrpc_call_get_kernel_service, "GET krnl-srv") \
EM(rxrpc_call_get_notify_socket, "GET notify ") \
@@ -269,6 +270,7 @@
EM(rxrpc_call_new_prealloc_service, "NEW prealloc") \
EM(rxrpc_call_put_discard_prealloc, "PUT disc-pre") \
EM(rxrpc_call_put_discard_error, "PUT disc-err") \
+ EM(rxrpc_call_put_io_thread, "PUT iothread") \
EM(rxrpc_call_put_input, "PUT input ") \
EM(rxrpc_call_put_kernel, "PUT kernel ") \
EM(rxrpc_call_put_poke, "PUT poke ") \
diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c
index 8e3e0ffa4417..26b0ad38f91b 100644
--- a/net/rxrpc/conn_client.c
+++ b/net/rxrpc/conn_client.c
@@ -718,8 +718,11 @@ int rxrpc_connect_call(struct rxrpc_call *call, gfp_t gfp)

rxrpc_discard_expired_client_conns(&rxnet->client_conn_reaper);

+ rxrpc_get_call(call, rxrpc_call_get_io_thread);
+
bundle = rxrpc_prep_call(call, gfp);
if (IS_ERR(bundle)) {
+ rxrpc_put_call(call, rxrpc_call_get_io_thread);
ret = PTR_ERR(bundle);
goto out;
}
@@ -902,6 +905,7 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call

out:
spin_unlock(&bundle->channel_lock);
+ rxrpc_put_call(call, rxrpc_call_put_io_thread);
_leave("");
return;
}