Index: linux-2.6.13/kernel/futex.c =================================================================== --- linux-2.6.13.orig/kernel/futex.c +++ linux-2.6.13/kernel/futex.c @@ -1354,18 +1354,25 @@ static void find_owned_futex(struct vm_a if (uaddr == 0) continue; + up(&mapping->robust_sem); + up_read(¤t->mm->mmap_sem); + value = futex_get_user(uaddr); + if (this->futex_mutex.mutex_attr & FUTEX_ATTR_ROBUST) + value |= FUTEX_OWNER_DIED; if (rt_mutex_owned_by(&this->futex_mutex, ti)) { - up(&mapping->robust_sem); - up_read(¤t->mm->mmap_sem); - if (this->futex_mutex.mutex_attr & FUTEX_ATTR_ROBUST) { - value = futex_get_user(uaddr); - value |= FUTEX_OWNER_DIED; - futex_put_user(value, uaddr); - } + futex_put_user(value, uaddr); up_futex(&this->futex_mutex); - down(&mapping->robust_sem); - down_read(¤t->mm->mmap_sem); + } else if ((value & FUTEX_PID) == current->pid) { + /* + * this bit is for the fast path. If the lock is only + * locked in user space wee need to unlock it + * for the exiting thread. + */ + value &= ~FUTEX_PID; + futex_put_user(value, uaddr); } + down(&mapping->robust_sem); + down_read(¤t->mm->mmap_sem); } up(&mapping->robust_sem); @@ -1524,7 +1531,7 @@ static int futex_deregister(unsigned lon if (rt_mutex_owned_by(&this->futex_mutex, ti)) { up_futex(&this->futex_mutex); } else if (rt_mutex_owner(&this->futex_mutex) != NULL) { - ret = -EINVAL; + ret = -EBUSY; break; } list_del(&this->list); Index: linux-2.6.13/include/linux/futex.h =================================================================== --- linux-2.6.13.orig/include/linux/futex.h +++ linux-2.6.13/include/linux/futex.h @@ -1,8 +1,6 @@ #ifndef _LINUX_FUTEX_H #define _LINUX_FUTEX_H -#include - /* Second argument to futex syscall */ Index: linux-2.6.13/kernel/rt.c =================================================================== --- linux-2.6.13.orig/kernel/rt.c +++ linux-2.6.13/kernel/rt.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #define CAPTURE_LOCK