Commit 1e5d8493 authored by David Howells's avatar David Howells
Browse files

afs: Add a tracepoint for struct afs_addr_list



Add a tracepoint to track the lifetime of the afs_addr_list struct.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
parent aa453bec
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -20,17 +20,39 @@ static void afs_free_addrlist(struct rcu_head *rcu)

	for (i = 0; i < alist->nr_addrs; i++)
		rxrpc_kernel_put_peer(alist->addrs[i].peer);
	trace_afs_alist(alist->debug_id, refcount_read(&alist->usage), afs_alist_trace_free);
	kfree(alist);
}

/*
 * Release an address list.
 */
void afs_put_addrlist(struct afs_addr_list *alist)
void afs_put_addrlist(struct afs_addr_list *alist, enum afs_alist_trace reason)
{
	if (alist && refcount_dec_and_test(&alist->usage))
	unsigned int debug_id;
	bool dead;
	int r;

	if (!alist)
		return;
	debug_id = alist->debug_id;
	dead = __refcount_dec_and_test(&alist->usage, &r);
	trace_afs_alist(debug_id, r - 1, reason);
	if (dead)
		call_rcu(&alist->rcu, afs_free_addrlist);
}

struct afs_addr_list *afs_get_addrlist(struct afs_addr_list *alist, enum afs_alist_trace reason)
{
	int r;

	if (alist) {
		__refcount_inc(&alist->usage, &r);
		trace_afs_alist(alist->debug_id, r + 1, reason);
	}
	return alist;
}

/*
 * Allocate an address list.
 */
@@ -38,6 +60,7 @@ struct afs_addr_list *afs_alloc_addrlist(unsigned int nr, u16 service_id)
{
	struct afs_addr_list *alist;
	unsigned int i;
	static atomic_t debug_id;

	_enter("%u,%u", nr, service_id);

@@ -50,9 +73,11 @@ struct afs_addr_list *afs_alloc_addrlist(unsigned int nr, u16 service_id)

	refcount_set(&alist->usage, 1);
	alist->max_addrs = nr;
	alist->debug_id = atomic_inc_return(&debug_id);

	for (i = 0; i < nr; i++)
		alist->addrs[i].service_id = service_id;
	trace_afs_alist(alist->debug_id, 1, afs_alist_trace_alloc);
	return alist;
}

@@ -217,7 +242,7 @@ struct afs_vlserver_list *afs_parse_text_addrs(struct afs_net *net,
	       problem, p - text, (int)len, (int)len, text);
	ret = -EINVAL;
error:
	afs_put_addrlist(alist);
	afs_put_addrlist(alist, afs_alist_trace_put_parse_error);
error_vl:
	afs_put_vlserverlist(net, vllist);
	return ERR_PTR(ret);
@@ -403,7 +428,7 @@ void afs_end_cursor(struct afs_addr_cursor *ac)
		    ac->index != alist->preferred &&
		    test_bit(ac->alist->preferred, &ac->tried))
			WRITE_ONCE(alist->preferred, ac->index);
		afs_put_addrlist(alist);
		afs_put_addrlist(alist, afs_alist_trace_put_end_cursor);
		ac->alist = NULL;
	}
}
+2 −2
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
	read_lock(&server->fs_lock);
	ac.alist = rcu_dereference_protected(server->addresses,
					     lockdep_is_held(&server->fs_lock));
	afs_get_addrlist(ac.alist);
	afs_get_addrlist(ac.alist, afs_alist_trace_get_probe);
	read_unlock(&server->fs_lock);

	server->probed_at = jiffies;
@@ -226,7 +226,7 @@ void afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server,
			afs_fs_probe_not_done(net, server, &ac);
	}

	afs_put_addrlist(ac.alist);
	afs_put_addrlist(ac.alist, afs_alist_trace_put_probe);
}

/*
+3 −7
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ struct afs_addr_list {
	struct rcu_head		rcu;
	refcount_t		usage;
	u32			version;	/* Version */
	unsigned int		debug_id;
	unsigned char		max_addrs;
	unsigned char		nr_addrs;
	unsigned char		preferred;	/* Preferred address */
@@ -969,14 +970,9 @@ static inline bool afs_is_folio_dirty_mmapped(unsigned long priv)
/*
 * addr_list.c
 */
static inline struct afs_addr_list *afs_get_addrlist(struct afs_addr_list *alist)
{
	if (alist)
		refcount_inc(&alist->usage);
	return alist;
}
struct afs_addr_list *afs_get_addrlist(struct afs_addr_list *alist, enum afs_alist_trace reason);
extern struct afs_addr_list *afs_alloc_addrlist(unsigned int nr, u16 service_id);
extern void afs_put_addrlist(struct afs_addr_list *);
extern void afs_put_addrlist(struct afs_addr_list *alist, enum afs_alist_trace reason);
extern struct afs_vlserver_list *afs_parse_text_addrs(struct afs_net *,
						      const char *, size_t, char,
						      unsigned short, unsigned short);
+2 −2
Original line number Diff line number Diff line
@@ -484,7 +484,7 @@ bool afs_select_fileserver(struct afs_operation *op)
	read_lock(&server->fs_lock);
	alist = rcu_dereference_protected(server->addresses,
					  lockdep_is_held(&server->fs_lock));
	afs_get_addrlist(alist);
	afs_get_addrlist(alist, afs_alist_trace_get_fsrotate_set);
	read_unlock(&server->fs_lock);

retry_server:
@@ -493,7 +493,7 @@ bool afs_select_fileserver(struct afs_operation *op)
	if (!op->ac.alist)
		op->ac.alist = alist;
	else
		afs_put_addrlist(alist);
		afs_put_addrlist(alist, afs_alist_trace_put_retry_server);

	op->ac.index = -1;

+2 −2
Original line number Diff line number Diff line
@@ -187,7 +187,7 @@ void afs_put_call(struct afs_call *call)
			call->type->destructor(call);

		afs_unuse_server_notime(call->net, call->server, afs_server_trace_put_call);
		afs_put_addrlist(call->alist);
		afs_put_addrlist(call->alist, afs_alist_trace_put_call);
		kfree(call->request);

		trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
@@ -315,7 +315,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
	       atomic_read(&call->net->nr_outstanding_calls));

	call->addr_ix = ac->index;
	call->alist = afs_get_addrlist(ac->alist);
	call->alist = afs_get_addrlist(ac->alist, afs_alist_trace_get_make_call);

	/* Work out the length we're going to transmit.  This is awkward for
	 * calls such as FS.StoreData where there's an extra injection of data
Loading