futex: add double_unlock_hb()

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Saturday, March 28, 2009 - 5:59 pm

Gitweb:     http://git.kernel.org/linus/5eb3dc62fc5986e85715041c23dcf3832812be4b
Commit:     5eb3dc62fc5986e85715041c23dcf3832812be4b
Parent:     de87fcc124a5d4a171aa32707b3265608ebda6e7
Author:     Darren Hart <dvhltc@us.ibm.com>
AuthorDate: Thu Mar 12 00:55:52 2009 -0700
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Thu Mar 12 11:20:56 2009 +0100

    futex: add double_unlock_hb()
    
    Impact: cleanup
    
    The futex code uses double_lock_hb() which locks the hb->lock's
    in pointer value order.  There is no parallel unlock routine,
    and the code unlocks them in name order, ignoring pointer value.
    
    This patch adds double_unlock_hb() to refactor the duplicated
    code segments.
    
    Build and boot tested on a 4 way Intel x86_64 workstation.
    Passes basic pthread_mutex and PI tests out of
    ltp/testcases/realtime.
    
    Signed-off-by: Darren Hart <dvhltc@us.ibm.com>
    Acked-by: Peter Zijlstra <peterz@infradead.org>
    Cc: Rusty Russell <rusty@rustcorp.com.au>
    LKML-Reference: <20090312075552.9856.48021.stgit@Aeon>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 kernel/futex.c |   29 +++++++++++++++++------------
 1 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/kernel/futex.c b/kernel/futex.c
index 4000454..e149545 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -690,6 +690,19 @@ double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
 	}
 }
 
+static inline void
+double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2)
+{
+	if (hb1 <= hb2) {
+		spin_unlock(&hb2->lock);
+		if (hb1 < hb2)
+			spin_unlock(&hb1->lock);
+	} else { /* hb1 > hb2 */
+		spin_unlock(&hb1->lock);
+		spin_unlock(&hb2->lock);
+	}
+}
+
 /*
  * Wake up waiters matching bitset queued on this futex (uaddr).
  */
@@ -767,9 +780,7 @@ retry:
 	if (unlikely(op_ret < 0)) {
 		u32 dummy;
 
-		spin_unlock(&hb1->lock);
-		if (hb1 != hb2)
-			spin_unlock(&hb2->lock);
+		double_unlock_hb(hb1, hb2);
 
 #ifndef CONFIG_MMU
 		/*
@@ -833,9 +844,7 @@ retry:
 		ret += op_ret;
 	}
 
-	spin_unlock(&hb1->lock);
-	if (hb1 != hb2)
-		spin_unlock(&hb2->lock);
+	double_unlock_hb(hb1, hb2);
 out_put_keys:
 	put_futex_key(fshared, &key2);
 out_put_key1:
@@ -876,9 +885,7 @@ retry:
 		ret = get_futex_value_locked(&curval, uaddr1);
 
 		if (unlikely(ret)) {
-			spin_unlock(&hb1->lock);
-			if (hb1 != hb2)
-				spin_unlock(&hb2->lock);
+			double_unlock_hb(hb1, hb2);
 
 			put_futex_key(fshared, &key2);
 			put_futex_key(fshared, &key1);
@@ -925,9 +932,7 @@ retry:
 	}
 
 out_unlock:
-	spin_unlock(&hb1->lock);
-	if (hb1 != hb2)
-		spin_unlock(&hb2->lock);
+	double_unlock_hb(hb1, hb2);
 
 	/* drop_futex_key_refs() must be called outside the spinlocks. */
 	while (--drop_count >= 0)
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
futex: add double_unlock_hb(), Linux Kernel Mailing ..., (Sat Mar 28, 5:59 pm)