Commit 5040011d authored by David Howells's avatar David Howells
Browse files

rxrpc: Make the local endpoint hold a ref on a connected call



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: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent 8a758d98
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -148,6 +148,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  ") \
@@ -160,6 +161,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    ") \
@@ -173,6 +175,7 @@
	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_disconnected,		"SEE disconn ") \
	EM(rxrpc_call_see_distribute_error,	"SEE dist-err") \
	EM(rxrpc_call_see_input,		"SEE input   ") \
	EM(rxrpc_call_see_release,		"SEE release ") \
+2 −0
Original line number Diff line number Diff line
@@ -453,6 +453,8 @@ void rxrpc_incoming_call(struct rxrpc_sock *rx,
		BUG();
	}

	rxrpc_get_call(call, rxrpc_call_get_io_thread);

	/* Set the channel for this call.  We don't get channel_lock as we're
	 * only defending against the data_ready handler (which we're called
	 * from) and the RESPONSE packet parser (which is only really
+3 −3
Original line number Diff line number Diff line
@@ -725,8 +725,11 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,

	rxrpc_discard_expired_client_conns(&rxnet->client_conn_reaper);

	rxrpc_get_call(call, rxrpc_call_get_io_thread);

	bundle = rxrpc_prep_call(rx, call, cp, srx, gfp);
	if (IS_ERR(bundle)) {
		rxrpc_put_call(call, rxrpc_call_get_io_thread);
		ret = PTR_ERR(bundle);
		goto out;
	}
@@ -820,7 +823,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call
	_enter("c=%x", call->debug_id);

	spin_lock(&bundle->channel_lock);
	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);

	/* Calls that have never actually been assigned a channel can simply be
	 * discarded.
@@ -912,8 +914,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_bundle *bundle, struct rxrpc_call

out:
	spin_unlock(&bundle->channel_lock);
	_leave("");
	return;
}

/*
+15 −10
Original line number Diff line number Diff line
@@ -178,6 +178,9 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
{
	struct rxrpc_connection *conn = call->conn;

	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
	rxrpc_see_call(call, rxrpc_call_see_disconnected);

	call->peer->cong_ssthresh = call->cong_ssthresh;

	if (!hlist_unhashed(&call->error_link)) {
@@ -186,20 +189,22 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
		spin_unlock(&call->peer->lock);
	}

	if (rxrpc_is_client_call(call))
		return rxrpc_disconnect_client_call(conn->bundle, call);

	if (rxrpc_is_client_call(call)) {
		rxrpc_disconnect_client_call(conn->bundle, call);
	} else {
		spin_lock(&conn->bundle->channel_lock);
		__rxrpc_disconnect_call(conn, call);
		spin_unlock(&conn->bundle->channel_lock);

	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
		conn->idle_timestamp = jiffies;
		if (atomic_dec_and_test(&conn->active))
			rxrpc_set_service_reap_timer(conn->rxnet,
						     jiffies + rxrpc_connection_expiry);
	}

	rxrpc_put_call(call, rxrpc_call_put_io_thread);
}

/*
 * Queue a connection's work processor, getting a ref to pass to the work
 * queue.