Commit bd197234 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Linus Torvalds

Revert "futex_requeue_pi optimization"

This reverts commit d0aa7a70.

It not only introduced user space visible changes to the futex syscall,
it is also non-functional and there is no way to fix it proper before
the 2.6.22 release.

The breakage report ( http://lkml.org/lkml/2007/5/12/17 ) went
unanswered, and unfortunately it turned out that the concept is not
feasible at all.  It violates the rtmutex semantics badly by introducing
a virtual owner, which hacks around the coupling of the user-space
pi_futex and the kernel internal rt_mutex representation.

At the moment the only safe option is to remove it fully as it contains
user-space visible changes to broken kernel code, which we do not want
to expose in the 2.6.22 release.

The patch reverts the original patch mostly 1:1, but contains a couple
of trivial manual cleanups which were necessary due to patches, which
touched the same area of code later.

Verified against the glibc tests and my own PI futex tests.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarIngo Molnar <mingo@elte.hu>
Acked-by: default avatarUlrich Drepper <drepper@redhat.com>
Cc: Pierre Peiffer <pierre.peiffer@bull.net>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 188e1f81
...@@ -17,7 +17,6 @@ union ktime; ...@@ -17,7 +17,6 @@ union ktime;
#define FUTEX_LOCK_PI 6 #define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7 #define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8 #define FUTEX_TRYLOCK_PI 8
#define FUTEX_CMP_REQUEUE_PI 9
#define FUTEX_PRIVATE_FLAG 128 #define FUTEX_PRIVATE_FLAG 128
#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG #define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG
...@@ -97,15 +96,10 @@ struct robust_list_head { ...@@ -97,15 +96,10 @@ struct robust_list_head {
*/ */
#define FUTEX_OWNER_DIED 0x40000000 #define FUTEX_OWNER_DIED 0x40000000
/*
* Some processes have been requeued on this PI-futex
*/
#define FUTEX_WAITER_REQUEUED 0x20000000
/* /*
* The rest of the robust-futex field is for the TID: * The rest of the robust-futex field is for the TID:
*/ */
#define FUTEX_TID_MASK 0x0fffffff #define FUTEX_TID_MASK 0x3fffffff
/* /*
* This limit protects against a deliberately circular list. * This limit protects against a deliberately circular list.
...@@ -139,7 +133,6 @@ handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi); ...@@ -139,7 +133,6 @@ handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi);
#define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */ #define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */
union futex_key { union futex_key {
u32 __user *uaddr;
struct { struct {
unsigned long pgoff; unsigned long pgoff;
struct inode *inode; struct inode *inode;
......
This diff is collapsed.
...@@ -157,8 +157,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val, ...@@ -157,8 +157,7 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
t = ktime_add(ktime_get(), t); t = ktime_add(ktime_get(), t);
tp = &t; tp = &t;
} }
if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE if (cmd == FUTEX_REQUEUE || cmd == FUTEX_CMP_REQUEUE)
|| cmd == FUTEX_CMP_REQUEUE_PI)
val2 = (int) (unsigned long) utime; val2 = (int) (unsigned long) utime;
return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); return do_futex(uaddr, op, val, tp, uaddr2, val2, val3);
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
* state. * state.
*/ */
void static void
rt_mutex_set_owner(struct rt_mutex *lock, struct task_struct *owner, rt_mutex_set_owner(struct rt_mutex *lock, struct task_struct *owner,
unsigned long mask) unsigned long mask)
{ {
...@@ -80,6 +80,29 @@ static void fixup_rt_mutex_waiters(struct rt_mutex *lock) ...@@ -80,6 +80,29 @@ static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
clear_rt_mutex_waiters(lock); clear_rt_mutex_waiters(lock);
} }
/*
* We can speed up the acquire/release, if the architecture
* supports cmpxchg and if there's no debugging state to be set up
*/
#if defined(__HAVE_ARCH_CMPXCHG) && !defined(CONFIG_DEBUG_RT_MUTEXES)
# define rt_mutex_cmpxchg(l,c,n) (cmpxchg(&l->owner, c, n) == c)
static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
{
unsigned long owner, *p = (unsigned long *) &lock->owner;
do {
owner = *p;
} while (cmpxchg(p, owner, owner | RT_MUTEX_HAS_WAITERS) != owner);
}
#else
# define rt_mutex_cmpxchg(l,c,n) (0)
static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
{
lock->owner = (struct task_struct *)
((unsigned long)lock->owner | RT_MUTEX_HAS_WAITERS);
}
#endif
/* /*
* Calculate task priority from the waiter list priority * Calculate task priority from the waiter list priority
* *
...@@ -100,7 +123,7 @@ int rt_mutex_getprio(struct task_struct *task) ...@@ -100,7 +123,7 @@ int rt_mutex_getprio(struct task_struct *task)
* *
* This can be both boosting and unboosting. task->pi_lock must be held. * This can be both boosting and unboosting. task->pi_lock must be held.
*/ */
void __rt_mutex_adjust_prio(struct task_struct *task) static void __rt_mutex_adjust_prio(struct task_struct *task)
{ {
int prio = rt_mutex_getprio(task); int prio = rt_mutex_getprio(task);
...@@ -136,7 +159,7 @@ int max_lock_depth = 1024; ...@@ -136,7 +159,7 @@ int max_lock_depth = 1024;
* Decreases task's usage by one - may thus free the task. * Decreases task's usage by one - may thus free the task.
* Returns 0 or -EDEADLK. * Returns 0 or -EDEADLK.
*/ */
int rt_mutex_adjust_prio_chain(struct task_struct *task, static int rt_mutex_adjust_prio_chain(struct task_struct *task,
int deadlock_detect, int deadlock_detect,
struct rt_mutex *orig_lock, struct rt_mutex *orig_lock,
struct rt_mutex_waiter *orig_waiter, struct rt_mutex_waiter *orig_waiter,
...@@ -514,7 +537,7 @@ static void wakeup_next_waiter(struct rt_mutex *lock) ...@@ -514,7 +537,7 @@ static void wakeup_next_waiter(struct rt_mutex *lock)
* *
* Must be called with lock->wait_lock held * Must be called with lock->wait_lock held
*/ */
void remove_waiter(struct rt_mutex *lock, static void remove_waiter(struct rt_mutex *lock,
struct rt_mutex_waiter *waiter) struct rt_mutex_waiter *waiter)
{ {
int first = (waiter == rt_mutex_top_waiter(lock)); int first = (waiter == rt_mutex_top_waiter(lock));
......
...@@ -112,29 +112,6 @@ static inline unsigned long rt_mutex_owner_pending(struct rt_mutex *lock) ...@@ -112,29 +112,6 @@ static inline unsigned long rt_mutex_owner_pending(struct rt_mutex *lock)
return (unsigned long)lock->owner & RT_MUTEX_OWNER_PENDING; return (unsigned long)lock->owner & RT_MUTEX_OWNER_PENDING;
} }
/*
* We can speed up the acquire/release, if the architecture
* supports cmpxchg and if there's no debugging state to be set up
*/
#if defined(__HAVE_ARCH_CMPXCHG) && !defined(CONFIG_DEBUG_RT_MUTEXES)
# define rt_mutex_cmpxchg(l,c,n) (cmpxchg(&l->owner, c, n) == c)
static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
{
unsigned long owner, *p = (unsigned long *) &lock->owner;
do {
owner = *p;
} while (cmpxchg(p, owner, owner | RT_MUTEX_HAS_WAITERS) != owner);
}
#else
# define rt_mutex_cmpxchg(l,c,n) (0)
static inline void mark_rt_mutex_waiters(struct rt_mutex *lock)
{
lock->owner = (struct task_struct *)
((unsigned long)lock->owner | RT_MUTEX_HAS_WAITERS);
}
#endif
/* /*
* PI-futex support (proxy locking functions, etc.): * PI-futex support (proxy locking functions, etc.):
*/ */
...@@ -143,15 +120,4 @@ extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock, ...@@ -143,15 +120,4 @@ extern void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
struct task_struct *proxy_owner); struct task_struct *proxy_owner);
extern void rt_mutex_proxy_unlock(struct rt_mutex *lock, extern void rt_mutex_proxy_unlock(struct rt_mutex *lock,
struct task_struct *proxy_owner); struct task_struct *proxy_owner);
extern void rt_mutex_set_owner(struct rt_mutex *lock, struct task_struct *owner,
unsigned long mask);
extern void __rt_mutex_adjust_prio(struct task_struct *task);
extern int rt_mutex_adjust_prio_chain(struct task_struct *task,
int deadlock_detect,
struct rt_mutex *orig_lock,
struct rt_mutex_waiter *orig_waiter,
struct task_struct *top_task);
extern void remove_waiter(struct rt_mutex *lock,
struct rt_mutex_waiter *waiter);
#endif #endif
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