arch: Make __mutex_fastpath_lock_retval return whether fastpath succeeded or not
authorMaarten Lankhorst <maarten.lankhorst@canonical.com>
Thu, 20 Jun 2013 11:31:05 +0000 (13:31 +0200)
committerIngo Molnar <mingo@kernel.org>
Wed, 26 Jun 2013 10:10:55 +0000 (12:10 +0200)
This will allow me to call functions that have multiple
arguments if fastpath fails. This is required to support ticket
mutexes, because they need to be able to pass an extra argument
to the fail function.

Originally I duplicated the functions, by adding
__mutex_fastpath_lock_retval_arg. This ended up being just a
duplication of the existing function, so a way to test if
fastpath was called ended up being better.

This also cleaned up the reservation mutex patch some by being
able to call an atomic_set instead of atomic_xchg, and making it
easier to detect if the wrong unlock function was previously
used.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@canonical.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org
Cc: robclark@gmail.com
Cc: rostedt@goodmis.org
Cc: daniel@ffwll.ch
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20130620113105.4001.83929.stgit@patser
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/ia64/include/asm/mutex.h
arch/powerpc/include/asm/mutex.h
arch/sh/include/asm/mutex-llsc.h
arch/x86/include/asm/mutex_32.h
arch/x86/include/asm/mutex_64.h
include/asm-generic/mutex-dec.h
include/asm-generic/mutex-null.h
include/asm-generic/mutex-xchg.h
kernel/mutex.c

index bed73a643a56e3c0169a4fd43b705fcba491f5c8..f41e66d65e31c4b6c1eb15e9bdb0ee71d2018378 100644 (file)
@@ -29,17 +29,15 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns.
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
        if (unlikely(ia64_fetchadd4_acq(count, -1) != 1))
-               return fail_fn(count);
+               return -1;
        return 0;
 }
 
index 5399f7e18102f7144bcb1464ff5f13c2fac4468c..127ab23e1f6ccdbe038b6cfdd84c569742968e27 100644 (file)
@@ -82,17 +82,15 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns.
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
        if (unlikely(__mutex_dec_return_lock(count) < 0))
-               return fail_fn(count);
+               return -1;
        return 0;
 }
 
index 090358a7e1bbd6ff9da88a10282da83662ca9fd4..dad29b687bd33c18291523206985cb6b52dbdad0 100644 (file)
@@ -37,7 +37,7 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
 }
 
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
        int __done, __res;
 
@@ -51,7 +51,7 @@ __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
                : "t");
 
        if (unlikely(!__done || __res != 0))
-               __res = fail_fn(count);
+               __res = -1;
 
        return __res;
 }
