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

afs: Use refcount_t rather than atomic_t



Use refcount_t rather than atomic_t in afs to make use of the count
checking facilities provided.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarMarc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://lore.kernel.org/r/165911277768.3745403.423349776836296452.stgit@warthog.procyon.org.uk/ # v1
parent 6e7765cb
Loading
Loading
Loading
Loading
+29 −32
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net,
		cell->name[i] = tolower(name[i]);
	cell->name[i] = 0;

	atomic_set(&cell->ref, 1);
	refcount_set(&cell->ref, 1);
	atomic_set(&cell->active, 0);
	INIT_WORK(&cell->manager, afs_manage_cell_work);
	cell->volumes = RB_ROOT;
@@ -287,7 +287,7 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net,
	cell = candidate;
	candidate = NULL;
	atomic_set(&cell->active, 2);
	trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), 2, afs_cell_trace_insert);
	trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 2, afs_cell_trace_insert);
	rb_link_node_rcu(&cell->net_node, parent, pp);
	rb_insert_color(&cell->net_node, &net->cells);
	up_write(&net->cells_lock);
@@ -295,7 +295,7 @@ struct afs_cell *afs_lookup_cell(struct afs_net *net,
	afs_queue_cell(cell, afs_cell_trace_get_queue_new);

wait_for_cell:
	trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), atomic_read(&cell->active),
	trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), atomic_read(&cell->active),
		       afs_cell_trace_wait);
	_debug("wait_for_cell");
	wait_var_event(&cell->state,
@@ -490,13 +490,13 @@ static void afs_cell_destroy(struct rcu_head *rcu)
{
	struct afs_cell *cell = container_of(rcu, struct afs_cell, rcu);
	struct afs_net *net = cell->net;
	int u;
	int r;

	_enter("%p{%s}", cell, cell->name);

	u = atomic_read(&cell->ref);
	ASSERTCMP(u, ==, 0);
	trace_afs_cell(cell->debug_id, u, atomic_read(&cell->active), afs_cell_trace_free);
	r = refcount_read(&cell->ref);
	ASSERTCMP(r, ==, 0);
	trace_afs_cell(cell->debug_id, r, atomic_read(&cell->active), afs_cell_trace_free);

	afs_put_vlserverlist(net, rcu_access_pointer(cell->vl_servers));
	afs_unuse_cell(net, cell->alias_of, afs_cell_trace_unuse_alias);
@@ -539,13 +539,10 @@ void afs_cells_timer(struct timer_list *timer)
 */
struct afs_cell *afs_get_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	int u;
	int r;

	if (atomic_read(&cell->ref) <= 0)
		BUG();

	u = atomic_inc_return(&cell->ref);
	trace_afs_cell(cell->debug_id, u, atomic_read(&cell->active), reason);
	__refcount_inc(&cell->ref, &r);
	trace_afs_cell(cell->debug_id, r + 1, atomic_read(&cell->active), reason);
	return cell;
}

@@ -556,12 +553,14 @@ void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	if (cell) {
		unsigned int debug_id = cell->debug_id;
		unsigned int u, a;
		unsigned int a;
		bool zero;
		int r;

		a = atomic_read(&cell->active);
		u = atomic_dec_return(&cell->ref);
		trace_afs_cell(debug_id, u, a, reason);
		if (u == 0) {
		zero = __refcount_dec_and_test(&cell->ref, &r);
		trace_afs_cell(debug_id, r - 1, a, reason);
		if (zero) {
			a = atomic_read(&cell->active);
			WARN(a != 0, "Cell active count %u > 0\n", a);
			call_rcu(&cell->rcu, afs_cell_destroy);
@@ -574,14 +573,12 @@ void afs_put_cell(struct afs_cell *cell, enum afs_cell_trace reason)
 */
struct afs_cell *afs_use_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	int u, a;

	if (atomic_read(&cell->ref) <= 0)
		BUG();
	int r, a;

	u = atomic_read(&cell->ref);
	r = refcount_read(&cell->ref);
	WARN_ON(r == 0);
	a = atomic_inc_return(&cell->active);
	trace_afs_cell(cell->debug_id, u, a, reason);
	trace_afs_cell(cell->debug_id, r, a, reason);
	return cell;
}

@@ -593,7 +590,7 @@ void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_tr
{
	unsigned int debug_id;
	time64_t now, expire_delay;
	int u, a;
	int r, a;

	if (!cell)
		return;
@@ -607,9 +604,9 @@ void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_tr
		expire_delay = afs_cell_gc_delay;

	debug_id = cell->debug_id;
	u = atomic_read(&cell->ref);
	r = refcount_read(&cell->ref);
	a = atomic_dec_return(&cell->active);
	trace_afs_cell(debug_id, u, a, reason);
	trace_afs_cell(debug_id, r, a, reason);
	WARN_ON(a == 0);
	if (a == 1)
		/* 'cell' may now be garbage collected. */
@@ -621,11 +618,11 @@ void afs_unuse_cell(struct afs_net *net, struct afs_cell *cell, enum afs_cell_tr
 */
void afs_see_cell(struct afs_cell *cell, enum afs_cell_trace reason)
{
	int u, a;
	int r, a;

	u = atomic_read(&cell->ref);
	r = refcount_read(&cell->ref);
	a = atomic_read(&cell->active);
	trace_afs_cell(cell->debug_id, u, a, reason);
	trace_afs_cell(cell->debug_id, r, a, reason);
}

/*
@@ -739,7 +736,7 @@ static void afs_manage_cell(struct afs_cell *cell)
		active = 1;
		if (atomic_try_cmpxchg_relaxed(&cell->active, &active, 0)) {
			rb_erase(&cell->net_node, &net->cells);
			trace_afs_cell(cell->debug_id, atomic_read(&cell->ref), 0,
			trace_afs_cell(cell->debug_id, refcount_read(&cell->ref), 0,
				       afs_cell_trace_unuse_delete);
			smp_store_release(&cell->state, AFS_CELL_REMOVED);
		}
@@ -866,7 +863,7 @@ void afs_manage_cells(struct work_struct *work)
		bool sched_cell = false;

		active = atomic_read(&cell->active);
		trace_afs_cell(cell->debug_id, atomic_read(&cell->ref),
		trace_afs_cell(cell->debug_id, refcount_read(&cell->ref),
			       active, afs_cell_trace_manage);

		ASSERTCMP(active, >=, 1);
@@ -874,7 +871,7 @@ void afs_manage_cells(struct work_struct *work)
		if (purging) {
			if (test_and_clear_bit(AFS_CELL_FL_NO_GC, &cell->flags)) {
				active = atomic_dec_return(&cell->active);
				trace_afs_cell(cell->debug_id, atomic_read(&cell->ref),
				trace_afs_cell(cell->debug_id, refcount_read(&cell->ref),
					       active, afs_cell_trace_unuse_pin);
			}
		}
+1 −1
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static void SRXAFSCB_CallBack(struct work_struct *work)
	 */
	if (call->server) {
		trace_afs_server(call->server,
				 atomic_read(&call->server->ref),
				 refcount_read(&call->server->ref),
				 atomic_read(&call->server->active),
				 afs_server_trace_callback);
		afs_break_callbacks(call->server, call->count, call->request);
+8 −8
Original line number Diff line number Diff line
@@ -122,7 +122,7 @@ struct afs_call {
	};
	struct afs_operation	*op;
	unsigned int		server_index;
	atomic_t		usage;
	refcount_t		ref;
	enum afs_call_state	state;
	spinlock_t		state_lock;
	int			error;		/* error code */
@@ -365,7 +365,7 @@ struct afs_cell {
	struct hlist_node	proc_link;	/* /proc cell list link */
	time64_t		dns_expiry;	/* Time AFSDB/SRV record expires */
	time64_t		last_inactive;	/* Time of last drop of usage count */
	atomic_t		ref;		/* Struct refcount */
	refcount_t		ref;		/* Struct refcount */
	atomic_t		active;		/* Active usage counter */
	unsigned long		flags;
#define AFS_CELL_FL_NO_GC	0		/* The cell was added manually, don't auto-gc */
@@ -410,7 +410,7 @@ struct afs_vlserver {
#define AFS_VLSERVER_FL_IS_YFS	2		/* Server is YFS not AFS */
#define AFS_VLSERVER_FL_RESPONDING 3		/* VL server is responding */
	rwlock_t		lock;		/* Lock on addresses */
	atomic_t		usage;
	refcount_t		ref;
	unsigned int		rtt;		/* Server's current RTT in uS */

	/* Probe state */
@@ -446,7 +446,7 @@ struct afs_vlserver_entry {

struct afs_vlserver_list {
	struct rcu_head		rcu;
	atomic_t		usage;
	refcount_t		ref;
	u8			nr_servers;
	u8			index;		/* Server currently in use */
	u8			preferred;	/* Preferred server */
@@ -517,7 +517,7 @@ struct afs_server {
#define AFS_SERVER_FL_NO_IBULK	17		/* Fileserver doesn't support FS.InlineBulkStatus */
#define AFS_SERVER_FL_NO_RM2	18		/* Fileserver doesn't support YFS.RemoveFile2 */
#define AFS_SERVER_FL_HAS_FS64	19		/* Fileserver supports FS.{Fetch,Store}Data64 */
	atomic_t		ref;		/* Object refcount */
	refcount_t		ref;		/* Object refcount */
	atomic_t		active;		/* Active user count */
	u32			addr_version;	/* Address list version */
	unsigned int		rtt;		/* Server's current RTT in uS */
@@ -571,7 +571,7 @@ struct afs_volume {
		struct rcu_head	rcu;
		afs_volid_t	vid;		/* volume ID */
	};
	atomic_t		usage;
	refcount_t		ref;
	time64_t		update_at;	/* Time at which to next update */
	struct afs_cell		*cell;		/* Cell to which belongs (pins ref) */
	struct rb_node		cell_node;	/* Link in cell->volumes */
@@ -1493,14 +1493,14 @@ extern int afs_end_vlserver_operation(struct afs_vl_cursor *);
 */
static inline struct afs_vlserver *afs_get_vlserver(struct afs_vlserver *vlserver)
{
	atomic_inc(&vlserver->usage);
	refcount_inc(&vlserver->ref);
	return vlserver;
}

static inline struct afs_vlserver_list *afs_get_vlserverlist(struct afs_vlserver_list *vllist)
{
	if (vllist)
		atomic_inc(&vllist->usage);
		refcount_inc(&vllist->ref);
	return vllist;
}

+3 −3
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ static int afs_proc_cells_show(struct seq_file *m, void *v)

	/* display one cell per line on subsequent lines */
	seq_printf(m, "%3u %3u %6lld %2u %2u %s\n",
		   atomic_read(&cell->ref),
		   refcount_read(&cell->ref),
		   atomic_read(&cell->active),
		   cell->dns_expiry - ktime_get_real_seconds(),
		   vllist ? vllist->nr_servers : 0,
@@ -217,7 +217,7 @@ static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
	}

	seq_printf(m, "%3d %08llx %s %s\n",
		   atomic_read(&vol->usage), vol->vid,
		   refcount_read(&vol->ref), vol->vid,
		   afs_vol_types[vol->type],
		   vol->name);

@@ -388,7 +388,7 @@ static int afs_proc_servers_show(struct seq_file *m, void *v)
	alist = rcu_dereference(server->addresses);
	seq_printf(m, "%pU %3d %3d\n",
		   &server->uuid,
		   atomic_read(&server->ref),
		   refcount_read(&server->ref),
		   atomic_read(&server->active));
	seq_printf(m, "  - info: fl=%lx rtt=%u brk=%x\n",
		   server->flags, server->rtt, server->cb_s_break);
+14 −12
Original line number Diff line number Diff line
@@ -145,7 +145,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
	call->type = type;
	call->net = net;
	call->debug_id = atomic_inc_return(&rxrpc_debug_id);
	atomic_set(&call->usage, 1);
	refcount_set(&call->ref, 1);
	INIT_WORK(&call->async_work, afs_process_async_call);
	init_waitqueue_head(&call->waitq);
	spin_lock_init(&call->state_lock);
@@ -163,14 +163,15 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
void afs_put_call(struct afs_call *call)
{
	struct afs_net *net = call->net;
	int n = atomic_dec_return(&call->usage);
	int o = atomic_read(&net->nr_outstanding_calls);
	bool zero;
	int r, o;

	trace_afs_call(call, afs_call_trace_put, n, o,
	zero = __refcount_dec_and_test(&call->ref, &r);
	o = atomic_read(&net->nr_outstanding_calls);
	trace_afs_call(call, afs_call_trace_put, r - 1, o,
		       __builtin_return_address(0));

	ASSERTCMP(n, >=, 0);
	if (n == 0) {
	if (zero) {
		ASSERT(!work_pending(&call->async_work));
		ASSERT(call->type->name != NULL);

@@ -198,9 +199,11 @@ void afs_put_call(struct afs_call *call)
static struct afs_call *afs_get_call(struct afs_call *call,
				     enum afs_call_trace why)
{
	int u = atomic_inc_return(&call->usage);
	int r;

	trace_afs_call(call, why, u,
	__refcount_inc(&call->ref, &r);

	trace_afs_call(call, why, r + 1,
		       atomic_read(&call->net->nr_outstanding_calls),
		       __builtin_return_address(0));
	return call;
@@ -668,14 +671,13 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
				   unsigned long call_user_ID)
{
	struct afs_call *call = (struct afs_call *)call_user_ID;
	int u;
	int r;

	trace_afs_notify_call(rxcall, call);
	call->need_attention = true;

	u = atomic_fetch_add_unless(&call->usage, 1, 0);
	if (u != 0) {
		trace_afs_call(call, afs_call_trace_wake, u + 1,
	if (__refcount_inc_not_zero(&call->ref, &r)) {
		trace_afs_call(call, afs_call_trace_wake, r + 1,
			       atomic_read(&call->net->nr_outstanding_calls),
			       __builtin_return_address(0));

Loading