Re: [PATCH] Robust-futex wakes up the waiters will be missed

From: Peter Zijlstra
Date: Mon Nov 04 2019 - 04:17:17 EST


On Fri, Nov 01, 2019 at 10:03:09AM +0800, Yi Wang wrote:
> kernel/futex.c | 16 +++++++++++-----
> 1 file changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/futex.c b/kernel/futex.c
> index bd18f60..c2fb590 100644
> --- a/kernel/futex.c
> +++ b/kernel/futex.c
> @@ -3456,7 +3456,9 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
> * Process a futex-list entry, check whether it's owned by the
> * dying task, and do notification if so:
> */
> -static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi)
> +static int handle_futex_death(u32 __user *uaddr,
> + struct task_struct *curr, int pi,
> + bool pending)
> {
> u32 uval, uninitialized_var(nval), mval;
> int err;
> @@ -3469,6 +3471,10 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int p
> if (get_user(uval, uaddr))
> return -1;
>
> + /* Robust-futex wakes up the waiters will be missed*/
> + if (pending && !pi && uval == 0)
> + futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY);
> +

I'm thinking you're right and this should fix things, but that comment
is really terse and will not help us understand things the next time we
try and figure out what this code does.

> if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr))
> return 0;
>
> @@ -3590,7 +3596,7 @@ void exit_robust_list(struct task_struct *curr)
> */
> if (entry != pending)
> if (handle_futex_death((void __user *)entry + futex_offset,
> - curr, pi))
> + curr, pi, 0))
> return;
> if (rc)
> return;
> @@ -3607,7 +3613,7 @@ void exit_robust_list(struct task_struct *curr)
>
> if (pending)
> handle_futex_death((void __user *)pending + futex_offset,
> - curr, pip);
> + curr, pip, 1);
> }
>
> long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
> @@ -3784,7 +3790,7 @@ void compat_exit_robust_list(struct task_struct *curr)
> if (entry != pending) {
> void __user *uaddr = futex_uaddr(entry, futex_offset);
>
> - if (handle_futex_death(uaddr, curr, pi))
> + if (handle_futex_death(uaddr, curr, pi, 0))
> return;
> }
> if (rc)
> @@ -3803,7 +3809,7 @@ void compat_exit_robust_list(struct task_struct *curr)
> if (pending) {
> void __user *uaddr = futex_uaddr(pending, futex_offset);
>
> - handle_futex_death(uaddr, curr, pip);
> + handle_futex_death(uaddr, curr, pip, 1);
> }
> }
>
> --
> 2.15.2
>