Skip to content

Commit

Permalink
[PATCH] lightweight robust futexes updates
Browse files Browse the repository at this point in the history
- fix: initialize the robust list(s) to NULL in copy_process.

- doc update

- cleanup: rename _inuser to _inatomic

- __user cleanups and other small cleanups

Signed-off-by: Ingo Molnar <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Arjan van de Ven <[email protected]>
Cc: Ulrich Drepper <[email protected]>
Cc: Andi Kleen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Ingo Molnar authored and Linus Torvalds committed Mar 27, 2006
1 parent 8fdd6c6 commit 8f17d3a
Show file tree
Hide file tree
Showing 12 changed files with 24 additions and 26 deletions.
2 changes: 0 additions & 2 deletions Documentation/robust-futex-ABI.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ On insertion:
of the 'lock word', to the linked list starting at 'head', and
4) clear the 'list_op_pending' word.

XXX I am particularly unsure of the following -pj XXX

On removal:
1) set the 'list_op_pending' word to the address of the 'lock word'
to be removed,
Expand Down
2 changes: 1 addition & 1 deletion Documentation/robust-futexes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,6 @@ robust-mutex testcases.
All other architectures should build just fine too - but they wont have
the new syscalls yet.

Architectures need to implement the new futex_atomic_cmpxchg_inuser()
Architectures need to implement the new futex_atomic_cmpxchg_inatomic()
inline function before writing up the syscalls (that function returns
-ENOSYS right now).
2 changes: 1 addition & 1 deletion include/asm-frv/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
extern int futex_atomic_op_inuser(int encoded_op, int __user *uaddr);

static inline int
futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
return -ENOSYS;
}
Expand Down
2 changes: 1 addition & 1 deletion include/asm-generic/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
}

static inline int
futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
return -ENOSYS;
}
Expand Down
2 changes: 1 addition & 1 deletion include/asm-i386/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
}

static inline int
futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
Expand Down
2 changes: 1 addition & 1 deletion include/asm-mips/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
}

static inline int
futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
return -ENOSYS;
}
Expand Down
2 changes: 1 addition & 1 deletion include/asm-powerpc/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
}

static inline int
futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
return -ENOSYS;
}
Expand Down
2 changes: 1 addition & 1 deletion include/asm-x86_64/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
}

static inline int
futex_atomic_cmpxchg_inuser(int __user *uaddr, int oldval, int newval)
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
Expand Down
2 changes: 1 addition & 1 deletion include/linux/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ long do_futex(unsigned long uaddr, int op, int val,
unsigned long timeout, unsigned long uaddr2, int val2,
int val3);

extern int handle_futex_death(unsigned int *uaddr, struct task_struct *curr);
extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr);

#ifdef CONFIG_FUTEX
extern void exit_robust_list(struct task_struct *curr);
Expand Down
5 changes: 4 additions & 1 deletion kernel/fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,10 @@ static task_t *copy_process(unsigned long clone_flags,
* Clear TID on mm_release()?
*/
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL;

p->robust_list = NULL;
#ifdef CONFIG_COMPAT
p->compat_robust_list = NULL;
#endif
/*
* sigaltstack should be cleared when sharing the same VM
*/
Expand Down
20 changes: 9 additions & 11 deletions kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -913,15 +913,15 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr,
* Process a futex-list entry, check whether it's owned by the
* dying task, and do notification if so:
*/
int handle_futex_death(unsigned int *uaddr, struct task_struct *curr)
int handle_futex_death(u32 __user *uaddr, struct task_struct *curr)
{
unsigned int futex_val;
u32 uval;

repeat:
if (get_user(futex_val, uaddr))
retry:
if (get_user(uval, uaddr))
return -1;

if ((futex_val & FUTEX_TID_MASK) == curr->pid) {
if ((uval & FUTEX_TID_MASK) == curr->pid) {
/*
* Ok, this dying thread is truly holding a futex
* of interest. Set the OWNER_DIED bit atomically
Expand All @@ -932,12 +932,11 @@ int handle_futex_death(unsigned int *uaddr, struct task_struct *curr)
* thread-death.) The rest of the cleanup is done in
* userspace.
*/
if (futex_atomic_cmpxchg_inuser(uaddr, futex_val,
futex_val | FUTEX_OWNER_DIED) !=
futex_val)
goto repeat;
if (futex_atomic_cmpxchg_inatomic(uaddr, uval,
uval | FUTEX_OWNER_DIED) != uval)
goto retry;

if (futex_val & FUTEX_WAITERS)
if (uval & FUTEX_WAITERS)
futex_wake((unsigned long)uaddr, 1);
}
return 0;
Expand Down Expand Up @@ -985,7 +984,6 @@ void exit_robust_list(struct task_struct *curr)
if (handle_futex_death((void *)entry + futex_offset,
curr))
return;

/*
* Fetch the next entry in the list:
*/
Expand Down
7 changes: 3 additions & 4 deletions kernel/futex_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ compat_sys_get_robust_list(int pid, compat_uptr_t *head_ptr,
return ret;
}

asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val,
asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, u32 val,
struct compat_timespec __user *utime, u32 __user *uaddr2,
int val3)
u32 val3)
{
struct timespec t;
unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
Expand All @@ -137,6 +137,5 @@ asmlinkage long compat_sys_futex(u32 __user *uaddr, int op, int val,
if (op >= FUTEX_REQUEUE)
val2 = (int) (unsigned long) utime;

return do_futex((unsigned long)uaddr, op, val, timeout,
(unsigned long)uaddr2, val2, val3);
return do_futex(uaddr, op, val, timeout, uaddr2, val2, val3);
}

0 comments on commit 8f17d3a

Please sign in to comment.