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: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
This commit is contained in:
Родитель
164d88abd7
Коммит
3cb5977c52
|
@ -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;
|
||||
|
|
|
@ -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 (;;) {
|
||||
spin_lock(&lslist_lock);
|
||||
if (ls->ls_count == 0) {
|
||||
WARN_ON(ls->ls_create_count != 0);
|
||||
list_del(&ls->ls_list);
|
||||
spin_unlock(&lslist_lock);
|
||||
return;
|
||||
}
|
||||
retry:
|
||||
wait_event(ls->ls_count_wait, atomic_read(&ls->ls_count) == 0);
|
||||
|
||||
spin_lock(&lslist_lock);
|
||||
if (atomic_read(&ls->ls_count) != 0) {
|
||||
spin_unlock(&lslist_lock);
|
||||
ssleep(1);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
WARN_ON(ls->ls_create_count != 0);
|
||||
list_del(&ls->ls_list);
|
||||
spin_unlock(&lslist_lock);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
Загрузка…
Ссылка в новой задаче