Module Name: src Committed By: riastradh Date: Sat Jan 18 07:26:06 UTC 2025
Modified Files: src/sys/kern: sys_futex.c src/tests/lib/libc/sys: t_futex_ops.c Log Message: futex(2): Fix FUTEX_CMP_REQUEUE to always compare even if no waiters. It must always compare the futex value and fail with EAGAIN on mismatch, even if there are no waiters. FUTEX_CMP_REQUEUE (since Linux 2.6.7) This operation first checks whether the location uaddr still contains the value val3. If not, the operation fails with the error EAGAIN. Otherwise, the operation [...] https://man7.org/linux/man-pages/man2/futex.2.html PR kern/56828: futex calls in Linux emulation sometimes hang To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/kern/sys_futex.c cvs rdiff -u -r1.8 -r1.9 src/tests/lib/libc/sys/t_futex_ops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/sys_futex.c diff -u src/sys/kern/sys_futex.c:1.20 src/sys/kern/sys_futex.c:1.21 --- src/sys/kern/sys_futex.c:1.20 Thu Apr 11 13:51:36 2024 +++ src/sys/kern/sys_futex.c Sat Jan 18 07:26:06 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: sys_futex.c,v 1.20 2024/04/11 13:51:36 riastradh Exp $ */ +/* $NetBSD: sys_futex.c,v 1.21 2025/01/18 07:26:06 riastradh Exp $ */ /*- * Copyright (c) 2018, 2019, 2020 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.20 2024/04/11 13:51:36 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sys_futex.c,v 1.21 2025/01/18 07:26:06 riastradh Exp $"); /* * Futexes @@ -1336,14 +1336,23 @@ futex_func_requeue(bool shared, int op, goto out; } - /* Look up the source futex, if any. */ - error = futex_lookup(uaddr, shared, &f); + /* + * Look up or create the source futex. For FUTEX_CMP_REQUEUE, + * we always create it, rather than bail if it has no waiters, + * because FUTEX_CMP_REQUEUE always tests the futex word in + * order to report EAGAIN. + */ + error = (op == FUTEX_CMP_REQUEUE + ? futex_lookup_create(uaddr, shared, &f) + : futex_lookup(uaddr, shared, &f)); if (error) goto out; - /* If there is none, nothing to do. */ - if (f == NULL) + /* If there is none for FUTEX_REQUEUE, nothing to do. */ + if (f == NULL) { + KASSERT(op != FUTEX_CMP_REQUEUE); goto out; + } /* * We may need to create the destination futex because it's Index: src/tests/lib/libc/sys/t_futex_ops.c diff -u src/tests/lib/libc/sys/t_futex_ops.c:1.8 src/tests/lib/libc/sys/t_futex_ops.c:1.9 --- src/tests/lib/libc/sys/t_futex_ops.c:1.8 Sat Jan 18 07:05:15 2025 +++ src/tests/lib/libc/sys/t_futex_ops.c Sat Jan 18 07:26:06 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: t_futex_ops.c,v 1.8 2025/01/18 07:05:15 riastradh Exp $ */ +/* $NetBSD: t_futex_ops.c,v 1.9 2025/01/18 07:26:06 riastradh Exp $ */ /*- * Copyright (c) 2019, 2020 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ #include <sys/cdefs.h> __COPYRIGHT("@(#) Copyright (c) 2019, 2020\ The NetBSD Foundation, inc. All rights reserved."); -__RCSID("$NetBSD: t_futex_ops.c,v 1.8 2025/01/18 07:05:15 riastradh Exp $"); +__RCSID("$NetBSD: t_futex_ops.c,v 1.9 2025/01/18 07:26:06 riastradh Exp $"); #include <sys/fcntl.h> #include <sys/mman.h> @@ -927,13 +927,10 @@ ATF_TC_BODY(futex_cmp_requeue_trivial, t futex_word = 123; futex_word1 = 456; /* should be ignored */ - atf_tc_expect_fail("PR kern/56828:" - " futex calls in Linux emulation sometimes hang"); ATF_CHECK_ERRNO(EAGAIN, __futex(&futex_word, FUTEX_CMP_REQUEUE, /*nwake*/1, NULL, &futex_word1, /*nrequeue*/1, 0) == -1); ATF_CHECK_ERRNO(EAGAIN, __futex(&futex_word, FUTEX_CMP_REQUEUE, /*nwake*/1, NULL, &futex_word1, /*nrequeue*/1, 122) == -1); - atf_tc_expect_pass(); nwoken = __futex(&futex_word, FUTEX_CMP_REQUEUE, /*nwake*/1, NULL, &futex_word1, /*nrequeue*/1, 123); ATF_CHECK_MSG(nwoken != -1, "errno=%d (%s)", errno, strerror(errno));