Commit fa3492ab authored by David Howells's avatar David Howells
Browse files

rxrpc: Trace rxrpc_bundle refcount



Add a tracepoint for the rxrpc_bundle refcounting.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent cb0fc0c9
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -81,6 +81,15 @@
	EM(rxrpc_peer_put_input_error,		"PUT inpt-err") \
	E_(rxrpc_peer_put_keepalive,		"PUT keepaliv")

#define rxrpc_bundle_traces \
	EM(rxrpc_bundle_free,			"FREE        ") \
	EM(rxrpc_bundle_get_client_call,	"GET clt-call") \
	EM(rxrpc_bundle_get_client_conn,	"GET clt-conn") \
	EM(rxrpc_bundle_get_service_conn,	"GET svc-conn") \
	EM(rxrpc_bundle_put_conn,		"PUT conn    ") \
	EM(rxrpc_bundle_put_discard,		"PUT discard ") \
	E_(rxrpc_bundle_new,			"NEW         ")

#define rxrpc_conn_traces \
	EM(rxrpc_conn_free,			"FREE        ") \
	EM(rxrpc_conn_get_activate_call,	"GET act-call") \
@@ -361,6 +370,7 @@
#define EM(a, b) a,
#define E_(a, b) a

enum rxrpc_bundle_trace		{ rxrpc_bundle_traces } __mode(byte);
enum rxrpc_call_trace		{ rxrpc_call_traces } __mode(byte);
enum rxrpc_client_trace		{ rxrpc_client_traces } __mode(byte);
enum rxrpc_congest_change	{ rxrpc_congest_changes } __mode(byte);
@@ -390,6 +400,7 @@ enum rxrpc_txqueue_trace { rxrpc_txqueue_traces } __mode(byte);
#define EM(a, b) TRACE_DEFINE_ENUM(a);
#define E_(a, b) TRACE_DEFINE_ENUM(a);

rxrpc_bundle_traces;
rxrpc_call_traces;
rxrpc_client_traces;
rxrpc_congest_changes;
@@ -467,6 +478,29 @@ TRACE_EVENT(rxrpc_peer,
		      __entry->ref)
	    );

TRACE_EVENT(rxrpc_bundle,
	    TP_PROTO(unsigned int bundle_debug_id, int ref, enum rxrpc_bundle_trace why),

	    TP_ARGS(bundle_debug_id, ref, why),

	    TP_STRUCT__entry(
		    __field(unsigned int,	bundle		)
		    __field(int,		ref		)
		    __field(int,		why		)
			     ),

	    TP_fast_assign(
		    __entry->bundle = bundle_debug_id;
		    __entry->ref = ref;
		    __entry->why = why;
			   ),

	    TP_printk("CB=%08x %s r=%d",
		      __entry->bundle,
		      __print_symbolic(__entry->why, rxrpc_bundle_traces),
		      __entry->ref)
	    );

TRACE_EVENT(rxrpc_conn,
	    TP_PROTO(unsigned int conn_debug_id, int ref, enum rxrpc_conn_trace why),

+2 −2
Original line number Diff line number Diff line
@@ -875,8 +875,8 @@ extern unsigned long rxrpc_conn_idle_client_fast_expiry;
extern struct idr rxrpc_client_conn_ids;

void rxrpc_destroy_client_conn_ids(void);
struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *);
void rxrpc_put_bundle(struct rxrpc_bundle *);
struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
void rxrpc_put_bundle(struct rxrpc_bundle *, enum rxrpc_bundle_trace);
int rxrpc_connect_call(struct rxrpc_sock *, struct rxrpc_call *,
		       struct rxrpc_conn_parameters *, struct sockaddr_rxrpc *,
		       gfp_t);
+16 −11
Original line number Diff line number Diff line
@@ -133,31 +133,36 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_conn_parameters *cp,
		atomic_set(&bundle->active, 1);
		spin_lock_init(&bundle->channel_lock);
		INIT_LIST_HEAD(&bundle->waiting_calls);
		trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_new);
	}
	return bundle;
}

struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle)
struct rxrpc_bundle *rxrpc_get_bundle(struct rxrpc_bundle *bundle,
				      enum rxrpc_bundle_trace why)
{
	refcount_inc(&bundle->ref);
	int r;

