ocfs2/dlm: do not get resource spinlock if lockres is new
There is a deadlock case which reported by Guozhonghua: https://oss.oracle.com/pipermail/ocfs2-devel/2014-September/010079.html This case is caused by &res->spinlock and &dlm->master_lock misordering in different threads. It was introduced by commit8d400b81cc
("ocfs2/dlm: Clean up refmap helpers"). Since lockres is new, it doesn't not require the &res->spinlock. So remove it. Fixes:8d400b81cc
("ocfs2/dlm: Clean up refmap helpers") Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Reviewed-by: joyce.xue <xuejiufei@huawei.com> Reported-by: Guozhonghua <guozhonghua@h3c.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Mark Fasheh <mfasheh@suse.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
56d7acc792
commit
5760a97c71
|
@ -655,12 +655,9 @@ void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
|
|||
clear_bit(bit, res->refmap);
|
||||
}
|
||||
|
||||
|
||||
void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
|
||||
static void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
|
||||
struct dlm_lock_resource *res)
|
||||
{
|
||||
assert_spin_locked(&res->spinlock);
|
||||
|
||||
res->inflight_locks++;
|
||||
|
||||
mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
|
||||
|
@ -668,6 +665,13 @@ void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
|
|||
__builtin_return_address(0));
|
||||
}
|
||||
|
||||
void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
|
||||
struct dlm_lock_resource *res)
|
||||
{
|
||||
assert_spin_locked(&res->spinlock);
|
||||
__dlm_lockres_grab_inflight_ref(dlm, res);
|
||||
}
|
||||
|
||||
void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
|
||||
struct dlm_lock_resource *res)
|
||||
{
|
||||
|
@ -894,10 +898,8 @@ lookup:
|
|||
/* finally add the lockres to its hash bucket */
|
||||
__dlm_insert_lockres(dlm, res);
|
||||
|
||||
/* Grab inflight ref to pin the resource */
|
||||
spin_lock(&res->spinlock);
|
||||
dlm_lockres_grab_inflight_ref(dlm, res);
|
||||
spin_unlock(&res->spinlock);
|
||||
/* since this lockres is new it doesn't not require the spinlock */
|
||||
__dlm_lockres_grab_inflight_ref(dlm, res);
|
||||
|
||||
/* get an extra ref on the mle in case this is a BLOCK
|
||||
* if so, the creator of the BLOCK may try to put the last
|
||||
|
|
Loading…
Reference in New Issue