All of lore.kernel.org
 help / color / mirror / Atom feed
* [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock
@ 2010-06-16  4:08 Wengang Wang
  2010-06-16  5:00 ` Srinivas Eeda
  2010-06-18  1:35 ` Sunil Mushran
  0 siblings, 2 replies; 5+ messages in thread
From: Wengang Wang @ 2010-06-16  4:08 UTC (permalink / raw)
  To: ocfs2-devel

We should check dlm->dlm_state under dlm->spinlock though maybe in this case it
doesn't hurt.

Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
---
 fs/ocfs2/dlm/dlmdomain.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 6b5a492..ab82add 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -796,7 +796,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
 	spin_lock(&dlm_domain_lock);
 	dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
 	if (!dlm)
-		goto unlock_respond;
+		goto unlock_domain_respond;
 
 	/*
 	 * There is a small window where the joining node may not see the
@@ -811,7 +811,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
 				     "have node %u in its nodemap\n",
 				     query->node_idx, nodenum);
 				packet.code = JOIN_DISALLOW;
-				goto unlock_respond;
+				goto unlock_domain_respond;
 			}
 		}
 		nodenum++;
@@ -821,9 +821,9 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
 	 * to be put in someone's domain map.
 	 * Also, explicitly disallow joining at certain troublesome
 	 * times (ie. during recovery). */
-	if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) {
+	spin_lock(&dlm->spinlock);
+	if (dlm->dlm_state != DLM_CTXT_LEAVING) {
 		int bit = query->node_idx;
-		spin_lock(&dlm->spinlock);
 
 		if (dlm->dlm_state == DLM_CTXT_NEW &&
 		    dlm->joining_node == DLM_LOCK_RES_OWNER_UNKNOWN) {
@@ -869,10 +869,9 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
 				__dlm_set_joining_node(dlm, query->node_idx);
 			}
 		}
-
-		spin_unlock(&dlm->spinlock);
 	}
