Skip to content

Commit 6b52ea7

Browse files
Alexander Aringteigland
authored andcommitted
dlm: drop mutex use in waiters recovery
The waiters_mutex no longer needs to be used in the waiters recovery functions dlm_recover_waiters_pre() and dlm_recover_waiters_pre(). During recovery, ordinary locking operations are paused, and the recovery thread is the only context accessing the waiters list, so the lock is not needed. Access to the waiters list from debugfs functions is avoided by taking the top level recovery lock in the debugfs dump function. Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent 3ae6776 commit 6b52ea7

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

fs/dlm/debug_fs.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,12 @@ static ssize_t waiters_read(struct file *file, char __user *userbuf,
737737
size_t len = DLM_DEBUG_BUF_LEN, pos = 0, ret, rv;
738738

739739
mutex_lock(&debug_buf_lock);
740+
ret = dlm_lock_recovery_try(ls);
741+
if (!ret) {
742+
rv = -EAGAIN;
743+
goto out;
744+
}
745+
740746
mutex_lock(&ls->ls_waiters_mutex);
741747
memset(debug_buf, 0, sizeof(debug_buf));
742748

@@ -749,8 +755,10 @@ static ssize_t waiters_read(struct file *file, char __user *userbuf,
749755
pos += ret;
750756
}
751757
mutex_unlock(&ls->ls_waiters_mutex);
758+
dlm_unlock_recovery(ls);
752759

753760
rv = simple_read_from_buffer(userbuf, count, ppos, debug_buf, pos);
761+
out:
754762
mutex_unlock(&debug_buf_lock);
755763
return rv;
756764
}
@@ -772,7 +780,12 @@ static ssize_t waiters_write(struct file *file, const char __user *user_buf,
772780
if (n != 3)
773781
return -EINVAL;
774782

783+
error = dlm_lock_recovery_try(ls);
784+
if (!error)
785+
return -EAGAIN;
786+
775787
error = dlm_debug_add_lkb_to_waiters(ls, lkb_id, mstype, to_nodeid);
788+
dlm_unlock_recovery(ls);
776789
if (error)
777790
return error;
778791

fs/dlm/lock.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ void dlm_dump_rsb(struct dlm_rsb *r)
201201

202202
/* Threads cannot use the lockspace while it's being recovered */
203203

204-
static inline void dlm_lock_recovery(struct dlm_ls *ls)
204+
void dlm_lock_recovery(struct dlm_ls *ls)
205205
{
206206
down_read(&ls->ls_in_recovery);
207207
}
@@ -1556,7 +1556,11 @@ static int remove_from_waiters(struct dlm_lkb *lkb, int mstype)
15561556
}
15571557

15581558
/* Handles situations where we might be processing a "fake" or "local" reply in
1559-
which we can't try to take waiters_mutex again. */
1559+
* the recovery context which stops any locking activity. Only debugfs might
1560+
* change the lockspace waiters but they will held the recovery lock to ensure
1561+
* remove_from_waiters_ms() in local case will be the only user manipulating the
1562+
* lockspace waiters in recovery context.
1563+
*/
15601564

15611565
static int remove_from_waiters_ms(struct dlm_lkb *lkb,
15621566
const struct dlm_message *ms, bool local)
@@ -1566,6 +1570,9 @@ static int remove_from_waiters_ms(struct dlm_lkb *lkb,
15661570

15671571
if (!local)
15681572
mutex_lock(&ls->ls_waiters_mutex);
1573+
else
1574+
WARN_ON_ONCE(!rwsem_is_locked(&ls->ls_in_recovery) ||
1575+
!dlm_locking_stopped(ls));
15691576
error = _remove_from_waiters(lkb, le32_to_cpu(ms->m_type), ms);
15701577
if (!local)
15711578
mutex_unlock(&ls->ls_waiters_mutex);
@@ -4398,7 +4405,6 @@ static void _receive_convert_reply(struct dlm_lkb *lkb,
43984405
if (error)
43994406
goto out;
44004407

4401-
/* local reply can happen with waiters_mutex held */
44024408
error = remove_from_waiters_ms(lkb, ms, local);
44034409
if (error)
44044410
goto out;
@@ -4437,7 +4443,6 @@ static void _receive_unlock_reply(struct dlm_lkb *lkb,
44374443
if (error)
44384444
goto out;
44394445

4440-
/* local reply can happen with waiters_mutex held */
44414446
error = remove_from_waiters_ms(lkb, ms, local);
44424447
if (error)
44434448
goto out;
@@ -4489,7 +4494,6 @@ static void _receive_cancel_reply(struct dlm_lkb *lkb,
44894494
if (error)
44904495
goto out;
44914496

4492-
/* local reply can happen with waiters_mutex held */
44934497
error = remove_from_waiters_ms(lkb, ms, local);
44944498
if (error)
44954499
goto out;
@@ -4890,8 +4894,6 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
48904894
if (!ms_local)
48914895
return;
48924896

4893-
mutex_lock(&ls->ls_waiters_mutex);
4894-
48954897
list_for_each_entry_safe(lkb, safe, &ls->ls_waiters, lkb_wait_reply) {
48964898

48974899
dir_nodeid = dlm_dir_nodeid(lkb->lkb_resource);
@@ -4984,7 +4986,6 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls)
49844986
}
49854987
schedule();
49864988
}
4987-
mutex_unlock(&ls->ls_waiters_mutex);
49884989
kfree(ms_local);
49894990
}
49904991

fs/dlm/lock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ void dlm_hold_rsb(struct dlm_rsb *r);
2323
int dlm_put_lkb(struct dlm_lkb *lkb);
2424
void dlm_scan_rsbs(struct dlm_ls *ls);
2525
int dlm_lock_recovery_try(struct dlm_ls *ls);
26+
void dlm_lock_recovery(struct dlm_ls *ls);
2627
void dlm_unlock_recovery(struct dlm_ls *ls);
2728

2829
int dlm_master_lookup(struct dlm_ls *ls, int from_nodeid, const char *name,

0 commit comments

Comments
 (0)