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

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
...@@ -548,8 +548,9 @@ struct dlm_ls { ...@@ -548,8 +548,9 @@ struct dlm_ls {
uint32_t ls_generation; uint32_t ls_generation;
uint32_t ls_exflags; uint32_t ls_exflags;
int ls_lvblen; int ls_lvblen;
int ls_count; /* refcount of processes in atomic_t ls_count; /* refcount of processes in
the dlm using this ls */ the dlm using this ls */
wait_queue_head_t ls_count_wait;
int ls_create_count; /* create/release refcount */ int ls_create_count; /* create/release refcount */
unsigned long ls_flags; /* LSFL_ */ unsigned long ls_flags; /* LSFL_ */
unsigned long ls_scan_time; unsigned long ls_scan_time;
......
...@@ -314,7 +314,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id) ...@@ -314,7 +314,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id)
list_for_each_entry(ls, &lslist, ls_list) { list_for_each_entry(ls, &lslist, ls_list) {
if (ls->ls_global_id == id) { if (ls->ls_global_id == id) {
ls->ls_count++; atomic_inc(&ls->ls_count);
goto out; goto out;
} }
} }
...@@ -331,7 +331,7 @@ struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace) ...@@ -331,7 +331,7 @@ struct dlm_ls *dlm_find_lockspace_local(dlm_lockspace_t *lockspace)
spin_lock(&lslist_lock); spin_lock(&lslist_lock);
list_for_each_entry(ls, &lslist, ls_list) { list_for_each_entry(ls, &lslist, ls_list) {
if (ls->ls_local_handle == lockspace) { if (ls->ls_local_handle == lockspace) {
ls->ls_count++; atomic_inc(&ls->ls_count);
goto out; goto out;
} }
} }
...@@ -348,7 +348,7 @@ struct dlm_ls *dlm_find_lockspace_device(int minor) ...@@ -348,7 +348,7 @@ struct dlm_ls *dlm_find_lockspace_device(int minor)
spin_lock(&lslist_lock); spin_lock(&lslist_lock);
list_for_each_entry(ls, &lslist, ls_list) { list_for_each_entry(ls, &lslist, ls_list) {
if (ls->ls_device.minor == minor) { if (ls->ls_device.minor == minor) {
ls->ls_count++; atomic_inc(&ls->ls_count);
goto out; goto out;
} }
} }
...@@ -360,24 +360,24 @@ struct dlm_ls *dlm_find_lockspace_device(int minor) ...@@ -360,24 +360,24 @@ struct dlm_ls *dlm_find_lockspace_device(int minor)
void dlm_put_lockspace(struct dlm_ls *ls) void dlm_put_lockspace(struct dlm_ls *ls)
{ {
spin_lock(&lslist_lock); if (atomic_dec_and_test(&ls->ls_count))
ls->ls_count--; wake_up(&ls->ls_count_wait);
spin_unlock(&lslist_lock);
} }
static void remove_lockspace(struct dlm_ls *ls) 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); spin_lock(&lslist_lock);
if (ls->ls_count == 0) { if (atomic_read(&ls->ls_count) != 0) {
WARN_ON(ls->ls_create_count != 0);
list_del(&ls->ls_list);
spin_unlock(&lslist_lock); spin_unlock(&lslist_lock);
return; goto retry;
} }
WARN_ON(ls->ls_create_count != 0);
list_del(&ls->ls_list);
spin_unlock(&lslist_lock); spin_unlock(&lslist_lock);
ssleep(1);
}
} }
static int threads_start(void) static int threads_start(void)
...@@ -481,7 +481,8 @@ static int new_lockspace(const char *name, const char *cluster, ...@@ -481,7 +481,8 @@ static int new_lockspace(const char *name, const char *cluster,
memcpy(ls->ls_name, name, namelen); memcpy(ls->ls_name, name, namelen);
ls->ls_namelen = namelen; ls->ls_namelen = namelen;
ls->ls_lvblen = lvblen; 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_flags = 0;
ls->ls_scan_time = jiffies; ls->ls_scan_time = jiffies;
......
...@@ -127,7 +127,7 @@ static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid) ...@@ -127,7 +127,7 @@ static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid)
uint32_t type = ms->m_type; uint32_t type = ms->m_type;
/* the ls is being cleaned up and freed by release_lockspace */ /* the ls is being cleaned up and freed by release_lockspace */
if (!ls->ls_count) if (!atomic_read(&ls->ls_count))
return 1; return 1;
if (dlm_is_removed(ls, nodeid)) if (dlm_is_removed(ls, nodeid))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment