diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -664,6 +664,7 @@ struct timespec uts, *ts; int error, save; uint32_t flags, val; + int no_compare; if (args->op & LINUX_FUTEX_PRIVATE_FLAG) { flags = 0; @@ -688,6 +689,7 @@ error = 0; f = f2 = NULL; + no_compare = 0; // for FUTEX_REQUEUE switch (args->op) { case LINUX_FUTEX_WAIT: @@ -767,6 +769,27 @@ futex_put(f, NULL); break; + case LINUX_FUTEX_REQUEUE: + /* + * Glibc does not use this operation since version 2.3.3, + * as it is racy and replaced by FUTEX_CMP_REQUEUE operation. + * Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when + * FUTEX_REQUEUE returned EINVAL. + */ + pem = pem_find(td->td_proc); + if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) { + linux_msg(td, "warn: deprecated FUTEX_REQUEUE"); + pem->flags |= LINUX_XDEPR_REQUEUEOP; + LIN_SDT_PROBE0(futex, linux_sys_futex, + deprecated_requeue); + } + /* + * The above is true, however musl libc does make use of the + * futex requeue operation, so we add support for it. + */ + no_compare = 1; + /* FALLTHROUGH */ + case LINUX_FUTEX_CMP_REQUEUE: LIN_SDT_PROBE5(futex, linux_sys_futex, debug_cmp_requeue, args->uaddr, args->val, args->val3, args->uaddr2, @@ -819,7 +842,7 @@ error); return (error); } - if (val != args->val3) { + if ((no_compare == 0) && val != args->val3) { LIN_SDT_PROBE2(futex, linux_sys_futex, debug_cmp_requeue_value_neq, args->val, val); LINUX_CTR2(sys_futex, "CMP_REQUEUE val 0x%x != uval 0x%x", @@ -931,22 +954,6 @@ } return (ENOSYS); - case LINUX_FUTEX_REQUEUE: - /* - * Glibc does not use this operation since version 2.3.3, - * as it is racy and replaced by FUTEX_CMP_REQUEUE operation. - * Glibc versions prior to 2.3.3 fall back to FUTEX_WAKE when - * FUTEX_REQUEUE returned EINVAL. - */ - pem = pem_find(td->td_proc); - if ((pem->flags & LINUX_XDEPR_REQUEUEOP) == 0) { - linux_msg(td, "unsupported FUTEX_REQUEUE"); - pem->flags |= LINUX_XDEPR_REQUEUEOP; - LIN_SDT_PROBE0(futex, linux_sys_futex, - deprecated_requeue); - } - return (EINVAL); - case LINUX_FUTEX_WAIT_REQUEUE_PI: /* not yet implemented */ pem = pem_find(td->td_proc);