From patchwork Mon Jun 21 11:16:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kurt Kanzenbach X-Patchwork-Id: 43929 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A4B7B389683C for ; Mon, 21 Jun 2021 11:21:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A4B7B389683C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1624274464; bh=SMwqXTZ4uLqd9fi30wR6RF8ajsp6+eRpzhW9EvbhUhM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=lNZqcrJR1pL8gO79bQn1LZh17l5qfhXPWODU1OOt461cfwHmdQUmxHY6MGI7lsizo C0fcwoIeRs9NVACVR8JtdbrKszTebPCVZGLb/P4ZVtbjwA89jQ+ZpN9YnR1ZaWVSP1 n9TUfRrhIlpBCNbG1evMZUpLy/XjsQwp1AVgd8Lo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by sourceware.org (Postfix) with ESMTPS id 75953393A426 for ; Mon, 21 Jun 2021 11:17:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 75953393A426 To: libc-alpha@sourceware.org Subject: [PATCH RFC 2/3] nptl: Use futex_lock_pi2() Date: Mon, 21 Jun 2021 13:16:49 +0200 Message-Id: <20210621111650.1164689-3-kurt@linutronix.de> In-Reply-To: <20210621111650.1164689-1-kurt@linutronix.de> References: <20210621111650.1164689-1-kurt@linutronix.de> MIME-Version: 1.0 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Kurt Kanzenbach via Libc-alpha From: Kurt Kanzenbach Reply-To: Kurt Kanzenbach Cc: Florian Weimer , Sebastian Andrzej Siewior , Kurt Kanzenbach , Thomas Gleixner Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Use futex_lock_pi2() by default, because it supports selectable clocks. On older kernels futex_lock_pi2() will return ENOSYS. Fallback to futex_lock_pi() and don't support CLOCK_MONOTONIC then. Signed-off-by: Kurt Kanzenbach --- nptl/pthread_mutex_timedlock.c | 24 ++++++++++++++++++------ sysdeps/nptl/futex-internal.h | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c index 5afd6222d61e..e7e001d2c17a 100644 --- a/nptl/pthread_mutex_timedlock.c +++ b/nptl/pthread_mutex_timedlock.c @@ -300,11 +300,15 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: { - /* Currently futex FUTEX_LOCK_PI operation only provides support for - CLOCK_REALTIME and trying to emulate by converting a - CLOCK_MONOTONIC to CLOCK_REALTIME will take in account possible - changes to the wall clock. */ - if (__glibc_unlikely (clockid != CLOCK_REALTIME)) + /* Currently futex FUTEX_LOCK_PI operation only provides support for + CLOCK_REALTIME and trying to emulate by converting a + CLOCK_MONOTONIC to CLOCK_REALTIME will take in account possible + changes to the wall clock. + + However, newer Linux kernels support FUTEX_LOCK_PI2 with selectable + clock support. */ + if (__glibc_unlikely (! futex_lockpi2_supported () && + clockid != CLOCK_REALTIME)) return EINVAL; int kind, robust; @@ -370,7 +374,15 @@ __pthread_mutex_clocklock_common (pthread_mutex_t *mutex, int private = (robust ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex) : PTHREAD_MUTEX_PSHARED (mutex)); - int e = futex_lock_pi64 (&mutex->__data.__lock, abstime, private); + int e = futex_lock_pi2_64 (&mutex->__data.__lock, clockid, abstime, + private); + + /* Use futex futex_lock_pi2() by default. This doesn't work for + older kernels. So fallback to futex_lock_pi() then. The clockid + is checked above already. */ + if (__glibc_unlikely (e == ENOSYS)) + e = futex_lock_pi64 (&mutex->__data.__lock, abstime, private); + if (e == ETIMEDOUT) return ETIMEDOUT; else if (e == ESRCH || e == EDEADLK) diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h index 60bdae84405c..b5f101b484c2 100644 --- a/sysdeps/nptl/futex-internal.h +++ b/sysdeps/nptl/futex-internal.h @@ -372,6 +372,23 @@ futex_lock_pi2_64 (int *futex_word, clockid_t clockid, } } +/* Checks whether FUTEX_LOCK_PI2 operation is available on the running Linux + kernel. FUTEX_LOCK_PI2 has been introduced on newer kernel versions. + + Returns true if FUTEX_LOCK_PI2 is available, false otherwise. */ +static __always_inline bool +futex_lockpi2_supported (void) +{ + int err = INTERNAL_SYSCALL_CALL (futex_time64, NULL, FUTEX_LOCK_PI2, 0, NULL); + +#ifndef __ASSUME_TIME64_SYSCALLS + if (err == -ENOSYS) + err = INTERNAL_SYSCALL_CALL (futex, NULL, FUTEX_LOCK_PI2, 0, NULL); +#endif + + return err != -ENOSYS; +} + /* Wakes the top priority waiter that called a futex_lock_pi operation on the futex.