git: 407c7c339adb - main - linux/futex: Don't load a timeout when try-locking a mutex

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 07 Jul 2026 23:32:05 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=407c7c339adb429efcb6658accd16399031c34ca

commit 407c7c339adb429efcb6658accd16399031c34ca
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-07 22:52:56 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-07 23:28:55 +0000

    linux/futex: Don't load a timeout when try-locking a mutex
    
    linux_sys_futex() does not copyin a timespec for the timeout if the
    operation is LINUX_FUTEX_TRYLOCK_PI, presumably because it doesn't make
    sense to specify a timeout for a try-lock operation.  However, this
    means that we pass a userspace timespec pointer to
    linux_umtx_abs_timeout_init().
    
    Modify linux_futex_lock_pi() to not initialize the timeout if we're
    try-locking.
    
    Reviewed by:    kib, dchagin
    Reported by:    Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li,
                    and Ke Xu from Tsinghua University using GLM-5.2 from Z.ai
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58061
---
 sys/compat/linux/linux_futex.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c
index 0586eb55a8f3..2e26fb6458a3 100644
--- a/sys/compat/linux/linux_futex.c
+++ b/sys/compat/linux/linux_futex.c
@@ -356,7 +356,7 @@ linux_futex(struct thread *td, struct linux_futex_args *args)
 static int
 linux_futex_lock_pi(struct thread *td, bool try, struct linux_futex_args *args)
 {
-	struct umtx_abs_timeout timo;
+	struct umtx_abs_timeout timo, *timop;
 	struct linux_emuldata *em;
 	struct umtx_pi *pi, *new_pi;
 	struct thread *td1;
@@ -370,8 +370,12 @@ linux_futex_lock_pi(struct thread *td, bool try, struct linux_futex_args *args)
 	    &uq->uq_key);
 	if (error != 0)
 		return (error);
-	if (args->ts != NULL)
-		linux_umtx_abs_timeout_init(&timo, args);
+	if (!try && args->ts != NULL) {
+		timop = &timo;
+		linux_umtx_abs_timeout_init(timop, args);
+	} else {
+		timop = NULL;
+	}
 
 	umtxq_lock(&uq->uq_key);
 	pi = umtx_pi_lookup(&uq->uq_key);
@@ -546,8 +550,7 @@ linux_futex_lock_pi(struct thread *td, bool try, struct linux_futex_args *args)
 
 		/* We set the contested bit, sleep. */
 		error = umtxq_sleep_pi(uq, pi, owner, "futexp",
-		    args->ts == NULL ? NULL : &timo,
-		    (args->flags & FUTEX_SHARED) != 0);
+		    timop, (args->flags & FUTEX_SHARED) != 0);
 		if (error != 0)
 			continue;