Skip to content

Commit 7b01273

Browse files
Alexander Aringteigland
authored andcommitted
dlm: fix sleep in atomic context
This patch changes the orphans mutex to a spinlock since commit c288745 ("dlm: avoid blocking receive at the end of recovery") is using a rwlock_t to lock the DLM message receive path and do_purge() can be called while this lock is held that forbids to sleep. We need to use spin_lock_bh() because also a user context that calls dlm_user_purge() can call do_purge() and since commit 92d59ad ("dlm: do message processing in softirq context") the DLM message receive path is done under softirq context. Fixes: c288745 ("dlm: avoid blocking receive at the end of recovery") Reported-by: Dan Carpenter <[email protected]> Closes: https://lore.kernel.org/gfs2/[email protected]/ Signed-off-by: Alexander Aring <[email protected]> Signed-off-by: David Teigland <[email protected]>
1 parent 15fd7e5 commit 7b01273

File tree

3 files changed

+8
-8
lines changed

3 files changed

+8
-8
lines changed

fs/dlm/dlm_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ struct dlm_ls {
602602
spinlock_t ls_waiters_lock;
603603
struct list_head ls_waiters; /* lkbs needing a reply */
604604

605-
struct mutex ls_orphans_mutex;
605+
spinlock_t ls_orphans_lock;
606606
struct list_head ls_orphans;
607607

608608
spinlock_t ls_new_rsb_spin;

fs/dlm/lock.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5880,7 +5880,7 @@ int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
58805880
int found_other_mode = 0;
58815881
int rv = 0;
58825882

5883-
mutex_lock(&ls->ls_orphans_mutex);
5883+
spin_lock_bh(&ls->ls_orphans_lock);
58845884
list_for_each_entry(iter, &ls->ls_orphans, lkb_ownqueue) {
58855885
if (iter->lkb_resource->res_length != namelen)
58865886
continue;
@@ -5897,7 +5897,7 @@ int dlm_user_adopt_orphan(struct dlm_ls *ls, struct dlm_user_args *ua_tmp,
58975897
*lkid = iter->lkb_id;
58985898
break;
58995899
}
5900-
mutex_unlock(&ls->ls_orphans_mutex);
5900+
spin_unlock_bh(&ls->ls_orphans_lock);
59015901

59025902
if (!lkb && found_other_mode) {
59035903
rv = -EAGAIN;
@@ -6089,9 +6089,9 @@ static int orphan_proc_lock(struct dlm_ls *ls, struct dlm_lkb *lkb)
60896089
int error;
60906090

60916091
hold_lkb(lkb); /* reference for the ls_orphans list */
6092-
mutex_lock(&ls->ls_orphans_mutex);
6092+
spin_lock_bh(&ls->ls_orphans_lock);
60936093
list_add_tail(&lkb->lkb_ownqueue, &ls->ls_orphans);
6094-
mutex_unlock(&ls->ls_orphans_mutex);
6094+
spin_unlock_bh(&ls->ls_orphans_lock);
60956095

60966096
set_unlock_args(0, lkb->lkb_ua, &args);
60976097

@@ -6241,15 +6241,15 @@ static void do_purge(struct dlm_ls *ls, int nodeid, int pid)
62416241
{
62426242
struct dlm_lkb *lkb, *safe;
62436243

6244-
mutex_lock(&ls->ls_orphans_mutex);
6244+
spin_lock_bh(&ls->ls_orphans_lock);
62456245
list_for_each_entry_safe(lkb, safe, &ls->ls_orphans, lkb_ownqueue) {
62466246
if (pid && lkb->lkb_ownpid != pid)
62476247
continue;
62486248
unlock_proc_lock(ls, lkb);
62496249
list_del_init(&lkb->lkb_ownqueue);
62506250
dlm_put_lkb(lkb);
62516251
}
6252-
mutex_unlock(&ls->ls_orphans_mutex);
6252+
spin_unlock_bh(&ls->ls_orphans_lock);
62536253
}
62546254

62556255
static int send_purge(struct dlm_ls *ls, int nodeid, int pid)

fs/dlm/lockspace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ static int new_lockspace(const char *name, const char *cluster,
436436
INIT_LIST_HEAD(&ls->ls_waiters);
437437
spin_lock_init(&ls->ls_waiters_lock);
438438
INIT_LIST_HEAD(&ls->ls_orphans);
439-
mutex_init(&ls->ls_orphans_mutex);
439+
spin_lock_init(&ls->ls_orphans_lock);
440440

441441
INIT_LIST_HEAD(&ls->ls_new_rsb);
442442
spin_lock_init(&ls->ls_new_rsb_spin);

0 commit comments

Comments
 (0)