-unlock_respond:
+	spin_unlock(&dlm->spinlock);
+unlock_domain_respond:
 	spin_unlock(&dlm_domain_lock);
 
 respond:
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock
  2010-06-16  4:08 [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock Wengang Wang
@ 2010-06-16  5:00 ` Srinivas Eeda
  2010-06-16  5:13   ` Wengang Wang
  2010-06-18  1:35 ` Sunil Mushran
  1 sibling, 1 reply; 5+ messages in thread
From: Srinivas Eeda @ 2010-06-16  5:00 UTC (permalink / raw)
  To: ocfs2-devel

The lock order in this code causes dead lock, not caused by your patch. 
The lock order in dlm_query_join_handler is

dlm_domain_lock
    ->dlm->spinlock

dead locks with ..

dlm_lockres_put calls dlm_lockres_release while holding dlm->spinlock 
which calls dlm_put which gets dlm_domain_lock. So the spin lock order 
here is
dlm->spinlock
    -> dlm_domain_lock


On 6/15/2010 9:08 PM, Wengang Wang wrote:
> We should check dlm->dlm_state under dlm->spinlock though maybe in this case it
> doesn't hurt.
>
> Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
> ---
>  fs/ocfs2/dlm/dlmdomain.c |   13 ++++++-------
>  1 files changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
> index 6b5a492..ab82add 100644
> --- a/fs/ocfs2/dlm/dlmdomain.c
> +++ b/fs/ocfs2/dlm/dlmdomain.c
> @@ -796,7 +796,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
>  	spin_lock(&dlm_domain_lock);
>  	dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
>  	if (!dlm)
> -		goto unlock_respond;
> +		goto unlock_domain_respond;
>  
>  	/*
>  	 * There is a small window where the joining node may not see the
> @@ -811,7 +811,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
>  				     "have node %u in its nodemap\n",
>  				     query->node_idx, nodenum);
>  				packet.code = JOIN_DISALLOW;
> -				goto unlock_respond;
> +				goto unlock_domain_respond;
>  			}
>  		}
>  		nodenum++;
> @@ -821,9 +821,9 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
>  	 * to be put in someone's domain map.
>  	 * Also, explicitly disallow joining at certain troublesome
>  	 * times (ie. during recovery). */
> -	if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) {
> +	spin_lock(&dlm->spinlock);
> +	if (dlm->dlm_state != DLM_CTXT_LEAVING) {
>  		int bit = query->node_idx;
> -		spin_lock(&dlm->spinlock);
>  
>  		if (dlm->dlm_state == DLM_CTXT_NEW &&
>  		    dlm->joining_node == DLM_LOCK_RES_OWNER_UNKNOWN) {
> @@ -869,10 +869,9 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
>  				__dlm_set_joining_node(dlm, query->node_idx);
>  			}
>  		}
> -
> -		spin_unlock(&dlm->spinlock);
>  	}
> -unlock_respond:
> +	spin_unlock(&dlm->spinlock);
> +unlock_domain_respond:
>  	spin_unlock(&dlm_domain_lock);
>  
>  respond:
>   

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock
  2010-06-16  5:00 ` Srinivas Eeda
@ 2010-06-16  5:13   ` Wengang Wang
  0 siblings, 0 replies; 5+ messages in thread
From: Wengang Wang @ 2010-06-16  5:13 UTC (permalink / raw)
  To: ocfs2-devel

Thanks for review :)

The second path has problem. I think the correct order should be dlm_domain_lock
and then dlm->spinlock.

I will try to fix it.

regards,
wengang.
On 10-06-15 22:00, Srinivas Eeda wrote:
> The lock order in this code causes dead lock, not caused by your
> patch. The lock order in dlm_query_join_handler is
> 
> dlm_domain_lock
>    ->dlm->spinlock
> 
> dead locks with ..
> 
> dlm_lockres_put calls dlm_lockres_release while holding
> dlm->spinlock which calls dlm_put which gets dlm_domain_lock. So the
> spin lock order here is
> dlm->spinlock
>    -> dlm_domain_lock
> 
> 
> On 6/15/2010 9:08 PM, Wengang Wang wrote:
> >We should check dlm->dlm_state under dlm->spinlock though maybe in this case it
> >doesn't hurt.
> >
> >Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
> >---
> > fs/ocfs2/dlm/dlmdomain.c |   13 ++++++-------
> > 1 files changed, 6 insertions(+), 7 deletions(-)
> >
> >diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
> >index 6b5a492..ab82add 100644
> >--- a/fs/ocfs2/dlm/dlmdomain.c
> >+++ b/fs/ocfs2/dlm/dlmdomain.c
> >@@ -796,7 +796,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
> > 	spin_lock(&dlm_domain_lock);
> > 	dlm = __dlm_lookup_domain_full(query->domain, query->name_len);
> > 	if (!dlm)
> >-		goto unlock_respond;
> >+		goto unlock_domain_respond;
> > 	/*
> > 	 * There is a small window where the joining node may not see the
> >@@ -811,7 +811,7 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
> > 				     "have node %u in its nodemap\n",
> > 				     query->node_idx, nodenum);
> > 				packet.code = JOIN_DISALLOW;
> >-				goto unlock_respond;
> >+				goto unlock_domain_respond;
> > 			}
> > 		}
> > 		nodenum++;
> >@@ -821,9 +821,9 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
> > 	 * to be put in someone's domain map.
> > 	 * Also, explicitly disallow joining at certain troublesome
> > 	 * times (ie. during recovery). */
> >-	if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) {
> >+	spin_lock(&dlm->spinlock);
> >+	if (dlm->dlm_state != DLM_CTXT_LEAVING) {
> > 		int bit = query->node_idx;
> >-		spin_lock(&dlm->spinlock);
> > 		if (dlm->dlm_state == DLM_CTXT_NEW &&
> > 		    dlm->joining_node == DLM_LOCK_RES_OWNER_UNKNOWN) {
> >@@ -869,10 +869,9 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data,
> > 				__dlm_set_joining_node(dlm, query->node_idx);
> > 			}
> > 		}
> >-
> >-		spin_unlock(&dlm->spinlock);
> > 	}
> >-unlock_respond:
> >+	spin_unlock(&dlm->spinlock);
> >+unlock_domain_respond:
> > 	spin_unlock(&dlm_domain_lock);
> > respond:

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock
  2010-06-16  4:08 [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock Wengang Wang
  2010-06-16  5:00 ` Srinivas Eeda
@ 2010-06-18  1:35 ` Sunil Mushran
  2010-06-18  2:48   ` Wengang Wang
  1 sibling, 1 reply; 5+ messages in thread
From: Sunil Mushran @ 2010-06-18  1:35 UTC (permalink / raw)
  To: ocfs2-devel

On 06/15/2010 09:08 PM, Wengang Wang wrote:
> We should check dlm->dlm_state under dlm->spinlock though maybe in this case it
> doesn't hurt.
>    

NAK.

dlm->dlm_state is protected by dlm_domain_lock which is held at that time.

         /* NOTE: Next three are protected by dlm_domain_lock */
         struct kref dlm_refs;
         enum dlm_ctxt_state dlm_state;
         unsigned int num_joins;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock
  2010-06-18  1:35 ` Sunil Mushran
@ 2010-06-18  2:48   ` Wengang Wang
  0 siblings, 0 replies; 5+ messages in thread
From: Wengang Wang @ 2010-06-18  2:48 UTC (permalink / raw)
  To: ocfs2-devel

On 10-06-17 18:35, Sunil Mushran wrote:
> On 06/15/2010 09:08 PM, Wengang Wang wrote:
> >We should check dlm->dlm_state under dlm->spinlock though maybe in this case it
> >doesn't hurt.
> 
> NAK.
> 
> dlm->dlm_state is protected by dlm_domain_lock which is held at that time.
> 
>         /* NOTE: Next three are protected by dlm_domain_lock */
>         struct kref dlm_refs;
>         enum dlm_ctxt_state dlm_state;
>         unsigned int num_joins;

Yes, that's ture. thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-06-18  2:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-06-16  4:08 [Ocfs2-devel] [PATCH] ocfs2/dlm: check dlm_state under spinlock Wengang Wang
2010-06-16  5:00 ` Srinivas Eeda
2010-06-16  5:13   ` Wengang Wang
2010-06-18  1:35 ` Sunil Mushran
2010-06-18  2:48   ` Wengang Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.