Skip to content
Permalink
Browse files
kernel: Enable waitpid() for futex2
To make pthreads works as expected if they are using futex2, wake
clear_child_tid with futex2 as well. This is make applications that uses
waitpid() (and clone(CLONE_CHILD_SETTID)) wake while waiting for the
child to terminate. Given that apps should not mix futex() and futex2(),
any correct app will trigger a harmless noop wakeup on the interface
that it isn't using.

Signed-off-by: André Almeida <andrealmeid@collabora.com>
---

This commit is here for the intend to show what we need to do in order
to get a full NPTL working on top of futex2. It should be merged after
we talk to glibc folks on the details around the futex_wait() side. For
instance, we could use this as an opportunity to use private futexes or
8bit sized futexes, but both sides need to use the exactly same flags.
  • Loading branch information
andrealmeid authored and damentz committed May 4, 2021
1 parent 3f97b7c commit 74b2323f995135be08649b48df710e78efcf7f62
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 12 deletions.
@@ -1315,6 +1315,8 @@ int ksys_ipc(unsigned int call, int first, unsigned long second,
unsigned long third, void __user * ptr, long fifth);
int compat_ksys_ipc(u32 call, int first, int second,
u32 third, u32 ptr, u32 fifth);
long ksys_futex_wake(void __user *uaddr, unsigned long nr_wake,
unsigned int flags);

/*
* The following kernel syscall equivalents are just wrappers to fs-internal
@@ -1316,6 +1316,8 @@ static void mm_release(struct task_struct *tsk, struct mm_struct *mm)
put_user(0, tsk->clear_child_tid);
do_futex(tsk->clear_child_tid, FUTEX_WAKE,
1, NULL, NULL, 0, 0);
ksys_futex_wake(tsk->clear_child_tid, 1,
FUTEX_32 | FUTEX_SHARED_FLAG);
}
tsk->clear_child_tid = NULL;
}
@@ -928,18 +928,8 @@ static inline bool futex_match(struct futex_key key1, struct futex_key key2)
key1.offset == key2.offset);
}

/**
* sys_futex_wake - Wake a number of futexes waiting on an address
* @uaddr: Address of futex to be woken up
* @nr_wake: Number of futexes waiting in uaddr to be woken up
* @flags: Flags for size and shared
*
* Wake `nr_wake` threads waiting at uaddr.
*
* Returns the number of woken threads on success, error code otherwise.
*/
SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake,
unsigned int, flags)
long ksys_futex_wake(void __user *uaddr, unsigned long nr_wake,
unsigned int flags)
{
bool shared = (flags & FUTEX_SHARED_FLAG) ? true : false;
unsigned int size = flags & FUTEX_SIZE_MASK;
@@ -976,6 +966,22 @@ SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake,
return ret;
}

/**
* sys_futex_wake - Wake a number of futexes waiting on an address
* @uaddr: Address of futex to be woken up
* @nr_wake: Number of futexes waiting in uaddr to be woken up
* @flags: Flags for size and shared
*
* Wake `nr_wake` threads waiting at uaddr.
*
* Returns the number of woken threads on success, error code otherwise.
*/
SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake,
unsigned int, flags)
{
return ksys_futex_wake(uaddr, nr_wake, flags);
}

static void futex_double_unlock(struct futex_bucket *b1, struct futex_bucket *b2)
{
spin_unlock(&b1->lock);

0 comments on commit 74b2323

Please sign in to comment.