Commit 3cb5977c authored by Alexander Aring's avatar Alexander Aring Committed by David Teigland
Browse files

fs: dlm: ls_count busy wait to event based wait



This patch changes the ls_count busy wait to use atomic counter values
and wait_event() to wait until ls_count reach zero. It will slightly
reduce the number of holding lslist_lock. At remove lockspace we need to
retry the wait because it a lockspace get could interefere between
wait_event() and holding the lock which deletes the lockspace list entry.

Signed-off-by: default avatarAlexander Aring <aahringo@redhat.com>
Signed-off-by: default avatarDavid Teigland <teigland@redhat.com>
parent 164d88ab
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -548,8 +548,9 @@ struct dlm_ls {
	uint32_t		ls_generation;
	uint32_t		ls_exflags;
	int			ls_lvblen;
	int			ls_count;	/* refcount of processes in
	atomic_t		ls_count;	/* refcount of processes in
						   the dlm using this ls */
	wait_queue_head_t	ls_count_wait;
	int			ls_create_count; /* create/release refcount */
	unsigned long		ls_flags;	/* LSFL_ */
	unsigned long		ls_scan_time;
+17 −16
Original line number Diff line number Diff line
@@ -314,7 +314,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id)

	list_for_each_entry(ls, &lslist, ls_list) {
		if (ls->ls_global_id == id) {
			ls->ls_count++;
			atomic_inc(&ls->ls_count);
			goto out;
		}
	}
@@ -331,7 +331,7 @@ struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace)
	spin_lock(&lslist_lock);
	list_for_each_entry(ls, &lslist, ls_list) {
		if (ls->ls_local_handle == lockspace) {
			ls->ls_count++;
			atomic_inc(&ls->ls_count);
			goto out;
		}
	}
@@ -348,7 +348,7 @@ struct dlm_ls *dlm_find_lockspace_device(int minor)
	spin_lock(&lslist_lock);
	list_for_each_entry(ls, &lslist, ls_list) {
		if (ls->ls_device.minor == minor) {
			ls->ls_count++;
			atomic_inc(&ls->ls_count);
			goto out;
		}
	}
@@ -360,24 +360,24 @@ struct dlm_ls *dlm_find_lockspace_device(int minor)

void dlm_put_lockspace(struct dlm_ls *ls)
{
	spin_lock(&lslist_lock);
	ls->ls_count--;
	spin_unlock(&lslist_lock);
	if (atomic_dec_and_test(&ls->ls_count))
		wake_up(&ls->ls_count_wait);
}

static void remove_lockspace(struct dlm_ls *ls)
{
	for (;;) {
retry:
	wait_event(ls->ls_count_wait, atomic_read(&ls->ls_count) == 0);

	spin_lock(&lslist_lock);
		if (ls->ls_count == 0) {
			WARN_ON(ls->ls_create_count != 0);
			list_del(&ls->ls_list);
	if (atomic_read(&ls->ls_count) != 0) {
		spin_unlock(&lslist_lock);
			return;
		goto retry;
	}

	WARN_ON(ls->ls_create_count != 0);
	list_del(&ls->ls_list);
	spin_unlock(&lslist_lock);
		ssleep(1);
	}
}

static int threads_start(void)
@@ -481,7 +481,8 @@ static int new_lockspace(const char *name, const char *cluster,
	memcpy(ls->ls_name, name, namelen);
	ls->ls_namelen = namelen;
	ls->ls_lvblen = lvblen;
	ls->ls_count = 0;
	atomic_set(&ls->ls_count, 0);
	init_waitqueue_head(&ls->ls_count_wait);
	ls->ls_flags = 0;
	ls->ls_scan_time = jiffies;

+1 −1
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid)
	uint32_t type = ms->m_type;

	/* the ls is being cleaned up and freed by release_lockspace */
	if (!ls->ls_count)
	if (!atomic_read(&ls->ls_count))
		return 1;

	if (dlm_is_removed(ls, nodeid))