[PATCH] fix i386 mutex fastpath on FRAME_POINTER && !DEBUG_MUTEXES
Ingo Molnar [Tue, 10 Jan 2006 21:07:44 +0000 (22:07 +0100)]
Call the mutex slowpath more conservatively - e.g.  FRAME_POINTERS can
change the calling convention, in which case a direct branch to the
slowpath becomes illegal.  Bug found by Hugh Dickins.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

include/asm-i386/mutex.h
kernel/mutex.c

index 4e5e3de..c657d4b 100644 (file)
@@ -28,7 +28,13 @@ do {                                                                 \
                                                                        \
        __asm__ __volatile__(                                           \
                LOCK    "   decl (%%eax)        \n"                     \
-                       "   js "#fail_fn"       \n"                     \
+                       "   js 2f               \n"                     \
+                       "1:                     \n"                     \
+                                                                       \
+               LOCK_SECTION_START("")                                  \
+                       "2: call "#fail_fn"     \n"                     \
+                       "   jmp 1b              \n"                     \
+               LOCK_SECTION_END                                        \
                                                                        \
                :"=a" (dummy)                                           \
                : "a" (count)                                           \
@@ -78,7 +84,13 @@ do {                                                                 \
                                                                        \
        __asm__ __volatile__(                                           \
                LOCK    "   incl (%%eax)        \n"                     \
-                       "   jle "#fail_fn"      \n"                     \
+                       "   jle 2f              \n"                     \
+                       "1:                     \n"                     \
+                                                                       \
+               LOCK_SECTION_START("")                                  \
+                       "2: call "#fail_fn"     \n"                     \
+                       "   jmp 1b              \n"                     \
+               LOCK_SECTION_END                                        \
                                                                        \
                :"=a" (dummy)                                           \
                : "a" (count)                                           \
index 7eb9606..d3dcb8b 100644 (file)
@@ -84,12 +84,6 @@ void fastcall __sched mutex_lock(struct mutex *lock)
        /*
         * The locking fastpath is the 1->0 transition from
         * 'unlocked' into 'locked' state.
-        *
-        * NOTE: if asm/mutex.h is included, then some architectures
-        * rely on mutex_lock() having _no other code_ here but this
-        * fastpath. That allows the assembly fastpath to do
-        * tail-merging optimizations. (If you want to put testcode
-        * here, do it under #ifndef CONFIG_MUTEX_DEBUG.)
         */
        __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath);
 }
@@ -115,8 +109,6 @@ void fastcall __sched mutex_unlock(struct mutex *lock)
        /*
         * The unlocking fastpath is the 0->1 transition from 'locked'
         * into 'unlocked' state:
-        *
-        * NOTE: no other code must be here - see mutex_lock() .
         */
        __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath);
 }
@@ -261,7 +253,6 @@ __mutex_lock_interruptible_slowpath(atomic_t *lock_count __IP_DECL__);
  */
 int fastcall __sched mutex_lock_interruptible(struct mutex *lock)
 {
-       /* NOTE: no other code must be here - see mutex_lock() */
        return __mutex_fastpath_lock_retval
                        (&lock->count, __mutex_lock_interruptible_slowpath);
 }