index 03f90c8a5a7c392b7f50ea0914cba04b0718fa76..0208c3c2cbc6733e3053681a5430428d5cacff5e 100644 (file)
@@ -42,17 +42,14 @@ do {                                                                \
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
- * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
-static inline int __mutex_fastpath_lock_retval(atomic_t *count,
-                                              int (*fail_fn)(atomic_t *))
+static inline int __mutex_fastpath_lock_retval(atomic_t *count)
 {
        if (unlikely(atomic_dec_return(count) < 0))
-               return fail_fn(count);
+               return -1;
        else
                return 0;
 }
index 68a87b0f8e29e491e4b71c3c9eb68d78efb6db3c..2c543fff241bb85cb3b07c6cd1c19033380ffd3c 100644 (file)
@@ -37,17 +37,14 @@ do {                                                                \
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
-static inline int __mutex_fastpath_lock_retval(atomic_t *count,
-                                              int (*fail_fn)(atomic_t *))
+static inline int __mutex_fastpath_lock_retval(atomic_t *count)
 {
        if (unlikely(atomic_dec_return(count) < 0))
-               return fail_fn(count);
+               return -1;
        else
                return 0;
 }
index f104af7cf4375f045af902af4315834ae41460c2..d4f9fb4e53dfa7ea2709bc63f5c98f7c72e64cf0 100644 (file)
@@ -28,17 +28,15 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if
- * it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns.
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
        if (unlikely(atomic_dec_return(count) < 0))
-               return fail_fn(count);
+               return -1;
        return 0;
 }
 
index e1bbbc72b6a257adc7b5c1ad0dc95b9d615e0872..61069ed334e2208a31b2d15c4973bea9844db57a 100644 (file)
@@ -11,7 +11,7 @@
 #define _ASM_GENERIC_MUTEX_NULL_H
 
 #define __mutex_fastpath_lock(count, fail_fn)          fail_fn(count)
-#define __mutex_fastpath_lock_retval(count, fail_fn)   fail_fn(count)
+#define __mutex_fastpath_lock_retval(count)            (-1)
 #define __mutex_fastpath_unlock(count, fail_fn)                fail_fn(count)
 #define __mutex_fastpath_trylock(count, fail_fn)       fail_fn(count)
 #define __mutex_slowpath_needs_to_unlock()             1
index c04e0db8a2d6df273472a04bfb882aecdc0d54ce..f169ec064785beea6c8ce4f1bee1d193a9faf079 100644 (file)
@@ -39,18 +39,16 @@ __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
  *  __mutex_fastpath_lock_retval - try to take the lock by moving the count
  *                                 from 1 to a 0 value
  *  @count: pointer of type atomic_t
- *  @fail_fn: function to call if the original value was not 1
  *
- * Change the count from 1 to a value lower than 1, and call <fail_fn> if it
- * wasn't 1 originally. This function returns 0 if the fastpath succeeds,
- * or anything the slow path function returns
+ * Change the count from 1 to a value lower than 1. This function returns 0
+ * if the fastpath succeeds, or -1 otherwise.
  */
 static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
+__mutex_fastpath_lock_retval(atomic_t *count)
 {
        if (unlikely(atomic_xchg(count, 0) != 1))
                if (likely(atomic_xchg(count, -1) != 1))
-                       return fail_fn(count);
+                       return -1;
        return 0;
 }
 
index ad53a664f113b7036fc9abed4d7d73f0be5b2479..42f8dda2467b8fa828b55d4639de691a6451c210 100644 (file)
@@ -494,10 +494,10 @@ __mutex_unlock_slowpath(atomic_t *lock_count)
  * mutex_lock_interruptible() and mutex_trylock().
  */
 static noinline int __sched
-__mutex_lock_killable_slowpath(atomic_t *lock_count);
+__mutex_lock_killable_slowpath(struct mutex *lock);
 
 static noinline int __sched
-__mutex_lock_interruptible_slowpath(atomic_t *lock_count);
+__mutex_lock_interruptible_slowpath(struct mutex *lock);
 
 /**
  * mutex_lock_interruptible - acquire the mutex, interruptible
@@ -515,12 +515,12 @@ int __sched mutex_lock_interruptible(struct mutex *lock)
        int ret;
 
        might_sleep();
-       ret =  __mutex_fastpath_lock_retval
-                       (&lock->count, __mutex_lock_interruptible_slowpath);
-       if (!ret)
+       ret =  __mutex_fastpath_lock_retval(&lock->count);
+       if (likely(!ret)) {
                mutex_set_owner(lock);
-
-       return ret;
+               return 0;
+       } else
+               return __mutex_lock_interruptible_slowpath(lock);
 }
 
 EXPORT_SYMBOL(mutex_lock_interruptible);
@@ -530,12 +530,12 @@ int __sched mutex_lock_killable(struct mutex *lock)
        int ret;
 
        might_sleep();
-       ret = __mutex_fastpath_lock_retval
-                       (&lock->count, __mutex_lock_killable_slowpath);
-       if (!ret)
+       ret = __mutex_fastpath_lock_retval(&lock->count);
+       if (likely(!ret)) {
                mutex_set_owner(lock);
-
-       return ret;
+               return 0;
+       } else
+               return __mutex_lock_killable_slowpath(lock);
 }
 EXPORT_SYMBOL(mutex_lock_killable);
 
@@ -548,18 +548,14 @@ __mutex_lock_slowpath(atomic_t *lock_count)
 }
 
 static noinline int __sched
-__mutex_lock_killable_slowpath(atomic_t *lock_count)
+__mutex_lock_killable_slowpath(struct mutex *lock)
 {
-       struct mutex *lock = container_of(lock_count, struct mutex, count);
-
        return __mutex_lock_common(lock, TASK_KILLABLE, 0, NULL, _RET_IP_);
 }
 
 static noinline int __sched
-__mutex_lock_interruptible_slowpath(atomic_t *lock_count)
+__mutex_lock_interruptible_slowpath(struct mutex *lock)
 {
-       struct mutex *lock = container_of(lock_count, struct mutex, count);
-
        return __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, NULL, _RET_IP_);
 }
 #endif