	__refcount_inc(&bundle->ref, &r);
	trace_rxrpc_bundle(bundle->debug_id, r + 1, why);
	return bundle;
}

static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
{
	trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_free);
	rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle);
	kfree(bundle);
}

void rxrpc_put_bundle(struct rxrpc_bundle *bundle)
void rxrpc_put_bundle(struct rxrpc_bundle *bundle, enum rxrpc_bundle_trace why)
{
	unsigned int d = bundle->debug_id;
	unsigned int id = bundle->debug_id;
	bool dead;
	int r;

	dead = __refcount_dec_and_test(&bundle->ref, &r);

	_debug("PUT B=%x %d", d, r - 1);
	trace_rxrpc_bundle(id, r - 1, why);
	if (dead)
		rxrpc_free_bundle(bundle);
}
@@ -206,7 +211,7 @@ rxrpc_alloc_client_connection(struct rxrpc_bundle *bundle, gfp_t gfp)
	list_add_tail(&conn->proc_link, &rxnet->conn_proc_list);
	write_unlock(&rxnet->conn_lock);

	rxrpc_get_bundle(bundle);
	rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_conn);
	rxrpc_get_peer(conn->peer, rxrpc_peer_get_client_conn);
	rxrpc_get_local(conn->local, rxrpc_local_get_client_conn);
	key_get(conn->key);
@@ -342,7 +347,7 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
	candidate->debug_id = atomic_inc_return(&rxrpc_bundle_id);
	rb_link_node(&candidate->local_node, parent, pp);
	rb_insert_color(&candidate->local_node, &local->client_bundles);
	rxrpc_get_bundle(candidate);
	rxrpc_get_bundle(candidate, rxrpc_bundle_get_client_call);
	spin_unlock(&local->client_bundles_lock);
	_leave(" = %u [new]", candidate->debug_id);
	return candidate;
@@ -350,7 +355,7 @@ static struct rxrpc_bundle *rxrpc_look_up_bundle(struct rxrpc_conn_parameters *c
found_bundle_free:
	rxrpc_free_bundle(candidate);
found_bundle:
	rxrpc_get_bundle(bundle);
	rxrpc_get_bundle(bundle, rxrpc_bundle_get_client_call);
	atomic_inc(&bundle->active);
	spin_unlock(&local->client_bundles_lock);
	_leave(" = %u [found]", bundle->debug_id);
@@ -740,7 +745,7 @@ int rxrpc_connect_call(struct rxrpc_sock *rx,

out_put_bundle:
	rxrpc_deactivate_bundle(bundle);
	rxrpc_put_bundle(bundle);
	rxrpc_put_bundle(bundle, rxrpc_bundle_get_client_call);
out:
	_leave(" = %d", ret);
	return ret;
@@ -958,7 +963,7 @@ static void rxrpc_deactivate_bundle(struct rxrpc_bundle *bundle)

		spin_unlock(&local->client_bundles_lock);
		if (need_put)
			rxrpc_put_bundle(bundle);
			rxrpc_put_bundle(bundle, rxrpc_bundle_put_discard);
	}
}

+1 −1
Original line number Diff line number Diff line
@@ -363,7 +363,7 @@ static void rxrpc_destroy_connection(struct rcu_head *rcu)

	conn->security->clear(conn);
	key_put(conn->key);
	rxrpc_put_bundle(conn->bundle);
	rxrpc_put_bundle(conn->bundle, rxrpc_bundle_put_conn);
	rxrpc_put_peer(conn->peer, rxrpc_peer_put_conn);

	if (atomic_dec_and_test(&conn->local->rxnet->nr_conns))
+2 −1
Original line number Diff line number Diff line
@@ -133,7 +133,8 @@ struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxn
		 */
		conn->state = RXRPC_CONN_SERVICE_PREALLOC;
		refcount_set(&conn->ref, 2);
		conn->bundle = rxrpc_get_bundle(&rxrpc_service_dummy_bundle);
		conn->bundle = rxrpc_get_bundle(&rxrpc_service_dummy_bundle,
						rxrpc_bundle_get_service_conn);

		atomic_inc(&rxnet->nr_conns);
		write_lock(&rxnet->conn_lock);