Commit 40d31c49 authored by Joseph Qi's avatar Joseph Qi Committed by Ben Hutchings

ocfs2/dlm: do not get resource spinlock if lockres is new

commit 5760a97c upstream.

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 commit 8d400b81 ("ocfs2/dlm: Clean up refmap
helpers").  Since lockres is new, it doesn't not require the
&res->spinlock.  So remove it.

Fixes: 8d400b81 ("ocfs2/dlm: Clean up refmap helpers")
Signed-off-by: default avatarJoseph Qi <joseph.qi@huawei.com>
Reviewed-by: default avatarjoyce.xue <xuejiufei@huawei.com>
Reported-by: default avatarGuozhonghua <guozhonghua@h3c.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent a428c0e1
...@@ -653,12 +653,9 @@ void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm, ...@@ -653,12 +653,9 @@ void dlm_lockres_clear_refmap_bit(struct dlm_ctxt *dlm,
clear_bit(bit, res->refmap); clear_bit(bit, res->refmap);
} }
static void __dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res) struct dlm_lock_resource *res)
{ {
assert_spin_locked(&res->spinlock);
res->inflight_locks++; res->inflight_locks++;
mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name, mlog(0, "%s: res %.*s, inflight++: now %u, %ps()\n", dlm->name,
...@@ -666,6 +663,13 @@ void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm, ...@@ -666,6 +663,13 @@ void dlm_lockres_grab_inflight_ref(struct dlm_ctxt *dlm,
__builtin_return_address(0)); __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, void dlm_lockres_drop_inflight_ref(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res) struct dlm_lock_resource *res)
{ {
...@@ -855,10 +859,8 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm, ...@@ -855,10 +859,8 @@ struct dlm_lock_resource * dlm_get_lock_resource(struct dlm_ctxt *dlm,
/* finally add the lockres to its hash bucket */ /* finally add the lockres to its hash bucket */
__dlm_insert_lockres(dlm, res); __dlm_insert_lockres(dlm, res);
/* Grab inflight ref to pin the resource */ /* since this lockres is new it doesn't not require the spinlock */
spin_lock(&res->spinlock); __dlm_lockres_grab_inflight_ref(dlm, res);
dlm_lockres_grab_inflight_ref(dlm, res);
spin_unlock(&res->spinlock);
/* get an extra ref on the mle in case this is a BLOCK /* 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 * if so, the creator of the BLOCK may try to put the last
......
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