* [PATCH 00/14] vdso: Add support for auxiliary clocks
@ 2025-07-01 8:57 Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 01/14] selftests/timers: Add testcase " Thomas Weißschuh
` (13 more replies)
0 siblings, 14 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:57 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Extend the vDSO for fast-path access to auxiliary clocks (CLOCK_AUX).
The implementation is based on the generic vDSO infrastructure and works for
all its supported architectures.
Namely x86, arm, arm64, riscv, powerpc, loongarch and s390.
No changes to userspace are necessary.
Based on timers/ptp of tip.git.
This also depends on v6.16-rc2 *exactly*.
The specific dependency is commit 11fcf368506d ("uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again"),
which is available in v6.16-rc2.
Unfortunately that got broken again in v6.16-rc3 by
commit fc92099902fb ("tools headers: Synchronize linux/bits.h with the kernel sources").
Another fix for this is pending [0] and should make it into v6.16.
[0] https://lore.kernel.org/lkml/20250630-uapi-genmask-v1-1-eb0ad956a83e@linutronix.de/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
Thomas Weißschuh (14):
selftests/timers: Add testcase for auxiliary clocks
vdso/vsyscall: Introduce a helper to fill clock configurations
vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock()
vdso/helpers: Add helpers for seqlocks of single vdso_clock
vdso/gettimeofday: Return bool from clock_getres() helpers
vdso/gettimeofday: Return bool from clock_gettime() helpers
vdso/gettimeofday: Introduce vdso_clockid_valid()
vdso/gettimeofday: Introduce vdso_set_timespec()
vdso/gettimeofday: Introduce vdso_get_timestamp()
vdso: Introduce aux_clock_resolution_ns()
vdso/vsyscall: Update auxiliary clock data in the datapage
vdso/gettimeofday: Add support for auxiliary clocks
Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers"
selftests/timers/auxclock: Test vDSO functionality
arch/arm64/include/asm/vdso/vsyscall.h | 7 +-
include/asm-generic/vdso/vsyscall.h | 6 +-
include/linux/timekeeper_internal.h | 13 +
include/vdso/auxclock.h | 13 +
include/vdso/datapage.h | 5 +
include/vdso/helpers.h | 40 ++-
kernel/time/namespace.c | 5 +
kernel/time/timekeeping.c | 18 +-
kernel/time/vsyscall.c | 70 ++++--
lib/vdso/gettimeofday.c | 212 ++++++++++------
tools/testing/selftests/timers/.gitignore | 1 +
tools/testing/selftests/timers/Makefile | 2 +-
tools/testing/selftests/timers/auxclock.c | 406 ++++++++++++++++++++++++++++++
tools/testing/selftests/vDSO/Makefile | 2 -
tools/testing/selftests/vDSO/parse_vdso.c | 3 +-
15 files changed, 683 insertions(+), 120 deletions(-)
---
base-commit: 4e83b31e48cf2e62aeaed5cd9875c851e36a90d9
change-id: 20250630-vdso-auxclock-97abdf8e042a
Best regards,
--
Thomas Weißschuh <thomas.weissschuh@linutronix.de>
^ permalink raw reply [flat|nested] 72+ messages in thread
* [PATCH 01/14] selftests/timers: Add testcase for auxiliary clocks
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
@ 2025-07-01 8:57 ` Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 02/14] vdso/vsyscall: Introduce a helper to fill clock configurations Thomas Weißschuh
` (12 subsequent siblings)
13 siblings, 0 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:57 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Auxiliary clocks behave differently from regular ones.
Add a testcase to validate their functionality.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
tools/testing/selftests/timers/.gitignore | 1 +
tools/testing/selftests/timers/Makefile | 2 +-
tools/testing/selftests/timers/auxclock.c | 319 ++++++++++++++++++++++++++++++
3 files changed, 321 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/timers/.gitignore b/tools/testing/selftests/timers/.gitignore
index bb5326ff900b8edc3aa2d8d596599973593fbaf0..dcee43b3ecd9351c9bb0483088d712ccd7b57367 100644
--- a/tools/testing/selftests/timers/.gitignore
+++ b/tools/testing/selftests/timers/.gitignore
@@ -20,3 +20,4 @@ valid-adjtimex
adjtick
set-tz
freq-step
+auxclock
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 32203593c62e1e0cdfd3de6f567ea1e82913f2ef..3a8833b3fb7449495c66a92c4d82e35a6755b5e8 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -5,7 +5,7 @@ LDLIBS += -lrt -lpthread -lm
# these are all "safe" tests that don't modify
# system time or require escalated privileges
TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
- inconsistency-check raw_skew threadtest rtcpie
+ inconsistency-check raw_skew threadtest rtcpie auxclock
DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \
skew_consistency clocksource-switch freq-step leap-a-day \
diff --git a/tools/testing/selftests/timers/auxclock.c b/tools/testing/selftests/timers/auxclock.c
new file mode 100644
index 0000000000000000000000000000000000000000..0ba2f9996114ade3147f0f3aec49904556a23cd4
--- /dev/null
+++ b/tools/testing/selftests/timers/auxclock.c
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/* Work around type conflicts between libc and the UAPI headers */
+#define _SYS_TIME_H
+#define __timeval_defined
+#define _GNU_SOURCE
+
+#include <fcntl.h>
+#include <linux/types.h>
+#include <linux/timex.h>
+#include <sched.h>
+#include <stdio.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#include "../kselftest_harness.h"
+
+#ifndef CLOCK_AUX
+#define CLOCK_AUX 16
+#endif
+
+#ifndef NSEC_PER_SEC
+#define NSEC_PER_SEC 1000000000ULL
+#endif
+
+#define AUXCLOCK_SELFTEST_TIMENS_OFFSET 10000
+
+static int configure_auxclock(__kernel_clockid_t clockid, bool enable)
+{
+ char path[100];
+ int fd, ret;
+
+ ret = snprintf(path, sizeof(path),
+ "/sys/kernel/time/aux_clocks/%d/aux_clock_enable",
+ (int)clockid - CLOCK_AUX);
+ if (ret >= sizeof(path))
+ return -ENOSPC;
+
+ fd = open(path, O_WRONLY);
+ if (fd == -1)
+ return -errno;
+
+ /* Always disable to reset */
+ ret = dprintf(fd, "0\n");
+ if (enable)
+ ret = dprintf(fd, "1\n");
+ close(fd);
+
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+/* Everything is done in terms of 64bit time values to keep the code readable */
+
+static inline void timespec_to_kernel_timespec(const struct timespec *ts,
+ struct __kernel_timespec *kts)
+{
+ if (!kts)
+ return;
+
+ kts->tv_sec = ts->tv_sec;
+ kts->tv_nsec = ts->tv_nsec;
+}
+
+static inline void kernel_timespec_to_timespec(const struct __kernel_timespec *kts,
+ struct timespec *ts)
+{
+ if (!kts)
+ return;
+
+ ts->tv_sec = kts->tv_sec;
+ ts->tv_nsec = kts->tv_nsec;
+}
+
+static int sys_clock_getres_time64(__kernel_clockid_t clockid, struct __kernel_timespec *ts)
+{
+#if defined(__NR_clock_getres_time64)
+ return syscall(__NR_clock_getres_time64, clockid, ts);
+#elif defined(__NR_clock_getres)
+ struct timespec _ts;
+ int ret;
+
+ ret = syscall(__NR_clock_getres, clockid, &_ts);
+ if (!ret)
+ timespec_to_kernel_timespec(&_ts, ts);
+ return ret;
+#else
+#error "No clock_getres() support"
+#endif
+}
+
+static int sys_clock_gettime64(__kernel_clockid_t clockid, struct __kernel_timespec *ts)
+{
+#if defined(__NR_clock_gettime64)
+ return syscall(__NR_clock_gettime64, clockid, ts);
+#elif defined(__NR_clock_gettime)
+ struct timespec _ts;
+ int ret;
+
+ ret = syscall(__NR_clock_gettime, clockid, &_ts);
+ if (!ret)
+ timespec_to_kernel_timespec(&_ts, ts);
+ return ret;
+#else
+#error "No clock_gettime() support"
+#endif
+}
+
+static int sys_clock_settime64(__kernel_clockid_t clockid, const struct __kernel_timespec *ts)
+{
+#if defined(__NR_clock_settime64)
+ return syscall(__NR_clock_settime64, clockid, ts);
+#elif defined(__NR_clock_settime)
+ struct timespec _ts;
+
+ kernel_timespec_to_timespec(ts, &_ts);
+ return syscall(__NR_clock_settime, clockid, &_ts);
+#else
+#error "No clock_settime() support"
+#endif
+}
+
+static int sys_clock_adjtime64(__kernel_clockid_t clockid, struct __kernel_timex *tx)
+{
+#if defined(__NR_clock_adjtime64)
+ return syscall(__NR_clock_adjtime64, clockid, tx);
+#elif __LONG_WIDTH__ == 64 && defined(__NR_clock_adjtime)
+ return syscall(__NR_clock_adjtime, clockid, tx);
+#else
+#error "No clock_adjtime() support"
+#endif
+}
+
+FIXTURE(auxclock) {};
+
+FIXTURE_VARIANT(auxclock) {
+ __kernel_clockid_t clock;
+ bool clock_enabled;
+ bool use_timens;
+};
+
+FIXTURE_VARIANT_ADD(auxclock, default) {
+ .clock = CLOCK_AUX,
+ .clock_enabled = true,
+ .use_timens = false,
+};
+
+FIXTURE_VARIANT_ADD(auxclock, timens) {
+ .clock = CLOCK_AUX,
+ .clock_enabled = true,
+ .use_timens = true,
+};
+
+FIXTURE_VARIANT_ADD(auxclock, disabled) {
+ .clock = CLOCK_AUX,
+ .clock_enabled = false,
+ .use_timens = false,
+};
+
+/* No timens_disabled to keep the testmatrix smaller. */
+
+static void enter_timens(struct __test_metadata *_metadata)
+{
+ int ret, fd;
+ char buf[100];
+
+ ret = unshare(CLONE_NEWTIME);
+ if (ret != 0 && errno == EPERM)
+ SKIP(return, "no permissions for unshare(CLONE_NEWTIME)");
+ if (ret != 0 && errno == EINVAL)
+ SKIP(return, "time namespaces not available");
+ ASSERT_EQ(0, ret) TH_LOG("unshare(CLONE_NEWTIME) failed: %s", strerror(errno));
+ fd = open("/proc/self/timens_offsets", O_WRONLY);
+ if (fd == -1 && errno == ENOENT)
+ SKIP(return, "no support for time namespaces");
+ ASSERT_NE(-1, fd);
+ /* Fiddle with the namespace to make the tests more meaningful */
+ ret = snprintf(buf, sizeof(buf), "monotonic %d 0\nboottime %d 0\n",
+ AUXCLOCK_SELFTEST_TIMENS_OFFSET, AUXCLOCK_SELFTEST_TIMENS_OFFSET);
+ ASSERT_TRUE(ret > 0 && ret < sizeof(buf));
+ ret = write(fd, buf, ret);
+ ASSERT_NE(-1, ret);
+ close(fd);
+ fd = open("/proc/self/ns/time_for_children", O_RDONLY);
+ ASSERT_NE(-1, fd);
+ ret = setns(fd, CLONE_NEWTIME);
+ close(fd);
+ ASSERT_EQ(0, ret);
+}
+
+FIXTURE_SETUP(auxclock) {
+ int ret;
+
+ ret = configure_auxclock(variant->clock, variant->clock_enabled);
+ if (ret == -ENOENT)
+ SKIP(return, "auxclocks not enabled");
+ ASSERT_EQ(0, ret);
+
+ if (variant->use_timens)
+ enter_timens(_metadata);
+}
+
+FIXTURE_TEARDOWN(auxclock) {
+ int ret;
+
+ ret = configure_auxclock(variant->clock, false);
+ ASSERT_EQ(0, ret);
+}
+
+TEST_F(auxclock, sys_clock_getres) {
+ struct __kernel_timespec ts;
+ int ret;
+
+ /* clock_getres() is always expected to work */
+ ret = sys_clock_getres_time64(variant->clock, &ts);
+ ASSERT_EQ(0, ret);
+ ASSERT_EQ(0, ts.tv_sec);
+ ASSERT_EQ(1, ts.tv_nsec);
+}
+
+TEST_F(auxclock, sys_clock_gettime) {
+ struct __kernel_timespec ts;
+ int ret;
+
+ ret = sys_clock_gettime64(variant->clock, &ts);
+ if (variant->clock_enabled) {
+ ASSERT_EQ(0, ret);
+ } else {
+ ASSERT_EQ(-1, ret);
+ ASSERT_EQ(ENODEV, errno);
+ }
+}
+
+static void auxclock_validate_progression(struct __test_metadata *_metadata,
+ const struct __kernel_timespec *a,
+ const struct __kernel_timespec *b)
+{
+ int64_t diff;
+
+ diff = (b->tv_sec - a->tv_sec) * NSEC_PER_SEC;
+ diff += b->tv_nsec - a->tv_nsec;
+
+ /* Arbitrary values */
+ ASSERT_LT(1, diff);
+ ASSERT_GT(1 * NSEC_PER_SEC, diff);
+}
+
+TEST_F(auxclock, sys_clock_settime) {
+ struct __kernel_timespec a, b = {};
+ int ret;
+
+ a.tv_sec = 1234;
+ a.tv_nsec = 5678;
+
+ ret = sys_clock_settime64(variant->clock, &a);
+ if (!variant->clock_enabled) {
+ ASSERT_EQ(-1, ret);
+ ASSERT_EQ(ENODEV, errno);
+ return;
+ }
+
+ ASSERT_EQ(0, ret);
+
+ ret = sys_clock_gettime64(variant->clock, &b);
+ ASSERT_EQ(0, ret);
+
+ auxclock_validate_progression(_metadata, &a, &b);
+}
+
+TEST_F(auxclock, sys_clock_adjtime) {
+ struct __kernel_timex tx;
+ int ret, realtime_freq;
+
+ memset(&tx, 0, sizeof(tx));
+ tx.modes = ADJ_FREQUENCY;
+ ret = sys_clock_adjtime64(CLOCK_REALTIME, &tx);
+ ASSERT_NE(-1, ret);
+ ASSERT_TRUE(tx.modes & ADJ_FREQUENCY);
+ realtime_freq = tx.freq;
+
+ ret = sys_clock_adjtime64(variant->clock, &tx);
+ if (variant->clock_enabled) {
+ ASSERT_NE(-1, ret);
+ ASSERT_EQ(realtime_freq, tx.freq);
+ } else {
+ ASSERT_EQ(-1, ret);
+ ASSERT_EQ(ENODEV, errno);
+ }
+}
+
+TEST_F(auxclock, progression) {
+ struct __kernel_timespec a, b;
+ int ret;
+
+ if (!variant->clock_enabled) {
+ TH_LOG("no progression on disabled clocks");
+ return;
+ }
+
+ /* set up reference */
+ ret = sys_clock_gettime64(variant->clock, &a);
+ ASSERT_EQ(0, ret);
+
+ for (int i = 0; i < 100; i++) {
+ memset(&b, 0, sizeof(b));
+ ret = sys_clock_gettime64(variant->clock, &b);
+ ASSERT_EQ(0, ret);
+ auxclock_validate_progression(_metadata, &a, &b);
+
+ memset(&a, 0, sizeof(a));
+ ret = sys_clock_gettime64(variant->clock, &a);
+ ASSERT_EQ(0, ret);
+ auxclock_validate_progression(_metadata, &b, &a);
+ }
+}
+
+TEST_HARNESS_MAIN
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 02/14] vdso/vsyscall: Introduce a helper to fill clock configurations
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 01/14] selftests/timers: Add testcase " Thomas Weißschuh
@ 2025-07-01 8:57 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 03/14] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock() Thomas Weißschuh
` (11 subsequent siblings)
13 siblings, 2 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:57 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
The logic to configure a 'struct vdso_clock' from a
'struct tk_read_base' is copied two times.
Split it into a shared function to reduce the duplication,
especially as another user will be added for auxiliary clocks.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
kernel/time/vsyscall.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index 32ef27c71b57aaa4ed898c0dbfdefcb73b8ff56a..d655df2597336f7305bfc74e2a87c651f314267b 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -15,26 +15,25 @@
#include "timekeeping_internal.h"
+static inline void fill_clock_configuration(struct vdso_clock *vc, const struct tk_read_base *base)
+{
+ vc->cycle_last = base->cycle_last;
+#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
+ vc->max_cycles = base->clock->max_cycles;
+#endif
+ vc->mask = base->mask;
+ vc->mult = base->mult;
+ vc->shift = base->shift;
+}
+
static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
{
struct vdso_clock *vc = vdata->clock_data;
struct vdso_timestamp *vdso_ts;
u64 nsec, sec;
- vc[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
-#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vc[CS_HRES_COARSE].max_cycles = tk->tkr_mono.clock->max_cycles;
-#endif
- vc[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
- vc[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
- vc[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
- vc[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
-#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vc[CS_RAW].max_cycles = tk->tkr_raw.clock->max_cycles;
-#endif
- vc[CS_RAW].mask = tk->tkr_raw.mask;
- vc[CS_RAW].mult = tk->tkr_raw.mult;
- vc[CS_RAW].shift = tk->tkr_raw.shift;
+ fill_clock_configuration(&vc[CS_HRES_COARSE], &tk->tkr_mono);
+ fill_clock_configuration(&vc[CS_RAW], &tk->tkr_raw);
/* CLOCK_MONOTONIC */
vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 03/14] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock()
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 01/14] selftests/timers: Add testcase " Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 02/14] vdso/vsyscall: Introduce a helper to fill clock configurations Thomas Weißschuh
@ 2025-07-01 8:57 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 04/14] vdso/helpers: Add helpers for seqlocks of single vdso_clock Thomas Weißschuh
` (10 subsequent siblings)
13 siblings, 2 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:57 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
The upcoming auxiliary clocks need this hook, too.
To separate the architecture hooks from the timekeeper internals, refactor
the hook to only operate on a single vDSO clock.
While at it, use a more robust #define for the hook override.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
arch/arm64/include/asm/vdso/vsyscall.h | 7 +++----
include/asm-generic/vdso/vsyscall.h | 6 +++---
kernel/time/vsyscall.c | 3 ++-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index de58951b8df6a4bb9afd411878793c79c30adbf2..417aae5763a86f39acffe1e6f96cb0e57212d04b 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -13,12 +13,11 @@
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
static __always_inline
-void __arm64_update_vsyscall(struct vdso_time_data *vdata)
+void __arch_update_vdso_clock(struct vdso_clock *vc)
{
- vdata->clock_data[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
- vdata->clock_data[CS_RAW].mask = VDSO_PRECISION_MASK;
+ vc->mask = VDSO_PRECISION_MASK;
}
-#define __arch_update_vsyscall __arm64_update_vsyscall
+#define __arch_update_vdso_clock __arch_update_vdso_clock
/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index b550afa15ecd101d821f51ce9105903978dced40..7fc0b560007dd8f09a2f24ace76ce68579ad17c1 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -22,11 +22,11 @@ static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(vo
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
-#ifndef __arch_update_vsyscall
-static __always_inline void __arch_update_vsyscall(struct vdso_time_data *vdata)
+#ifndef __arch_update_vdso_clock
+static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
{
}
-#endif /* __arch_update_vsyscall */
+#endif /* __arch_update_vdso_clock */
#ifndef __arch_sync_vdso_time_data
static __always_inline void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index d655df2597336f7305bfc74e2a87c651f314267b..df6bada2d58ed9a03e5dd3cb4b218983089a2877 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -118,7 +118,8 @@ void update_vsyscall(struct timekeeper *tk)
if (clock_mode != VDSO_CLOCKMODE_NONE)
update_vdso_time_data(vdata, tk);
- __arch_update_vsyscall(vdata);
+ __arch_update_vdso_clock(&vc[CS_HRES_COARSE]);
+ __arch_update_vdso_clock(&vc[CS_RAW]);
vdso_write_end(vdata);
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 04/14] vdso/helpers: Add helpers for seqlocks of single vdso_clock
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (2 preceding siblings ...)
2025-07-01 8:57 ` [PATCH 03/14] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock() Thomas Weißschuh
@ 2025-07-01 8:57 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 05/14] vdso/gettimeofday: Return bool from clock_getres() helpers Thomas Weißschuh
` (9 subsequent siblings)
13 siblings, 2 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:57 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Auxiliary clocks will have their vDSO data in a dedicated 'struct vdso_clock',
which needs to be synchronized independently.
Add a helper to synchronize a single vDSO clock.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/helpers.h | 40 +++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
index 0a98fed550ba66a84a620fbbd6aee3e3029b4772..a5679f5efdfdcaaf6efd5f4a317d1f132c3dc617 100644
--- a/include/vdso/helpers.h
+++ b/include/vdso/helpers.h
@@ -28,32 +28,46 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
return seq != start;
}
-static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
+static __always_inline void vdso_write_begin_clock(struct vdso_clock *vc, bool last)
{
- struct vdso_clock *vc = vd->clock_data;
-
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
- * updates to vd[x].seq and it is possible that the value seen by the
+ * updates to vc->seq and it is possible that the value seen by the
* reader is inconsistent.
*/
- WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
- smp_wmb();
+ WRITE_ONCE(vc->seq, vc->seq + 1);
+
+ if (last)
+ smp_wmb();
}
-static __always_inline void vdso_write_end(struct vdso_time_data *vd)
+static __always_inline void vdso_write_end_clock(struct vdso_clock *vc, bool first)
{
- struct vdso_clock *vc = vd->clock_data;
+ if (first)
+ smp_wmb();
- smp_wmb();
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
- * updates to vd[x].seq and it is possible that the value seen by the
+ * updates to vc->seq and it is possible that the value seen by the
* reader is inconsistent.
*/
- WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
+ WRITE_ONCE(vc->seq, vc->seq + 1);
+}
+
+static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
+{
+ struct vdso_clock *vc = vd->clock_data;
+
+ vdso_write_begin_clock(&vc[CS_HRES_COARSE], false);
+ vdso_write_begin_clock(&vc[CS_RAW], true);
+}
+
+static __always_inline void vdso_write_end(struct vdso_time_data *vd)
+{
+ struct vdso_clock *vc = vd->clock_data;
+
+ vdso_write_end_clock(&vc[CS_HRES_COARSE], true);
+ vdso_write_end_clock(&vc[CS_RAW], false);
}
#endif /* !__ASSEMBLY__ */
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 05/14] vdso/gettimeofday: Return bool from clock_getres() helpers
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (3 preceding siblings ...)
2025-07-01 8:57 ` [PATCH 04/14] vdso/helpers: Add helpers for seqlocks of single vdso_clock Thomas Weißschuh
@ 2025-07-01 8:57 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
` (8 subsequent siblings)
13 siblings, 2 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:57 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 93ef801a97ef25f66195490d14e41bebcd41982b..9b77f23566f6a35887d4c9aaefc61a971131b499 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -396,8 +396,8 @@ static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time
#ifdef VDSO_HAS_CLOCK_GETRES
static __maybe_unused
-int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
- struct __kernel_timespec *res)
+bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
+ struct __kernel_timespec *res)
{
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
@@ -405,7 +405,7 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
@@ -427,23 +427,25 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
*/
ns = LOW_RES_NSEC;
} else {
- return -1;
+ return false;
}
if (likely(res)) {
res->tv_sec = 0;
res->tv_nsec = ns;
}
- return 0;
+ return true;
}
static __maybe_unused
int __cvdso_clock_getres_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *res)
{
- int ret = __cvdso_clock_getres_common(vd, clock, res);
+ bool ok;
- if (unlikely(ret))
+ ok = __cvdso_clock_getres_common(vd, clock, res);
+
+ if (unlikely(!ok))
return clock_getres_fallback(clock, res);
return 0;
}
@@ -460,18 +462,18 @@ __cvdso_clock_getres_time32_data(const struct vdso_time_data *vd, clockid_t cloc
struct old_timespec32 *res)
{
struct __kernel_timespec ts;
- int ret;
+ bool ok;
- ret = __cvdso_clock_getres_common(vd, clock, &ts);
+ ok = __cvdso_clock_getres_common(vd, clock, &ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_getres32_fallback(clock, res);
if (likely(res)) {
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
}
- return ret;
+ return 0;
}
static __maybe_unused int
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (4 preceding siblings ...)
2025-07-01 8:57 ` [PATCH 05/14] vdso/gettimeofday: Return bool from clock_getres() helpers Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (5 more replies)
2025-07-01 8:58 ` [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid() Thomas Weißschuh
` (7 subsequent siblings)
13 siblings, 6 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 58 +++++++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 28 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 9b77f23566f6a35887d4c9aaefc61a971131b499..c5266532a097c06f33d12e345c695357d75abf42 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -82,8 +82,8 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -103,11 +103,11 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
seq = vdso_read_begin(vc);
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -123,7 +123,7 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#else
static __always_inline
@@ -133,16 +133,16 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
}
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -EINVAL;
+ return false;
}
#endif
static __always_inline
-int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u64 cycles, sec, ns;
@@ -150,7 +150,7 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
/* Allows to compile the high resolution parts out */
if (!__arch_vdso_hres_capable())
- return -1;
+ return false;
do {
/*
@@ -173,11 +173,11 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
smp_rmb();
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -189,13 +189,13 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#ifdef CONFIG_TIME_NS
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -223,20 +223,20 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
*/
ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
ts->tv_nsec = nsec;
- return 0;
+ return true;
}
#else
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -1;
+ return false;
}
#endif
static __always_inline
-int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u32 seq;
@@ -258,10 +258,10 @@ int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_nsec = vdso_ts->nsec;
} while (unlikely(vdso_read_retry(vc, seq)));
- return 0;
+ return true;
}
-static __always_inline int
+static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
@@ -270,7 +270,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
/*
* Convert the clockid to a bitmask and use it to check which
@@ -284,7 +284,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
else
- return -1;
+ return false;
return do_hres(vd, vc, clock, ts);
}
@@ -293,9 +293,11 @@ static __maybe_unused int
__cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
- int ret = __cvdso_clock_gettime_common(vd, clock, ts);
+ bool ok;
- if (unlikely(ret))
+ ok = __cvdso_clock_gettime_common(vd, clock, ts);
+
+ if (unlikely(!ok))
return clock_gettime_fallback(clock, ts);
return 0;
}
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid()
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (5 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (2 more replies)
2025-07-01 8:58 ` [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec() Thomas Weißschuh
` (6 subsequent siblings)
13 siblings, 3 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
With the upcoming addition of auxiliary clocks the clockid validation will
become more complicated. Split it into a dedicated function to keep the
code readable.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c5266532a097c06f33d12e345c695357d75abf42..215151bd5a1320ee6edda8f334d47c739577f696 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -71,6 +71,12 @@ static inline bool vdso_cycles_ok(u64 cycles)
}
#endif
+static __always_inline bool vdso_clockid_valid(clockid_t clock)
+{
+ /* Check for negative values or invalid clocks */
+ return likely((u32) clock < MAX_CLOCKS);
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -268,8 +274,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
/*
@@ -405,8 +410,7 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
u32 msk;
u64 ns;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec()
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (6 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid() Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (2 more replies)
2025-07-01 8:58 ` [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp() Thomas Weißschuh
` (5 subsequent siblings)
13 siblings, 3 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 215151bd5a1320ee6edda8f334d47c739577f696..50611ba28abfcfc7841616e8787101ea1ffcb7d8 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -77,6 +77,16 @@ static __always_inline bool vdso_clockid_valid(clockid_t clock)
return likely((u32) clock < MAX_CLOCKS);
}
+/*
+ * Must not be invoked within the sequence read section as a race inside
+ * that loop could result in __iter_div_u64_rem() being extremely slow.
+ */
+static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64 sec, u64 ns)
+{
+ ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
+ ts->tv_nsec = ns;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -122,12 +132,7 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
sec += offs->sec;
ns += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -188,12 +193,7 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -223,12 +223,8 @@ bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
sec += offs->sec;
nsec += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
- ts->tv_nsec = nsec;
+ vdso_set_timespec(ts, sec, nsec);
+
return true;
}
#else
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp()
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (7 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec() Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (2 more replies)
2025-07-01 8:58 ` [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns() Thomas Weißschuh
` (4 subsequent siblings)
13 siblings, 3 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
lib/vdso/gettimeofday.c | 43 ++++++++++++++++++++++++-------------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 50611ba28abfcfc7841616e8787101ea1ffcb7d8..c383878bb5445a62d8fea6591e8550183852c2e6 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -87,6 +87,26 @@ static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64
ts->tv_nsec = ns;
}
+static __always_inline
+bool vdso_get_timestamp(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ unsigned int clkidx, u64 *sec, u64 *ns)
+{
+ const struct vdso_timestamp *vdso_ts = &vc->basetime[clkidx];
+ u64 cycles;
+
+ if (unlikely(!vdso_clocksource_ok(vc)))
+ return false;
+
+ cycles = __arch_get_hw_counter(vc->clock_mode, vd);
+ if (unlikely(!vdso_cycles_ok(cycles)))
+ return false;
+
+ *ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
+ *sec = vdso_ts->sec;
+
+ return true;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -104,28 +124,20 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
const struct vdso_clock *vc = vd->clock_data;
- const struct vdso_timestamp *vdso_ts;
- u64 cycles, ns;
u32 seq;
s64 sec;
+ u64 ns;
if (clk != CLOCK_MONOTONIC_RAW)
vc = &vc[CS_HRES_COARSE];
else
vc = &vc[CS_RAW];
- vdso_ts = &vc->basetime[clk];
do {
seq = vdso_read_begin(vc);
- if (unlikely(!vdso_clocksource_ok(vc)))
- return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
/* Add the namespace offset */
@@ -155,8 +167,7 @@ static __always_inline
bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
- u64 cycles, sec, ns;
+ u64 sec, ns;
u32 seq;
/* Allows to compile the high resolution parts out */
@@ -183,14 +194,8 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
}
smp_rmb();
- if (unlikely(!vdso_clocksource_ok(vc)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
- return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
vdso_set_timespec(ts, sec, ns);
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns()
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (8 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp() Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (2 more replies)
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
` (3 subsequent siblings)
13 siblings, 3 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Move the constant resolution to a shared header,
so the vDSO can use it and return it without going through a syscall.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/auxclock.h | 13 +++++++++++++
kernel/time/timekeeping.c | 6 ++++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/include/vdso/auxclock.h b/include/vdso/auxclock.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d6e74cbc400e7f5cd7194280759f5e5f3059900
--- /dev/null
+++ b/include/vdso/auxclock.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VDSO_AUXCLOCK_H
+#define _VDSO_AUXCLOCK_H
+
+#include <uapi/linux/time.h>
+#include <uapi/linux/types.h>
+
+static __always_inline u64 aux_clock_resolution_ns(void)
+{
+ return 1;
+}
+
+#endif /* _VDSO_AUXCLOCK_H */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 6a61887eb87e364b3ef170939919a8d4046c0508..6a088378df54d561ecfeafb45a8b54333e11a9a7 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -26,6 +26,8 @@
#include <linux/audit.h>
#include <linux/random.h>
+#include <vdso/auxclock.h>
+
#include "tick-internal.h"
#include "ntp_internal.h"
#include "timekeeping_internal.h"
@@ -2842,8 +2844,8 @@ static int aux_get_res(clockid_t id, struct timespec64 *tp)
if (!clockid_aux_valid(id))
return -ENODEV;
- tp->tv_sec = 0;
- tp->tv_nsec = 1;
+ tp->tv_sec = aux_clock_resolution_ns() / NSEC_PER_SEC;
+ tp->tv_nsec = aux_clock_resolution_ns() % NSEC_PER_SEC;
return 0;
}
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (9 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns() Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-07 6:57 ` Thomas Gleixner
` (3 more replies)
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
` (2 subsequent siblings)
13 siblings, 4 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Expose the auxiliary clock data so it can be read from the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/linux/timekeeper_internal.h | 13 ++++++++++++
include/vdso/datapage.h | 3 +++
kernel/time/namespace.c | 5 +++++
kernel/time/timekeeping.c | 12 +++++++++++
kernel/time/vsyscall.c | 40 +++++++++++++++++++++++++++++++++++++
5 files changed, 73 insertions(+)
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index ca79938b62f396afd503e0cf06bbecf6f95cfce4..5de2e019399c72246f7d7dfad561c8b3d479dbd1 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -190,4 +190,17 @@ static inline void update_vsyscall_tz(void)
}
#endif
+#if defined(CONFIG_GENERIC_TIME_VSYSCALL) && defined(CONFIG_GENERIC_GETTIMEOFDAY) && \
+ defined(CONFIG_POSIX_AUX_CLOCKS)
+
+extern void vdso_time_update_aux(struct timekeeper *tk);
+
+#else
+
+static inline void vdso_time_update_aux(struct timekeeper *tk)
+{
+}
+
+#endif /* CONFIG_GENERIC_TIME_VSYSCALL && CONFIG_POSIX_AUX_CLOCKS */
+
#endif /* _LINUX_TIMEKEEPER_INTERNAL_H */
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 1864e76e8f691bab10813543880f71bc59afa9c0..f4c96d9ce674abb07ccd8703f1a04da7631c1677 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -38,6 +38,7 @@ struct vdso_arch_data {
#endif
#define VDSO_BASES (CLOCK_TAI + 1)
+#define VDSO_BASE_AUX 0
#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
BIT(CLOCK_MONOTONIC) | \
BIT(CLOCK_BOOTTIME) | \
@@ -117,6 +118,7 @@ struct vdso_clock {
* @arch_data: architecture specific data (optional, defaults
* to an empty struct)
* @clock_data: clocksource related data (array)
+ * @aux_clock_data: auxiliary clocksource related data (array)
* @tz_minuteswest: minutes west of Greenwich
* @tz_dsttime: type of DST correction
* @hrtimer_res: hrtimer resolution
@@ -133,6 +135,7 @@ struct vdso_time_data {
struct arch_vdso_time_data arch_data;
struct vdso_clock clock_data[CS_BASES];
+ struct vdso_clock aux_clock_data[MAX_AUX_CLOCKS];
s32 tz_minuteswest;
s32 tz_dsttime;
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index e3642278df433c41654ffb6a8043c3fcecc2994a..667452768ed3b50e48e3cfb70f8ef68e4bed9e0b 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -242,6 +242,11 @@ static void timens_set_vvar_page(struct task_struct *task,
for (i = 0; i < CS_BASES; i++)
timens_setup_vdso_clock_data(&vc[i], ns);
+ if (IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS)) {
+ for (i = 0; i < ARRAY_SIZE(vdata->aux_clock_data); i++)
+ timens_setup_vdso_clock_data(&vdata->aux_clock_data[i], ns);
+ }
+
out:
mutex_unlock(&offset_lock);
}
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 6a088378df54d561ecfeafb45a8b54333e11a9a7..928b8e0773f9e1b8fd700f130a700c5908fe6c27 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -66,11 +66,21 @@ static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return ktime_get_aux_ts64(CLOCK_AUX + tkid - TIMEKEEPER_AUX_FIRST, ts);
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return tk->id >= TIMEKEEPER_AUX_FIRST && tk->id <= TIMEKEEPER_AUX_LAST;
+}
#else
static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return false;
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return false;
+}
#endif
/* flag for if timekeeping is suspended */
@@ -719,6 +729,8 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono);
update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw);
+ } else if (tk_is_aux(tk)) {
+ vdso_time_update_aux(tk);
}
if (action & TK_CLOCK_WAS_SET)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index df6bada2d58ed9a03e5dd3cb4b218983089a2877..62d9701db9135ba4ef377f3f534a9279d7922d2d 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -136,6 +136,46 @@ void update_vsyscall_tz(void)
__arch_sync_vdso_time_data(vdata);
}
+#ifdef CONFIG_POSIX_AUX_CLOCKS
+void vdso_time_update_aux(struct timekeeper *tk)
+{
+ struct vdso_time_data *vdata = vdso_k_time_data;
+ struct vdso_timestamp *vdso_ts;
+ struct vdso_clock *vc;
+ s32 clock_mode;
+ u64 nsec;
+
+ vc = &vdata->aux_clock_data[tk->id - TIMEKEEPER_AUX_FIRST];
+ vdso_ts = &vc->basetime[VDSO_BASE_AUX];
+ clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
+ if (!tk->clock_valid)
+ clock_mode = VDSO_CLOCKMODE_NONE;
+
+ /* copy vsyscall data */
+ vdso_write_begin_clock(vc, true);
+
+ vc->clock_mode = clock_mode;
+
+ if (clock_mode != VDSO_CLOCKMODE_NONE) {
+ fill_clock_configuration(vc, &tk->tkr_mono);
+
+ vdso_ts->sec = tk->xtime_sec;
+
+ nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
+ nsec += tk->offs_aux;
+ vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
+ nsec = nsec << tk->tkr_mono.shift;
+ vdso_ts->nsec = nsec;
+ }
+
+ __arch_update_vdso_clock(vc);
+
+ vdso_write_end_clock(vc, true);
+
+ __arch_sync_vdso_time_data(vdata);
+}
+#endif
+
/**
* vdso_update_begin - Start of a VDSO update section
*
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (10 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-06 19:31 ` Thomas Gleixner
` (5 more replies)
2025-07-01 8:58 ` [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers" Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality Thomas Weißschuh
13 siblings, 6 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Expose the auxiliary clocks through the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
include/vdso/datapage.h | 2 ++
lib/vdso/gettimeofday.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index f4c96d9ce674abb07ccd8703f1a04da7631c1677..02533038640e53c40291c7e09139e0f9b32f502a 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
+#include <uapi/linux/bits.h>
#include <uapi/linux/time.h>
#include <uapi/linux/types.h>
#include <uapi/asm-generic/errno-base.h>
@@ -46,6 +47,7 @@ struct vdso_arch_data {
#define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
BIT(CLOCK_MONOTONIC_COARSE))
#define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
+#define VDSO_AUX __GENMASK(CLOCK_AUX_LAST, CLOCK_AUX)
#define CS_HRES_COARSE 0
#define CS_RAW 1
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c383878bb5445a62d8fea6591e8550183852c2e6..3a54dbb8fe32849cd749e71ec2a8be44baf42816 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -2,6 +2,7 @@
/*
* Generic userspace implementations of gettimeofday() and similar.
*/
+#include <vdso/auxclock.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles)
static __always_inline bool vdso_clockid_valid(clockid_t clock)
{
/* Check for negative values or invalid clocks */
- return likely((u32) clock < MAX_CLOCKS);
+ return likely((u32) clock < CLOCK_AUX_LAST);
}
/*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
return true;
}
+static __always_inline
+bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_clock *vc;
+ u64 sec, ns;
+ u32 seq;
+ u8 idx;
+
+ if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
+ return false;
+
+ idx = clock - CLOCK_AUX;
+ vc = &vd->aux_clock_data[idx];
+
+ do {
+ /*
+ * Open coded function vdso_read_begin() to handle
+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
+ */
+ while ((seq = READ_ONCE(vc->seq)) & 1) {
+ if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
+ vd = __arch_get_vdso_u_timens_data(vd);
+ vc = &vd->aux_clock_data[idx];
+ break;
+ }
+ cpu_relax();
+ }
+ smp_rmb();
+
+ /* Auxclock disabled? */
+ if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
+ return false;
+
+ if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
+ return false;
+ } while (unlikely(vdso_read_retry(vc, seq)));
+
+ vdso_set_timespec(ts, sec, ns);
+
+ return true;
+}
+
static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
+ else if (msk & VDSO_AUX)
+ return do_aux(vd, clock, ts);
else
return false;
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
* Preserves the behaviour of posix_get_coarse_res().
*/
ns = LOW_RES_NSEC;
+ } else if (msk & VDSO_AUX) {
+ ns = aux_clock_resolution_ns();
} else {
return false;
}
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers"
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (11 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-06 20:43 ` Thomas Gleixner
2025-07-01 8:58 ` [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality Thomas Weißschuh
13 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
This reverts commit c9fbaa879508 ("selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers")
The kernel headers were used to make parse_vdso.c compatible with nolibc.
Unfortunately linux/elf.h is incompatible with glibc's sys/auxv.h.
When using glibc it is therefore not possible build parse_vdso.c as part of the
same compilation unit as its caller as sys/auxv.h is needed for getauxval().
In the meantime nolibc gained its own elf.h, providing compatibility with the
documented libc interfaces.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
tools/testing/selftests/vDSO/Makefile | 2 --
tools/testing/selftests/vDSO/parse_vdso.c | 3 +--
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile
index 12a0614b9fd4983deffe5d6a7cfa06ba8d92a516..67ead1ba6cb9c6d6088680a9c4d24a9d19f7231f 100644
--- a/tools/testing/selftests/vDSO/Makefile
+++ b/tools/testing/selftests/vDSO/Makefile
@@ -20,8 +20,6 @@ endif
include ../lib.mk
-CFLAGS += $(TOOLS_INCLUDES)
-
CFLAGS_NOLIBC := -nostdlib -nostdinc -ffreestanding -fno-asynchronous-unwind-tables \
-fno-stack-protector -include $(top_srcdir)/tools/include/nolibc/nolibc.h \
-I$(top_srcdir)/tools/include/nolibc/ $(KHDR_INCLUDES)
diff --git a/tools/testing/selftests/vDSO/parse_vdso.c b/tools/testing/selftests/vDSO/parse_vdso.c
index 3ff00fb624a44b964cc54954f1f088cabe11a901..c6ff4413ea367ae57bc6a60073314b29f938c99d 100644
--- a/tools/testing/selftests/vDSO/parse_vdso.c
+++ b/tools/testing/selftests/vDSO/parse_vdso.c
@@ -19,8 +19,7 @@
#include <stdint.h>
#include <string.h>
#include <limits.h>
-#include <linux/auxvec.h>
-#include <linux/elf.h>
+#include <elf.h>
#include "parse_vdso.h"
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
` (12 preceding siblings ...)
2025-07-01 8:58 ` [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers" Thomas Weißschuh
@ 2025-07-01 8:58 ` Thomas Weißschuh
2025-07-06 20:26 ` Thomas Gleixner
13 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-01 8:58 UTC (permalink / raw)
To: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
Extend the auxclock test to also cover the vDSO.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
tools/testing/selftests/timers/auxclock.c | 95 +++++++++++++++++++++++++++++--
1 file changed, 91 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/timers/auxclock.c b/tools/testing/selftests/timers/auxclock.c
index 0ba2f9996114ade3147f0f3aec49904556a23cd4..314037839c1c7dd32ca32722231c67bc408a2ea3 100644
--- a/tools/testing/selftests/timers/auxclock.c
+++ b/tools/testing/selftests/timers/auxclock.c
@@ -10,11 +10,16 @@
#include <linux/timex.h>
#include <sched.h>
#include <stdio.h>
+#include <sys/auxv.h>
#include <sys/syscall.h>
#include <unistd.h>
#include "../kselftest_harness.h"
+#include "../vDSO/parse_vdso.c"
+#include "../vDSO/vdso_config.h"
+#include "../vDSO/vdso_call.h"
+
#ifndef CLOCK_AUX
#define CLOCK_AUX 16
#endif
@@ -133,7 +138,45 @@ static int sys_clock_adjtime64(__kernel_clockid_t clockid, struct __kernel_timex
#endif
}
-FIXTURE(auxclock) {};
+FIXTURE(auxclock) {
+ int (*vdso_clock_gettime)(__kernel_clockid_t clockid, struct timespec *ts);
+ int (*vdso_clock_gettime64)(__kernel_clockid_t clockid, struct __kernel_timespec *ts);
+ int (*vdso_clock_getres)(__kernel_clockid_t clockid, struct timespec *ts);
+};
+
+static int vdso_clock_gettime64(FIXTURE_DATA(auxclock) *self, __kernel_clockid_t clockid,
+ struct __kernel_timespec *ts)
+{
+ struct timespec _ts;
+ int ret;
+
+ if (self->vdso_clock_gettime64) {
+ return VDSO_CALL(self->vdso_clock_gettime64, 2, clockid, ts);
+ } else if (self->vdso_clock_gettime) {
+ ret = VDSO_CALL(self->vdso_clock_gettime, 2, clockid, &_ts);
+ if (!ret)
+ timespec_to_kernel_timespec(&_ts, ts);
+ return ret;
+ } else {
+ return -ENOSYS;
+ }
+}
+
+static int vdso_clock_getres_time64(FIXTURE_DATA(auxclock) *self, __kernel_clockid_t clockid,
+ struct __kernel_timespec *ts)
+{
+ struct timespec _ts;
+ int ret;
+
+ if (self->vdso_clock_getres) {
+ ret = VDSO_CALL(self->vdso_clock_getres, 2, clockid, &_ts);
+ if (!ret)
+ timespec_to_kernel_timespec(&_ts, ts);
+ return ret;
+ } else {
+ return -ENOSYS;
+ }
+}
FIXTURE_VARIANT(auxclock) {
__kernel_clockid_t clock;
@@ -193,6 +236,18 @@ static void enter_timens(struct __test_metadata *_metadata)
FIXTURE_SETUP(auxclock) {
int ret;
+#ifdef AT_SYSINFO_EHDR
+ unsigned long sysinfo_ehdr;
+
+ sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
+ if (sysinfo_ehdr)
+ vdso_init_from_sysinfo_ehdr(sysinfo_ehdr);
+
+ self->vdso_clock_gettime = vdso_sym(versions[VDSO_VERSION], names[VDSO_NAMES][1]);
+ self->vdso_clock_gettime64 = vdso_sym(versions[VDSO_VERSION], names[VDSO_NAMES][5]);
+ self->vdso_clock_getres = vdso_sym(versions[VDSO_VERSION], names[VDSO_NAMES][3]);
+#endif /* !AT_SYSINFO_EHDR */
+
ret = configure_auxclock(variant->clock, variant->clock_enabled);
if (ret == -ENOENT)
SKIP(return, "auxclocks not enabled");
@@ -220,6 +275,20 @@ TEST_F(auxclock, sys_clock_getres) {
ASSERT_EQ(1, ts.tv_nsec);
}
+TEST_F(auxclock, vdso_clock_getres) {
+ struct __kernel_timespec ts;
+ int ret;
+
+ ret = vdso_clock_getres_time64(self, variant->clock, &ts);
+ if (ret == -ENOSYS) {
+ SKIP(return, "no clock_getres() in vDSO");
+ } else {
+ ASSERT_EQ(0, ret);
+ ASSERT_EQ(0, ts.tv_sec);
+ ASSERT_EQ(1, ts.tv_nsec);
+ }
+}
+
TEST_F(auxclock, sys_clock_gettime) {
struct __kernel_timespec ts;
int ret;
@@ -233,6 +302,20 @@ TEST_F(auxclock, sys_clock_gettime) {
}
}
+TEST_F(auxclock, vdso_clock_gettime) {
+ struct __kernel_timespec ts;
+ int ret;
+
+ ret = vdso_clock_gettime64(self, variant->clock, &ts);
+ if (ret == -ENOSYS) {
+ SKIP(return, "no clock_gettime() in vDSO");
+ } else if (variant->clock_enabled) {
+ ASSERT_EQ(0, ret);
+ } else {
+ ASSERT_EQ(-ENODEV, ret);
+ }
+}
+
static void auxclock_validate_progression(struct __test_metadata *_metadata,
const struct __kernel_timespec *a,
const struct __kernel_timespec *b)
@@ -310,9 +393,13 @@ TEST_F(auxclock, progression) {
auxclock_validate_progression(_metadata, &a, &b);
memset(&a, 0, sizeof(a));
- ret = sys_clock_gettime64(variant->clock, &a);
- ASSERT_EQ(0, ret);
- auxclock_validate_progression(_metadata, &b, &a);
+ ret = vdso_clock_gettime64(self, variant->clock, &a);
+ if (ret == -ENOSYS) {
+ a = b;
+ } else {
+ ASSERT_EQ(0, ret);
+ auxclock_validate_progression(_metadata, &b, &a);
+ }
}
}
--
2.50.0
^ permalink raw reply related [flat|nested] 72+ messages in thread
* Re: [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
@ 2025-07-06 19:31 ` Thomas Gleixner
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (4 subsequent siblings)
5 siblings, 0 replies; 72+ messages in thread
From: Thomas Gleixner @ 2025-07-06 19:31 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Vincenzo Frascino,
Shuah Khan, Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
> +static __always_inline
> +bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
> +{
> + const struct vdso_clock *vc;
> + u64 sec, ns;
> + u32 seq;
> + u8 idx;
> +
> + if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
> + return false;
> +
> + idx = clock - CLOCK_AUX;
> + vc = &vd->aux_clock_data[idx];
> +
> + do {
> + /*
> + * Open coded function vdso_read_begin() to handle
> + * VDSO_CLOCK_TIMENS. See comment in do_hres().
> + */
> + while ((seq = READ_ONCE(vc->seq)) & 1) {
> + if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
> + vd = __arch_get_vdso_u_timens_data(vd);
> + vc = &vd->aux_clock_data[idx];
> + break;
This actually wants to be a continue because otherwise @seq contains the
stale value from the initial read of the TIMENS page, which is
0x1. That's a pointless extra round through the below.
With continue it re-reads, but this time the actual value from the time
data page and also takes an eventual odd value into account properly.
I fixed it up locally already.
Thanks,
tglx
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality
2025-07-01 8:58 ` [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality Thomas Weißschuh
@ 2025-07-06 20:26 ` Thomas Gleixner
2025-07-07 7:17 ` Thomas Weißschuh
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Gleixner @ 2025-07-06 20:26 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Vincenzo Frascino,
Shuah Khan, Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
> Extend the auxclock test to also cover the vDSO.
I'm not really convinved, that this is the right thing to do. Why can't
this just extend selftests/vDSO instead of creating these
> +#include "../vDSO/parse_vdso.c"
> +#include "../vDSO/vdso_config.h"
> +#include "../vDSO/vdso_call.h"
cross directory oddities? Confused.
Thanks,
tglx
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers"
2025-07-01 8:58 ` [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers" Thomas Weißschuh
@ 2025-07-06 20:43 ` Thomas Gleixner
2025-07-07 6:21 ` Thomas Weißschuh
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Gleixner @ 2025-07-06 20:43 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Vincenzo Frascino,
Shuah Khan, Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
> This reverts commit c9fbaa879508 ("selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers")
>
> The kernel headers were used to make parse_vdso.c compatible with nolibc.
> Unfortunately linux/elf.h is incompatible with glibc's sys/auxv.h.
> When using glibc it is therefore not possible build parse_vdso.c as part of the
> same compilation unit as its caller as sys/auxv.h is needed for getauxval().
>
> In the meantime nolibc gained its own elf.h, providing compatibility with the
> documented libc interfaces.
I'm kinda surprised to find this here in this series. Isn't that commit
c9fbaa879508 obsolete since nolibc got it's own elf.h?
So this should just go straight to Linus, no?
Thanks,
tglx
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers"
2025-07-06 20:43 ` Thomas Gleixner
@ 2025-07-07 6:21 ` Thomas Weißschuh
0 siblings, 0 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-07 6:21 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Andy Lutomirski, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Sun, Jul 06, 2025 at 10:43:47PM +0200, Thomas Gleixner wrote:
> On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
> > This reverts commit c9fbaa879508 ("selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers")
> >
> > The kernel headers were used to make parse_vdso.c compatible with nolibc.
> > Unfortunately linux/elf.h is incompatible with glibc's sys/auxv.h.
> > When using glibc it is therefore not possible build parse_vdso.c as part of the
> > same compilation unit as its caller as sys/auxv.h is needed for getauxval().
> >
> > In the meantime nolibc gained its own elf.h, providing compatibility with the
> > documented libc interfaces.
>
> I'm kinda surprised to find this here in this series. Isn't that commit
> c9fbaa879508 obsolete since nolibc got it's own elf.h?
Correct.
> So this should just go straight to Linus, no?
It could. But the next patch of this series depends on it for now.
So to avoid ordering issues I kept both patches together.
Thomas
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
@ 2025-07-07 6:57 ` Thomas Gleixner
2025-07-07 11:34 ` Arnd Bergmann
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (2 subsequent siblings)
3 siblings, 1 reply; 72+ messages in thread
From: Thomas Gleixner @ 2025-07-07 6:57 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Vincenzo Frascino,
Shuah Khan, Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Frederic Weisbecker,
Anna-Maria Behnsen, Miroslav Lichvar, Werner Abt, David Woodhouse,
Stephen Boyd, Kurt Kanzenbach, Nam Cao, Antoine Tenart,
Thomas Weißschuh
On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
>
> +#if defined(CONFIG_GENERIC_TIME_VSYSCALL) && defined(CONFIG_GENERIC_GETTIMEOFDAY) && \
> + defined(CONFIG_POSIX_AUX_CLOCKS)
CONFIG_GENERIC_GETTIMEOFDAY requires CONFIG_GENERIC_TIME_VSYSCALL, but
that's not expressed anywhere. This stuff has grown too many config
options over time:
GENERIC_TIME_VSYSCALL, HAVE_GENERIC_VDSO, GENERIC_VDSO_DATA_STORE
All architectures except SPARC64 use the generic code and the generic
VDSO data store implementation. That config maze wants to be
consolidated.
^ permalink raw reply [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
2025-07-06 19:31 ` Thomas Gleixner
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
` (3 subsequent siblings)
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 7893ea1006fcbb876ddf53ad4ebba4a054add4b2
Gitweb: https://git.kernel.org/tip/7893ea1006fcbb876ddf53ad4ebba4a054add4b2
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:06 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:54 +02:00
vdso/gettimeofday: Add support for auxiliary clocks
Expose the auxiliary clocks through the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-12-df7d9f87b9b8@linutronix.de
---
include/vdso/datapage.h | 2 ++-
lib/vdso/gettimeofday.c | 49 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index f4c96d9..0253303 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
+#include <uapi/linux/bits.h>
#include <uapi/linux/time.h>
#include <uapi/linux/types.h>
#include <uapi/asm-generic/errno-base.h>
@@ -46,6 +47,7 @@ struct vdso_arch_data {
#define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
BIT(CLOCK_MONOTONIC_COARSE))
#define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
+#define VDSO_AUX __GENMASK(CLOCK_AUX_LAST, CLOCK_AUX)
#define CS_HRES_COARSE 0
#define CS_RAW 1
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c383878..d6743ed 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -2,6 +2,7 @@
/*
* Generic userspace implementations of gettimeofday() and similar.
*/
+#include <vdso/auxclock.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles)
static __always_inline bool vdso_clockid_valid(clockid_t clock)
{
/* Check for negative values or invalid clocks */
- return likely((u32) clock < MAX_CLOCKS);
+ return likely((u32) clock < CLOCK_AUX_LAST);
}
/*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
return true;
}
+static __always_inline
+bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_clock *vc;
+ u32 seq, idx;
+ u64 sec, ns;
+
+ if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
+ return false;
+
+ idx = clock - CLOCK_AUX;
+ vc = &vd->aux_clock_data[idx];
+
+ do {
+ /*
+ * Open coded function vdso_read_begin() to handle
+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
+ */
+ while ((seq = READ_ONCE(vc->seq)) & 1) {
+ if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
+ vd = __arch_get_vdso_u_timens_data(vd);
+ vc = &vd->aux_clock_data[idx];
+ /* Re-read from the real time data page */
+ continue;
+ }
+ cpu_relax();
+ }
+ smp_rmb();
+
+ /* Auxclock disabled? */
+ if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
+ return false;
+
+ if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
+ return false;
+ } while (unlikely(vdso_read_retry(vc, seq)));
+
+ vdso_set_timespec(ts, sec, ns);
+
+ return true;
+}
+
static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
+ else if (msk & VDSO_AUX)
+ return do_aux(vd, clock, ts);
else
return false;
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
* Preserves the behaviour of posix_get_coarse_res().
*/
ns = LOW_RES_NSEC;
+ } else if (msk & VDSO_AUX) {
+ ns = aux_clock_resolution_ns();
} else {
return false;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
2025-07-07 6:57 ` Thomas Gleixner
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
3 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 8764009ff21cc773c0c44ecdc987ced5ca853d90
Gitweb: https://git.kernel.org/tip/8764009ff21cc773c0c44ecdc987ced5ca853d90
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:05 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:54 +02:00
vdso/vsyscall: Update auxiliary clock data in the datapage
Expose the auxiliary clock data so it can be read from the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-11-df7d9f87b9b8@linutronix.de
---
include/linux/timekeeper_internal.h | 6 ++++-
include/vdso/datapage.h | 3 ++-
kernel/time/namespace.c | 5 ++++-
kernel/time/timekeeping.c | 12 ++++++++-
kernel/time/vsyscall.c | 40 ++++++++++++++++++++++++++++-
5 files changed, 66 insertions(+)
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index ca79938..c27aac6 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -190,4 +190,10 @@ static inline void update_vsyscall_tz(void)
}
#endif
+#if defined(CONFIG_GENERIC_GETTIMEOFDAY) && defined(CONFIG_POSIX_AUX_CLOCKS)
+extern void vdso_time_update_aux(struct timekeeper *tk);
+#else
+static inline void vdso_time_update_aux(struct timekeeper *tk) { }
+#endif
+
#endif /* _LINUX_TIMEKEEPER_INTERNAL_H */
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 1864e76..f4c96d9 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -38,6 +38,7 @@ struct vdso_arch_data {
#endif
#define VDSO_BASES (CLOCK_TAI + 1)
+#define VDSO_BASE_AUX 0
#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
BIT(CLOCK_MONOTONIC) | \
BIT(CLOCK_BOOTTIME) | \
@@ -117,6 +118,7 @@ struct vdso_clock {
* @arch_data: architecture specific data (optional, defaults
* to an empty struct)
* @clock_data: clocksource related data (array)
+ * @aux_clock_data: auxiliary clocksource related data (array)
* @tz_minuteswest: minutes west of Greenwich
* @tz_dsttime: type of DST correction
* @hrtimer_res: hrtimer resolution
@@ -133,6 +135,7 @@ struct vdso_time_data {
struct arch_vdso_time_data arch_data;
struct vdso_clock clock_data[CS_BASES];
+ struct vdso_clock aux_clock_data[MAX_AUX_CLOCKS];
s32 tz_minuteswest;
s32 tz_dsttime;
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index e364227..6674527 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -242,6 +242,11 @@ static void timens_set_vvar_page(struct task_struct *task,
for (i = 0; i < CS_BASES; i++)
timens_setup_vdso_clock_data(&vc[i], ns);
+ if (IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS)) {
+ for (i = 0; i < ARRAY_SIZE(vdata->aux_clock_data); i++)
+ timens_setup_vdso_clock_data(&vdata->aux_clock_data[i], ns);
+ }
+
out:
mutex_unlock(&offset_lock);
}
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cbcf090..243fe25 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -66,11 +66,21 @@ static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return ktime_get_aux_ts64(CLOCK_AUX + tkid - TIMEKEEPER_AUX_FIRST, ts);
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return tk->id >= TIMEKEEPER_AUX_FIRST && tk->id <= TIMEKEEPER_AUX_LAST;
+}
#else
static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return false;
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return false;
+}
#endif
/* flag for if timekeeping is suspended */
@@ -719,6 +729,8 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono);
update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw);
+ } else if (tk_is_aux(tk)) {
+ vdso_time_update_aux(tk);
}
if (action & TK_CLOCK_WAS_SET)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index df6bada..8ba8b0d 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -136,6 +136,46 @@ void update_vsyscall_tz(void)
__arch_sync_vdso_time_data(vdata);
}
+#ifdef CONFIG_POSIX_AUX_CLOCKS
+void vdso_time_update_aux(struct timekeeper *tk)
+{
+ struct vdso_time_data *vdata = vdso_k_time_data;
+ struct vdso_timestamp *vdso_ts;
+ struct vdso_clock *vc;
+ s32 clock_mode;
+ u64 nsec;
+
+ vc = &vdata->aux_clock_data[tk->id - TIMEKEEPER_AUX_FIRST];
+ vdso_ts = &vc->basetime[VDSO_BASE_AUX];
+ clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
+ if (!tk->clock_valid)
+ clock_mode = VDSO_CLOCKMODE_NONE;
+
+ /* copy vsyscall data */
+ vdso_write_begin_clock(vc);
+
+ vc->clock_mode = clock_mode;
+
+ if (clock_mode != VDSO_CLOCKMODE_NONE) {
+ fill_clock_configuration(vc, &tk->tkr_mono);
+
+ vdso_ts->sec = tk->xtime_sec;
+
+ nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
+ nsec += tk->offs_aux;
+ vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
+ nsec = nsec << tk->tkr_mono.shift;
+ vdso_ts->nsec = nsec;
+ }
+
+ __arch_update_vdso_clock(vc);
+
+ vdso_write_end_clock(vc);
+
+ __arch_sync_vdso_time_data(vdata);
+}
+#endif
+
/**
* vdso_update_begin - Start of a VDSO update section
*
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso: Introduce aux_clock_resolution_ns()
2025-07-01 8:58 ` [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns() Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 8361c5bf4965e5d091e0413c4aeeb2f9dad4278f
Gitweb: https://git.kernel.org/tip/8361c5bf4965e5d091e0413c4aeeb2f9dad4278f
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:04 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:53 +02:00
vdso: Introduce aux_clock_resolution_ns()
Move the constant resolution to a shared header,
so the vDSO can use it and return it without going through a syscall.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-10-df7d9f87b9b8@linutronix.de
---
include/vdso/auxclock.h | 13 +++++++++++++
kernel/time/timekeeping.c | 6 ++++--
2 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 include/vdso/auxclock.h
diff --git a/include/vdso/auxclock.h b/include/vdso/auxclock.h
new file mode 100644
index 0000000..6d6e74c
--- /dev/null
+++ b/include/vdso/auxclock.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VDSO_AUXCLOCK_H
+#define _VDSO_AUXCLOCK_H
+
+#include <uapi/linux/time.h>
+#include <uapi/linux/types.h>
+
+static __always_inline u64 aux_clock_resolution_ns(void)
+{
+ return 1;
+}
+
+#endif /* _VDSO_AUXCLOCK_H */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c6fe89b..cbcf090 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -26,6 +26,8 @@
#include <linux/audit.h>
#include <linux/random.h>
+#include <vdso/auxclock.h>
+
#include "tick-internal.h"
#include "ntp_internal.h"
#include "timekeeping_internal.h"
@@ -2876,8 +2878,8 @@ static int aux_get_res(clockid_t id, struct timespec64 *tp)
if (!clockid_aux_valid(id))
return -ENODEV;
- tp->tv_sec = 0;
- tp->tv_nsec = 1;
+ tp->tv_sec = aux_clock_resolution_ns() / NSEC_PER_SEC;
+ tp->tv_nsec = aux_clock_resolution_ns() % NSEC_PER_SEC;
return 0;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_get_timestamp()
2025-07-01 8:58 ` [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp() Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 6e14fcf095e99d1ed882e8ecfb668dc6d7f5e720
Gitweb: https://git.kernel.org/tip/6e14fcf095e99d1ed882e8ecfb668dc6d7f5e720
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:03 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:53 +02:00
vdso/gettimeofday: Introduce vdso_get_timestamp()
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-9-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 43 ++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 50611ba..c383878 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -87,6 +87,26 @@ static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64
ts->tv_nsec = ns;
}
+static __always_inline
+bool vdso_get_timestamp(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ unsigned int clkidx, u64 *sec, u64 *ns)
+{
+ const struct vdso_timestamp *vdso_ts = &vc->basetime[clkidx];
+ u64 cycles;
+
+ if (unlikely(!vdso_clocksource_ok(vc)))
+ return false;
+
+ cycles = __arch_get_hw_counter(vc->clock_mode, vd);
+ if (unlikely(!vdso_cycles_ok(cycles)))
+ return false;
+
+ *ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
+ *sec = vdso_ts->sec;
+
+ return true;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -104,28 +124,20 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
const struct vdso_clock *vc = vd->clock_data;
- const struct vdso_timestamp *vdso_ts;
- u64 cycles, ns;
u32 seq;
s64 sec;
+ u64 ns;
if (clk != CLOCK_MONOTONIC_RAW)
vc = &vc[CS_HRES_COARSE];
else
vc = &vc[CS_RAW];
- vdso_ts = &vc->basetime[clk];
do {
seq = vdso_read_begin(vc);
- if (unlikely(!vdso_clocksource_ok(vc)))
- return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
/* Add the namespace offset */
@@ -155,8 +167,7 @@ static __always_inline
bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
- u64 cycles, sec, ns;
+ u64 sec, ns;
u32 seq;
/* Allows to compile the high resolution parts out */
@@ -183,14 +194,8 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
}
smp_rmb();
- if (unlikely(!vdso_clocksource_ok(vc)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
- return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
vdso_set_timespec(ts, sec, ns);
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_set_timespec()
2025-07-01 8:58 ` [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec() Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 3313cfe7e3d0f9ac0782f566db52a084cba45894
Gitweb: https://git.kernel.org/tip/3313cfe7e3d0f9ac0782f566db52a084cba45894
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:02 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:52 +02:00
vdso/gettimeofday: Introduce vdso_set_timespec()
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-8-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 215151b..50611ba 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -77,6 +77,16 @@ static __always_inline bool vdso_clockid_valid(clockid_t clock)
return likely((u32) clock < MAX_CLOCKS);
}
+/*
+ * Must not be invoked within the sequence read section as a race inside
+ * that loop could result in __iter_div_u64_rem() being extremely slow.
+ */
+static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64 sec, u64 ns)
+{
+ ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
+ ts->tv_nsec = ns;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -122,12 +132,7 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
sec += offs->sec;
ns += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -188,12 +193,7 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -223,12 +223,8 @@ bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
sec += offs->sec;
nsec += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
- ts->tv_nsec = nsec;
+ vdso_set_timespec(ts, sec, nsec);
+
return true;
}
#else
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_clockid_valid()
2025-07-01 8:58 ` [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid() Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: b5df72706b044b30b17f5d623fe040b83e98be36
Gitweb: https://git.kernel.org/tip/b5df72706b044b30b17f5d623fe040b83e98be36
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:01 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:52 +02:00
vdso/gettimeofday: Introduce vdso_clockid_valid()
Move the clock ID validation check into a common helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-7-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c526653..215151b 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -71,6 +71,12 @@ static inline bool vdso_cycles_ok(u64 cycles)
}
#endif
+static __always_inline bool vdso_clockid_valid(clockid_t clock)
+{
+ /* Check for negative values or invalid clocks */
+ return likely((u32) clock < MAX_CLOCKS);
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -268,8 +274,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
/*
@@ -405,8 +410,7 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
u32 msk;
u64 ns;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
[not found] ` <CGME20250708151720eucas1p260f984fd95d3460d3e9f6c9b48e0e25c@eucas1p2.samsung.com>
` (4 subsequent siblings)
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: fcc8e46f768ff508dab0e3cfc2001e96dcb388e2
Gitweb: https://git.kernel.org/tip/fcc8e46f768ff508dab0e3cfc2001e96dcb388e2
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:00 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:51 +02:00
vdso/gettimeofday: Return bool from clock_gettime() helpers
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-6-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 58 ++++++++++++++++++++--------------------
1 file changed, 30 insertions(+), 28 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 9b77f23..c526653 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -82,8 +82,8 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -103,11 +103,11 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
seq = vdso_read_begin(vc);
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -123,7 +123,7 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#else
static __always_inline
@@ -133,16 +133,16 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
}
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -EINVAL;
+ return false;
}
#endif
static __always_inline
-int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u64 cycles, sec, ns;
@@ -150,7 +150,7 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
/* Allows to compile the high resolution parts out */
if (!__arch_vdso_hres_capable())
- return -1;
+ return false;
do {
/*
@@ -173,11 +173,11 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
smp_rmb();
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -189,13 +189,13 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#ifdef CONFIG_TIME_NS
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -223,20 +223,20 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
*/
ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
ts->tv_nsec = nsec;
- return 0;
+ return true;
}
#else
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -1;
+ return false;
}
#endif
static __always_inline
-int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u32 seq;
@@ -258,10 +258,10 @@ int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_nsec = vdso_ts->nsec;
} while (unlikely(vdso_read_retry(vc, seq)));
- return 0;
+ return true;
}
-static __always_inline int
+static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
@@ -270,7 +270,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
/*
* Convert the clockid to a bitmask and use it to check which
@@ -284,7 +284,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
else
- return -1;
+ return false;
return do_hres(vd, vc, clock, ts);
}
@@ -293,9 +293,11 @@ static __maybe_unused int
__cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
- int ret = __cvdso_clock_gettime_common(vd, clock, ts);
+ bool ok;
- if (unlikely(ret))
+ ok = __cvdso_clock_gettime_common(vd, clock, ts);
+
+ if (unlikely(!ok))
return clock_gettime_fallback(clock, ts);
return 0;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_getres() helpers
2025-07-01 8:57 ` [PATCH 05/14] vdso/gettimeofday: Return bool from clock_getres() helpers Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 7413d7c640aa1d9620aa467922cfe3b8df51272e
Gitweb: https://git.kernel.org/tip/7413d7c640aa1d9620aa467922cfe3b8df51272e
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:59 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:51 +02:00
vdso/gettimeofday: Return bool from clock_getres() helpers
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-5-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 93ef801..9b77f23 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -396,8 +396,8 @@ static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time
#ifdef VDSO_HAS_CLOCK_GETRES
static __maybe_unused
-int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
- struct __kernel_timespec *res)
+bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
+ struct __kernel_timespec *res)
{
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
@@ -405,7 +405,7 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
@@ -427,23 +427,25 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
*/
ns = LOW_RES_NSEC;
} else {
- return -1;
+ return false;
}
if (likely(res)) {
res->tv_sec = 0;
res->tv_nsec = ns;
}
- return 0;
+ return true;
}
static __maybe_unused
int __cvdso_clock_getres_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *res)
{
- int ret = __cvdso_clock_getres_common(vd, clock, res);
+ bool ok;
- if (unlikely(ret))
+ ok = __cvdso_clock_getres_common(vd, clock, res);
+
+ if (unlikely(!ok))
return clock_getres_fallback(clock, res);
return 0;
}
@@ -460,18 +462,18 @@ __cvdso_clock_getres_time32_data(const struct vdso_time_data *vd, clockid_t cloc
struct old_timespec32 *res)
{
struct __kernel_timespec ts;
- int ret;
+ bool ok;
- ret = __cvdso_clock_getres_common(vd, clock, &ts);
+ ok = __cvdso_clock_getres_common(vd, clock, &ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_getres32_fallback(clock, res);
if (likely(res)) {
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
}
- return ret;
+ return 0;
}
static __maybe_unused int
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/helpers: Add helpers for seqlocks of single vdso_clock
2025-07-01 8:57 ` [PATCH 04/14] vdso/helpers: Add helpers for seqlocks of single vdso_clock Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 9916785ef2ce464edd83fce80eaa11fab7792547
Gitweb: https://git.kernel.org/tip/9916785ef2ce464edd83fce80eaa11fab7792547
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:58 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:51 +02:00
vdso/helpers: Add helpers for seqlocks of single vdso_clock
Auxiliary clocks will have their vDSO data in a dedicated 'struct vdso_clock',
which needs to be synchronized independently.
Add a helper to synchronize a single vDSO clock.
[ tglx: Move the SMP memory barriers to the call sites and get rid of the
confusing first/last arguments and conditional barriers ]
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-4-df7d9f87b9b8@linutronix.de
---
include/vdso/helpers.h | 50 +++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
index 0a98fed..1a5ee9d 100644
--- a/include/vdso/helpers.h
+++ b/include/vdso/helpers.h
@@ -28,17 +28,47 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
return seq != start;
}
-static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
+static __always_inline void vdso_write_seq_begin(struct vdso_clock *vc)
{
- struct vdso_clock *vc = vd->clock_data;
+ /*
+ * WRITE_ONCE() is required otherwise the compiler can validly tear
+ * updates to vc->seq and it is possible that the value seen by the
+ * reader is inconsistent.
+ */
+ WRITE_ONCE(vc->seq, vc->seq + 1);
+}
+static __always_inline void vdso_write_seq_end(struct vdso_clock *vc)
+{
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
- * updates to vd[x].seq and it is possible that the value seen by the
+ * updates to vc->seq and it is possible that the value seen by the
* reader is inconsistent.
*/
- WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
+ WRITE_ONCE(vc->seq, vc->seq + 1);
+}
+
+static __always_inline void vdso_write_begin_clock(struct vdso_clock *vc)
+{
+ vdso_write_seq_begin(vc);
+ /* Ensure the sequence invalidation is visible before data is modified */
+ smp_wmb();
+}
+
+static __always_inline void vdso_write_end_clock(struct vdso_clock *vc)
+{
+ /* Ensure the data update is visible before the sequence is set valid again */
+ smp_wmb();
+ vdso_write_seq_end(vc);
+}
+
+static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
+{
+ struct vdso_clock *vc = vd->clock_data;
+
+ vdso_write_seq_begin(&vc[CS_HRES_COARSE]);
+ vdso_write_seq_begin(&vc[CS_RAW]);
+ /* Ensure the sequence invalidation is visible before data is modified */
smp_wmb();
}
@@ -46,14 +76,10 @@ static __always_inline void vdso_write_end(struct vdso_time_data *vd)
{
struct vdso_clock *vc = vd->clock_data;
+ /* Ensure the data update is visible before the sequence is set valid again */
smp_wmb();
- /*
- * WRITE_ONCE() is required otherwise the compiler can validly tear
- * updates to vd[x].seq and it is possible that the value seen by the
- * reader is inconsistent.
- */
- WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
+ vdso_write_seq_end(&vc[CS_HRES_COARSE]);
+ vdso_write_seq_end(&vc[CS_RAW]);
}
#endif /* !__ASSEMBLY__ */
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock()
2025-07-01 8:57 ` [PATCH 03/14] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock() Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 88c88561f36b60d500af389fac1e63d3b63cf2a4
Gitweb: https://git.kernel.org/tip/88c88561f36b60d500af389fac1e63d3b63cf2a4
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:57 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:50 +02:00
vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock()
The upcoming auxiliary clocks need this hook, too.
To separate the architecture hooks from the timekeeper internals, refactor
the hook to only operate on a single vDSO clock.
While at it, use a more robust #define for the hook override.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-3-df7d9f87b9b8@linutronix.de
---
arch/arm64/include/asm/vdso/vsyscall.h | 7 +++----
include/asm-generic/vdso/vsyscall.h | 6 +++---
kernel/time/vsyscall.c | 3 ++-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index de58951..417aae5 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -13,12 +13,11 @@
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
static __always_inline
-void __arm64_update_vsyscall(struct vdso_time_data *vdata)
+void __arch_update_vdso_clock(struct vdso_clock *vc)
{
- vdata->clock_data[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
- vdata->clock_data[CS_RAW].mask = VDSO_PRECISION_MASK;
+ vc->mask = VDSO_PRECISION_MASK;
}
-#define __arch_update_vsyscall __arm64_update_vsyscall
+#define __arch_update_vdso_clock __arch_update_vdso_clock
/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index b550afa..7fc0b56 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -22,11 +22,11 @@ static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(vo
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
-#ifndef __arch_update_vsyscall
-static __always_inline void __arch_update_vsyscall(struct vdso_time_data *vdata)
+#ifndef __arch_update_vdso_clock
+static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
{
}
-#endif /* __arch_update_vsyscall */
+#endif /* __arch_update_vdso_clock */
#ifndef __arch_sync_vdso_time_data
static __always_inline void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index d655df2..df6bada 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -118,7 +118,8 @@ void update_vsyscall(struct timekeeper *tk)
if (clock_mode != VDSO_CLOCKMODE_NONE)
update_vdso_time_data(vdata, tk);
- __arch_update_vsyscall(vdata);
+ __arch_update_vdso_clock(&vc[CS_HRES_COARSE]);
+ __arch_update_vdso_clock(&vc[CS_RAW]);
vdso_write_end(vdata);
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Introduce a helper to fill clock configurations
2025-07-01 8:57 ` [PATCH 02/14] vdso/vsyscall: Introduce a helper to fill clock configurations Thomas Weißschuh
@ 2025-07-07 7:11 ` tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-07 7:11 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: d878e2960cb638faf3cc9f1409c6a2a3f9283ec1
Gitweb: https://git.kernel.org/tip/d878e2960cb638faf3cc9f1409c6a2a3f9283ec1
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:56 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Mon, 07 Jul 2025 08:58:50 +02:00
vdso/vsyscall: Introduce a helper to fill clock configurations
The logic to configure a 'struct vdso_clock' from a
'struct tk_read_base' is copied two times.
Split it into a shared function to reduce the duplication,
especially as another user will be added for auxiliary clocks.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-2-df7d9f87b9b8@linutronix.de
---
kernel/time/vsyscall.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index 32ef27c..d655df2 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -15,26 +15,25 @@
#include "timekeeping_internal.h"
+static inline void fill_clock_configuration(struct vdso_clock *vc, const struct tk_read_base *base)
+{
+ vc->cycle_last = base->cycle_last;
+#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
+ vc->max_cycles = base->clock->max_cycles;
+#endif
+ vc->mask = base->mask;
+ vc->mult = base->mult;
+ vc->shift = base->shift;
+}
+
static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
{
struct vdso_clock *vc = vdata->clock_data;
struct vdso_timestamp *vdso_ts;
u64 nsec, sec;
- vc[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
-#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vc[CS_HRES_COARSE].max_cycles = tk->tkr_mono.clock->max_cycles;
-#endif
- vc[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
- vc[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
- vc[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
- vc[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
-#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vc[CS_RAW].max_cycles = tk->tkr_raw.clock->max_cycles;
-#endif
- vc[CS_RAW].mask = tk->tkr_raw.mask;
- vc[CS_RAW].mult = tk->tkr_raw.mult;
- vc[CS_RAW].shift = tk->tkr_raw.shift;
+ fill_clock_configuration(&vc[CS_HRES_COARSE], &tk->tkr_mono);
+ fill_clock_configuration(&vc[CS_RAW], &tk->tkr_raw);
/* CLOCK_MONOTONIC */
vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
^ permalink raw reply related [flat|nested] 72+ messages in thread
* Re: [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality
2025-07-06 20:26 ` Thomas Gleixner
@ 2025-07-07 7:17 ` Thomas Weißschuh
2025-07-07 13:18 ` Thomas Gleixner
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-07 7:17 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Andy Lutomirski, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Sun, Jul 06, 2025 at 10:26:31PM +0200, Thomas Gleixner wrote:
> On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
>
> > Extend the auxclock test to also cover the vDSO.
>
> I'm not really convinved, that this is the right thing to do. Why can't
> this just extend selftests/vDSO instead of creating these
>
> > +#include "../vDSO/parse_vdso.c"
> > +#include "../vDSO/vdso_config.h"
> > +#include "../vDSO/vdso_call.h"
>
> cross directory oddities? Confused.
Then we'd have to duplicate the auxclock management into the vDSO selftests.
And the knowledge about the expected clock_getres() return values.
In general I think we need to introduce some reuse of the vDSO parsing code
from other selftests in any case. For example the timens selftests call the
vDSO by just invoking the libc wrappers. But the libc may not support a vDSO,
have it disabled for some reason or the vDSO itself falls back to a syscall.
I intend to introduce some vDSO accessors which force the usage of the vDSO
fastpath by using parse_vdso.c to directly call into the vDSO and seccomp to
inhibit the fallback syscalls.
Or, to avoid a dependency we could move the vDSO parsing one step up to
tools/testing/selftests/vdso_support.h, and clean up the interfaces.
Thomas
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-07 6:57 ` Thomas Gleixner
@ 2025-07-07 11:34 ` Arnd Bergmann
2025-07-07 13:16 ` Thomas Gleixner
0 siblings, 1 reply; 72+ messages in thread
From: Arnd Bergmann @ 2025-07-07 11:34 UTC (permalink / raw)
To: Thomas Gleixner, Thomas Weißschuh, Andy Lutomirski,
Vincenzo Frascino, shuah, Anna-Maria Gleixner,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, Linux-Arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Mon, Jul 7, 2025, at 08:57, Thomas Gleixner wrote:
> On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
>>
>> +#if defined(CONFIG_GENERIC_TIME_VSYSCALL) && defined(CONFIG_GENERIC_GETTIMEOFDAY) && \
>> + defined(CONFIG_POSIX_AUX_CLOCKS)
>
> CONFIG_GENERIC_GETTIMEOFDAY requires CONFIG_GENERIC_TIME_VSYSCALL, but
> that's not expressed anywhere. This stuff has grown too many config
> options over time:
>
> GENERIC_TIME_VSYSCALL, HAVE_GENERIC_VDSO, GENERIC_VDSO_DATA_STORE
>
> All architectures except SPARC64 use the generic code and the generic
> VDSO data store implementation. That config maze wants to be
> consolidated.
Would it help to replace the custom sparc64 vdso with the
thing that parisc does and call the fallback directly?
I doubt anyone still cares about the clock_gettime() performance
on sparc64, and removing it would remove all those special cases:
arch/sparc/Kconfig | 1 -
arch/sparc/include/asm/vvar.h | 75 --------
arch/sparc/kernel/Makefile | 1 -
arch/sparc/kernel/vdso.c | 69 --------
arch/sparc/vdso/Makefile | 2 +-
arch/sparc/vdso/vclock_gettime.c | 340 +++---------------------------------
arch/sparc/vdso/vdso.lds.S | 2 -
arch/sparc/vdso/vdso32/vdso32.lds.S | 3 +-
arch/sparc/vdso/vma.c | 265 +---------------------------
9 files changed, 28 insertions(+), 730 deletions(-)
(the added lines here also fix the missing clock_gettime64,
which was equally blocked on the sparc64 oddities)
Arnd
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-07 11:34 ` Arnd Bergmann
@ 2025-07-07 13:16 ` Thomas Gleixner
2025-07-07 14:48 ` Arnd Bergmann
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Gleixner @ 2025-07-07 13:16 UTC (permalink / raw)
To: Arnd Bergmann, Thomas Weißschuh, Andy Lutomirski,
Vincenzo Frascino, shuah, Anna-Maria Gleixner,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, Linux-Arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Mon, Jul 07 2025 at 13:34, Arnd Bergmann wrote:
> On Mon, Jul 7, 2025, at 08:57, Thomas Gleixner wrote:
>> On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
>>>
>>> +#if defined(CONFIG_GENERIC_TIME_VSYSCALL) && defined(CONFIG_GENERIC_GETTIMEOFDAY) && \
>>> + defined(CONFIG_POSIX_AUX_CLOCKS)
>>
>> CONFIG_GENERIC_GETTIMEOFDAY requires CONFIG_GENERIC_TIME_VSYSCALL, but
>> that's not expressed anywhere. This stuff has grown too many config
>> options over time:
>>
>> GENERIC_TIME_VSYSCALL, HAVE_GENERIC_VDSO, GENERIC_VDSO_DATA_STORE
>>
>> All architectures except SPARC64 use the generic code and the generic
>> VDSO data store implementation. That config maze wants to be
>> consolidated.
>
> Would it help to replace the custom sparc64 vdso with the
> thing that parisc does and call the fallback directly?
Definitely.
> I doubt anyone still cares about the clock_gettime() performance
> on sparc64, and removing it would remove all those special cases:
>
> arch/sparc/Kconfig | 1 -
> arch/sparc/include/asm/vvar.h | 75 --------
> arch/sparc/kernel/Makefile | 1 -
> arch/sparc/kernel/vdso.c | 69 --------
> arch/sparc/vdso/Makefile | 2 +-
> arch/sparc/vdso/vclock_gettime.c | 340 +++---------------------------------
> arch/sparc/vdso/vdso.lds.S | 2 -
> arch/sparc/vdso/vdso32/vdso32.lds.S | 3 +-
> arch/sparc/vdso/vma.c | 265 +---------------------------
> 9 files changed, 28 insertions(+), 730 deletions(-)
That's definitely an argument :)
> (the added lines here also fix the missing clock_gettime64,
> which was equally blocked on the sparc64 oddities)
I'm all for it.
Can you post a patch to that effect?
Thanks,
tglx
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality
2025-07-07 7:17 ` Thomas Weißschuh
@ 2025-07-07 13:18 ` Thomas Gleixner
0 siblings, 0 replies; 72+ messages in thread
From: Thomas Gleixner @ 2025-07-07 13:18 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Mon, Jul 07 2025 at 09:17, Thomas Weißschuh wrote:
> On Sun, Jul 06, 2025 at 10:26:31PM +0200, Thomas Gleixner wrote:
>> On Tue, Jul 01 2025 at 10:58, Thomas Weißschuh wrote:
>>
>> > Extend the auxclock test to also cover the vDSO.
>>
>> I'm not really convinved, that this is the right thing to do. Why can't
>> this just extend selftests/vDSO instead of creating these
>>
>> > +#include "../vDSO/parse_vdso.c"
>> > +#include "../vDSO/vdso_config.h"
>> > +#include "../vDSO/vdso_call.h"
>>
>> cross directory oddities? Confused.
>
> Then we'd have to duplicate the auxclock management into the vDSO selftests.
Fair enough.
> I intend to introduce some vDSO accessors which force the usage of the vDSO
> fastpath by using parse_vdso.c to directly call into the vDSO and seccomp to
> inhibit the fallback syscalls.
>
> Or, to avoid a dependency we could move the vDSO parsing one step up to
> tools/testing/selftests/vdso_support.h, and clean up the interfaces.
Maybe that's not the worst thing as there are VDSO tests in several
places by now.
Thanks,
tglx
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-07 13:16 ` Thomas Gleixner
@ 2025-07-07 14:48 ` Arnd Bergmann
0 siblings, 0 replies; 72+ messages in thread
From: Arnd Bergmann @ 2025-07-07 14:48 UTC (permalink / raw)
To: Thomas Gleixner, Thomas Weißschuh, Andy Lutomirski,
Vincenzo Frascino, shuah, Anna-Maria Gleixner,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, Linux-Arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Mon, Jul 7, 2025, at 15:16, Thomas Gleixner wrote:
> On Mon, Jul 07 2025 at 13:34, Arnd Bergmann wrote:
>> On Mon, Jul 7, 2025, at 08:57, Thomas Gleixner wrote:
>> (the added lines here also fix the missing clock_gettime64,
>> which was equally blocked on the sparc64 oddities)
>
> I'm all for it.
>
> Can you post a patch to that effect?
>
Sent, plus a bonus patch to remove CONFIG_ARCH_CLOCKSOURCE_DATA.
Arnd
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
[not found] ` <CGME20250708151720eucas1p260f984fd95d3460d3e9f6c9b48e0e25c@eucas1p2.samsung.com>
@ 2025-07-08 15:17 ` Marek Szyprowski
[not found] ` <CGME20250708154921eucas1p1fd8fa4374610a991ca5c67bd612ca0c2@eucas1p1.samsung.com>
0 siblings, 1 reply; 72+ messages in thread
From: Marek Szyprowski @ 2025-07-08 15:17 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On 01.07.2025 10:58, Thomas Weißschuh wrote:
> The internal helpers are effectively using boolean results,
> while pretending to use error numbers.
>
> Switch the return type to bool for more clarity.
>
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> ---
> lib/vdso/gettimeofday.c | 58 +++++++++++++++++++++++++------------------------
> 1 file changed, 30 insertions(+), 28 deletions(-)
This patch landed in today's linux-next as commit fcc8e46f768f
("vdso/gettimeofday: Return bool from clock_gettime() helpers"). In my
tests I found that it causes serious problem with hwclock operation on
some of my ARM 32bit test boards. I observe that calling "hwclock -w -f
/dev/rtc0" never ends on those boards. Disabling vdso support (by
removing ARM architected timer) fixes this issue.
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index 9b77f23566f6a35887d4c9aaefc61a971131b499..c5266532a097c06f33d12e345c695357d75abf42 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -82,8 +82,8 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
> #endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
>
> static __always_inline
> -int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> - clockid_t clk, struct __kernel_timespec *ts)
> +bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> + clockid_t clk, struct __kernel_timespec *ts)
> {
> const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
> const struct timens_offset *offs = &vcns->offset[clk];
> @@ -103,11 +103,11 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
> seq = vdso_read_begin(vc);
>
> if (unlikely(!vdso_clocksource_ok(vc)))
> - return -1;
> + return false;
>
> cycles = __arch_get_hw_counter(vc->clock_mode, vd);
> if (unlikely(!vdso_cycles_ok(cycles)))
> - return -1;
> + return false;
> ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
> sec = vdso_ts->sec;
> } while (unlikely(vdso_read_retry(vc, seq)));
> @@ -123,7 +123,7 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
> ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
> ts->tv_nsec = ns;
>
> - return 0;
> + return true;
> }
> #else
> static __always_inline
> @@ -133,16 +133,16 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
> }
>
> static __always_inline
> -int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> - clockid_t clk, struct __kernel_timespec *ts)
> +bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> + clockid_t clk, struct __kernel_timespec *ts)
> {
> - return -EINVAL;
> + return false;
> }
> #endif
>
> static __always_inline
> -int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> - clockid_t clk, struct __kernel_timespec *ts)
> +bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> + clockid_t clk, struct __kernel_timespec *ts)
> {
> const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
> u64 cycles, sec, ns;
> @@ -150,7 +150,7 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
>
> /* Allows to compile the high resolution parts out */
> if (!__arch_vdso_hres_capable())
> - return -1;
> + return false;
>
> do {
> /*
> @@ -173,11 +173,11 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> smp_rmb();
>
> if (unlikely(!vdso_clocksource_ok(vc)))
> - return -1;
> + return false;
>
> cycles = __arch_get_hw_counter(vc->clock_mode, vd);
> if (unlikely(!vdso_cycles_ok(cycles)))
> - return -1;
> + return false;
> ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
> sec = vdso_ts->sec;
> } while (unlikely(vdso_read_retry(vc, seq)));
> @@ -189,13 +189,13 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
> ts->tv_nsec = ns;
>
> - return 0;
> + return true;
> }
>
> #ifdef CONFIG_TIME_NS
> static __always_inline
> -int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> - clockid_t clk, struct __kernel_timespec *ts)
> +bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> + clockid_t clk, struct __kernel_timespec *ts)
> {
> const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
> const struct timens_offset *offs = &vcns->offset[clk];
> @@ -223,20 +223,20 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
> */
> ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
> ts->tv_nsec = nsec;
> - return 0;
> + return true;
> }
> #else
> static __always_inline
> -int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> - clockid_t clk, struct __kernel_timespec *ts)
> +bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
> + clockid_t clk, struct __kernel_timespec *ts)
> {
> - return -1;
> + return false;
> }
> #endif
>
> static __always_inline
> -int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> - clockid_t clk, struct __kernel_timespec *ts)
> +bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> + clockid_t clk, struct __kernel_timespec *ts)
> {
> const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
> u32 seq;
> @@ -258,10 +258,10 @@ int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
> ts->tv_nsec = vdso_ts->nsec;
> } while (unlikely(vdso_read_retry(vc, seq)));
>
> - return 0;
> + return true;
> }
>
> -static __always_inline int
> +static __always_inline bool
> __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
> struct __kernel_timespec *ts)
> {
> @@ -270,7 +270,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
>
> /* Check for negative values or invalid clocks */
> if (unlikely((u32) clock >= MAX_CLOCKS))
> - return -1;
> + return false;
>
> /*
> * Convert the clockid to a bitmask and use it to check which
> @@ -284,7 +284,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
> else if (msk & VDSO_RAW)
> vc = &vc[CS_RAW];
> else
> - return -1;
> + return false;
>
> return do_hres(vd, vc, clock, ts);
> }
> @@ -293,9 +293,11 @@ static __maybe_unused int
> __cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
> struct __kernel_timespec *ts)
> {
> - int ret = __cvdso_clock_gettime_common(vd, clock, ts);
> + bool ok;
>
> - if (unlikely(ret))
> + ok = __cvdso_clock_gettime_common(vd, clock, ts);
> +
> + if (unlikely(!ok))
> return clock_gettime_fallback(clock, ts);
> return 0;
> }
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
[not found] ` <CGME20250708154921eucas1p1fd8fa4374610a991ca5c67bd612ca0c2@eucas1p1.samsung.com>
@ 2025-07-08 15:49 ` Marek Szyprowski
2025-07-09 7:34 ` Thomas Weißschuh
0 siblings, 1 reply; 72+ messages in thread
From: Marek Szyprowski @ 2025-07-08 15:49 UTC (permalink / raw)
To: Thomas Weißschuh, Andy Lutomirski, Thomas Gleixner,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann
Cc: linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On 08.07.2025 17:17, Marek Szyprowski wrote:
> On 01.07.2025 10:58, Thomas Weißschuh wrote:
>> The internal helpers are effectively using boolean results,
>> while pretending to use error numbers.
>>
>> Switch the return type to bool for more clarity.
>>
>> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>> ---
>> lib/vdso/gettimeofday.c | 58
>> +++++++++++++++++++++++++------------------------
>> 1 file changed, 30 insertions(+), 28 deletions(-)
>
> This patch landed in today's linux-next as commit fcc8e46f768f
> ("vdso/gettimeofday: Return bool from clock_gettime() helpers"). In my
> tests I found that it causes serious problem with hwclock operation on
> some of my ARM 32bit test boards. I observe that calling "hwclock -w
> -f /dev/rtc0" never ends on those boards. Disabling vdso support (by
> removing ARM architected timer) fixes this issue.
I spent some time analyzing the code refactored in this patch and it
looks that the following change is missing:
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index c5266532a097..7e79b02839b0 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -344,7 +344,7 @@ __cvdso_gettimeofday_data(const struct
vdso_time_data *vd,
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
- if (do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
+ if (!do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
return gettimeofday_fallback(tv, tz);
tv->tv_sec = ts.tv_sec;
In my tests this fixed the hwclock issue on the mentioned boards.
>
>> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
>> index
>> 9b77f23566f6a35887d4c9aaefc61a971131b499..c5266532a097c06f33d12e345c695357d75abf42
>> 100644
>> --- a/lib/vdso/gettimeofday.c
>> +++ b/lib/vdso/gettimeofday.c
>> @@ -82,8 +82,8 @@ const struct vdso_time_data
>> *__arch_get_vdso_u_timens_data(const struct vdso_tim
>> #endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
>> static __always_inline
>> -int do_hres_timens(const struct vdso_time_data *vdns, const struct
>> vdso_clock *vcns,
>> - clockid_t clk, struct __kernel_timespec *ts)
>> +bool do_hres_timens(const struct vdso_time_data *vdns, const struct
>> vdso_clock *vcns,
>> + clockid_t clk, struct __kernel_timespec *ts)
>> {
>> const struct vdso_time_data *vd =
>> __arch_get_vdso_u_timens_data(vdns);
>> const struct timens_offset *offs = &vcns->offset[clk];
>> @@ -103,11 +103,11 @@ int do_hres_timens(const struct vdso_time_data
>> *vdns, const struct vdso_clock *v
>> seq = vdso_read_begin(vc);
>> if (unlikely(!vdso_clocksource_ok(vc)))
>> - return -1;
>> + return false;
>> cycles = __arch_get_hw_counter(vc->clock_mode, vd);
>> if (unlikely(!vdso_cycles_ok(cycles)))
>> - return -1;
>> + return false;
>> ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
>> sec = vdso_ts->sec;
>> } while (unlikely(vdso_read_retry(vc, seq)));
>> @@ -123,7 +123,7 @@ int do_hres_timens(const struct vdso_time_data
>> *vdns, const struct vdso_clock *v
>> ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
>> ts->tv_nsec = ns;
>> - return 0;
>> + return true;
>> }
>> #else
>> static __always_inline
>> @@ -133,16 +133,16 @@ const struct vdso_time_data
>> *__arch_get_vdso_u_timens_data(const struct vdso_tim
>> }
>> static __always_inline
>> -int do_hres_timens(const struct vdso_time_data *vdns, const struct
>> vdso_clock *vcns,
>> - clockid_t clk, struct __kernel_timespec *ts)
>> +bool do_hres_timens(const struct vdso_time_data *vdns, const struct
>> vdso_clock *vcns,
>> + clockid_t clk, struct __kernel_timespec *ts)
>> {
>> - return -EINVAL;
>> + return false;
>> }
>> #endif
>> static __always_inline
>> -int do_hres(const struct vdso_time_data *vd, const struct vdso_clock
>> *vc,
>> - clockid_t clk, struct __kernel_timespec *ts)
>> +bool do_hres(const struct vdso_time_data *vd, const struct
>> vdso_clock *vc,
>> + clockid_t clk, struct __kernel_timespec *ts)
>> {
>> const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
>> u64 cycles, sec, ns;
>> @@ -150,7 +150,7 @@ int do_hres(const struct vdso_time_data *vd,
>> const struct vdso_clock *vc,
>> /* Allows to compile the high resolution parts out */
>> if (!__arch_vdso_hres_capable())
>> - return -1;
>> + return false;
>> do {
>> /*
>> @@ -173,11 +173,11 @@ int do_hres(const struct vdso_time_data *vd,
>> const struct vdso_clock *vc,
>> smp_rmb();
>> if (unlikely(!vdso_clocksource_ok(vc)))
>> - return -1;
>> + return false;
>> cycles = __arch_get_hw_counter(vc->clock_mode, vd);
>> if (unlikely(!vdso_cycles_ok(cycles)))
>> - return -1;
>> + return false;
>> ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
>> sec = vdso_ts->sec;
>> } while (unlikely(vdso_read_retry(vc, seq)));
>> @@ -189,13 +189,13 @@ int do_hres(const struct vdso_time_data *vd,
>> const struct vdso_clock *vc,
>> ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
>> ts->tv_nsec = ns;
>> - return 0;
>> + return true;
>> }
>> #ifdef CONFIG_TIME_NS
>> static __always_inline
>> -int do_coarse_timens(const struct vdso_time_data *vdns, const struct
>> vdso_clock *vcns,
>> - clockid_t clk, struct __kernel_timespec *ts)
>> +bool do_coarse_timens(const struct vdso_time_data *vdns, const
>> struct vdso_clock *vcns,
>> + clockid_t clk, struct __kernel_timespec *ts)
>> {
>> const struct vdso_time_data *vd =
>> __arch_get_vdso_u_timens_data(vdns);
>> const struct timens_offset *offs = &vcns->offset[clk];
>> @@ -223,20 +223,20 @@ int do_coarse_timens(const struct
>> vdso_time_data *vdns, const struct vdso_clock
>> */
>> ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
>> ts->tv_nsec = nsec;
>> - return 0;
>> + return true;
>> }
>> #else
>> static __always_inline
>> -int do_coarse_timens(const struct vdso_time_data *vdns, const struct
>> vdso_clock *vcns,
>> - clockid_t clk, struct __kernel_timespec *ts)
>> +bool do_coarse_timens(const struct vdso_time_data *vdns, const
>> struct vdso_clock *vcns,
>> + clockid_t clk, struct __kernel_timespec *ts)
>> {
>> - return -1;
>> + return false;
>> }
>> #endif
>> static __always_inline
>> -int do_coarse(const struct vdso_time_data *vd, const struct
>> vdso_clock *vc,
>> - clockid_t clk, struct __kernel_timespec *ts)
>> +bool do_coarse(const struct vdso_time_data *vd, const struct
>> vdso_clock *vc,
>> + clockid_t clk, struct __kernel_timespec *ts)
>> {
>> const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
>> u32 seq;
>> @@ -258,10 +258,10 @@ int do_coarse(const struct vdso_time_data *vd,
>> const struct vdso_clock *vc,
>> ts->tv_nsec = vdso_ts->nsec;
>> } while (unlikely(vdso_read_retry(vc, seq)));
>> - return 0;
>> + return true;
>> }
>> -static __always_inline int
>> +static __always_inline bool
>> __cvdso_clock_gettime_common(const struct vdso_time_data *vd,
>> clockid_t clock,
>> struct __kernel_timespec *ts)
>> {
>> @@ -270,7 +270,7 @@ __cvdso_clock_gettime_common(const struct
>> vdso_time_data *vd, clockid_t clock,
>> /* Check for negative values or invalid clocks */
>> if (unlikely((u32) clock >= MAX_CLOCKS))
>> - return -1;
>> + return false;
>> /*
>> * Convert the clockid to a bitmask and use it to check which
>> @@ -284,7 +284,7 @@ __cvdso_clock_gettime_common(const struct
>> vdso_time_data *vd, clockid_t clock,
>> else if (msk & VDSO_RAW)
>> vc = &vc[CS_RAW];
>> else
>> - return -1;
>> + return false;
>> return do_hres(vd, vc, clock, ts);
>> }
>> @@ -293,9 +293,11 @@ static __maybe_unused int
>> __cvdso_clock_gettime_data(const struct vdso_time_data *vd,
>> clockid_t clock,
>> struct __kernel_timespec *ts)
>> {
>> - int ret = __cvdso_clock_gettime_common(vd, clock, ts);
>> + bool ok;
>> - if (unlikely(ret))
>> + ok = __cvdso_clock_gettime_common(vd, clock, ts);
>> +
>> + if (unlikely(!ok))
>> return clock_gettime_fallback(clock, ts);
>> return 0;
>> }
>>
> Best regards
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply related [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-08 15:49 ` Marek Szyprowski
@ 2025-07-09 7:34 ` Thomas Weißschuh
2025-07-09 8:04 ` Marek Szyprowski
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-09 7:34 UTC (permalink / raw)
To: Marek Szyprowski, Thomas Gleixner
Cc: Andy Lutomirski, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
Hi Marek,
On Tue, Jul 08, 2025 at 05:49:18PM +0200, Marek Szyprowski wrote:
> On 08.07.2025 17:17, Marek Szyprowski wrote:
> > On 01.07.2025 10:58, Thomas Weißschuh wrote:
> >> The internal helpers are effectively using boolean results,
> >> while pretending to use error numbers.
> >>
> >> Switch the return type to bool for more clarity.
> >>
> >> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> >> ---
> >> lib/vdso/gettimeofday.c | 58
> >> +++++++++++++++++++++++++------------------------
> >> 1 file changed, 30 insertions(+), 28 deletions(-)
> >
> > This patch landed in today's linux-next as commit fcc8e46f768f
> > ("vdso/gettimeofday: Return bool from clock_gettime() helpers"). In my
> > tests I found that it causes serious problem with hwclock operation on
> > some of my ARM 32bit test boards. I observe that calling "hwclock -w
> > -f /dev/rtc0" never ends on those boards. Disabling vdso support (by
> > removing ARM architected timer) fixes this issue.
>
> I spent some time analyzing the code refactored in this patch and it
> looks that the following change is missing:
Thanks for the report and investigation!
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index c5266532a097..7e79b02839b0 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -344,7 +344,7 @@ __cvdso_gettimeofday_data(const struct
> vdso_time_data *vd,
> if (likely(tv != NULL)) {
> struct __kernel_timespec ts;
>
> - if (do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
> + if (!do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
> return gettimeofday_fallback(tv, tz);
>
> tv->tv_sec = ts.tv_sec;
>
>
> In my tests this fixed the hwclock issue on the mentioned boards.
This fix looks correct to me.
tglx:
Are you going to fold the fix into the commit or do you want a proper patch?
Marek:
If a new patch is required, do you want to send it? You found and fixed the
issue after all. If not, I'll take care of it.
Thomas
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-09 7:34 ` Thomas Weißschuh
@ 2025-07-09 8:04 ` Marek Szyprowski
2025-07-16 12:25 ` Mark Brown
0 siblings, 1 reply; 72+ messages in thread
From: Marek Szyprowski @ 2025-07-09 8:04 UTC (permalink / raw)
To: Thomas Weißschuh, Thomas Gleixner
Cc: Andy Lutomirski, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On 09.07.2025 09:34, Thomas Weißschuh wrote:
> On Tue, Jul 08, 2025 at 05:49:18PM +0200, Marek Szyprowski wrote:
>> On 08.07.2025 17:17, Marek Szyprowski wrote:
>>> On 01.07.2025 10:58, Thomas Weißschuh wrote:
>>>> The internal helpers are effectively using boolean results,
>>>> while pretending to use error numbers.
>>>>
>>>> Switch the return type to bool for more clarity.
>>>>
>>>> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>>>> ---
>>>> lib/vdso/gettimeofday.c | 58
>>>> +++++++++++++++++++++++++------------------------
>>>> 1 file changed, 30 insertions(+), 28 deletions(-)
>>> This patch landed in today's linux-next as commit fcc8e46f768f
>>> ("vdso/gettimeofday: Return bool from clock_gettime() helpers"). In my
>>> tests I found that it causes serious problem with hwclock operation on
>>> some of my ARM 32bit test boards. I observe that calling "hwclock -w
>>> -f /dev/rtc0" never ends on those boards. Disabling vdso support (by
>>> removing ARM architected timer) fixes this issue.
>> I spent some time analyzing the code refactored in this patch and it
>> looks that the following change is missing:
> Thanks for the report and investigation!
>
>> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
>> index c5266532a097..7e79b02839b0 100644
>> --- a/lib/vdso/gettimeofday.c
>> +++ b/lib/vdso/gettimeofday.c
>> @@ -344,7 +344,7 @@ __cvdso_gettimeofday_data(const struct
>> vdso_time_data *vd,
>> if (likely(tv != NULL)) {
>> struct __kernel_timespec ts;
>>
>> - if (do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
>> + if (!do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
>> return gettimeofday_fallback(tv, tz);
>>
>> tv->tv_sec = ts.tv_sec;
>>
>>
>> In my tests this fixed the hwclock issue on the mentioned boards.
> This fix looks correct to me.
>
>
> tglx:
>
> Are you going to fold the fix into the commit or do you want a proper patch?
>
>
> Marek:
>
> If a new patch is required, do you want to send it? You found and fixed the
> issue after all. If not, I'll take care of it.
If it is possible to fold it into original patch then go ahead, it would
make less noise imho. If you need a formal patch, I can send it in a few
minutes.
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
[not found] ` <CGME20250708151720eucas1p260f984fd95d3460d3e9f6c9b48e0e25c@eucas1p2.samsung.com>
@ 2025-07-09 8:29 ` Mark Brown
2025-07-09 9:57 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
` (2 subsequent siblings)
5 siblings, 0 replies; 72+ messages in thread
From: Mark Brown @ 2025-07-09 8:29 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Marek Szyprowski, Nam Cao,
Antoine Tenart
[-- Attachment #1: Type: text/plain, Size: 23595 bytes --]
On Tue, Jul 01, 2025 at 10:58:00AM +0200, Thomas Weißschuh wrote:
> The internal helpers are effectively using boolean results,
> while pretending to use error numbers.
>
> Switch the return type to bool for more clarity.
Marek already reported and analysed a hwclock issue with this but I'm
also seeing issues with the vDSO selftest's vdso_test_correcteness on
pine64plus (an arm64 board) which bisect down to this patch:
# [RUN] Testing gettimeofday...
# 1752000653.829103 0.000000 1752000653.829106
# [FAIL] Times are out of sequence
https://lava.sirena.org.uk/scheduler/job/1550140#L9170
and it causes infrastructure issues due to time on x15 (a 32 bit arm
platform):
| INFO: Generating a skipfile based on /lava-4163764/1/tests/5_kselftest-signal/automated/linux/kselftest/skipfile-lkft.yaml
| fatal error: nanotime returning zero
| goroutine 1 [running, locked to thread]:
| runtime.throw(0x132d83, 0x17)
| /usr/lib/golang/src/runtime/panic.go:774 +0x5c fp=0x42c7a4 sp=0x42c790 pc=0x3b740
| runtime.main()
| /usr/lib/golang/src/runtime/proc.go:152 +0x350 fp=0x42c7e4 sp=0x42c7a4 pc=0x3d308
| runtime.goexit()
| /usr/lib/golang/src/runtime/asm_arm.s:868 +0x4 fp=0x42c7e4 sp=0x42c7e4 pc=0x645dc
| ERROR: skipgen failed to generate a skipfile: 2
https://validation.linaro.org/scheduler/job/4163764#L2162
for mystifying reasons which bisect similarly. I'll try to test Marek's
fix but I'm at a conference this week so no guarantees.
bisect for pine64plus:
# bad: [58ba80c4740212c29a1cf9b48f588e60a7612209] Add linux-next specific files for 20250708
# good: [3a92879a3786d4f28bb3a91a07fd58359b29ca13] Merge branch 'for-linux-next-fixes' of https://gitlab.freedesktop.org/drm/misc/kernel.git
# good: [08dc0f5cc26a203e8008c38d9b436c079e7dbb45] ASoC: soc-dapm: add prefix on soc_dapm_dev_attrs
# good: [571defe0dff3f1e4180bd0db79283d3d5bf74a71] ASoC: codec: rockchip_sai: Remove including of_gpio.h
# good: [2fca750160f29015ab1109bb478537a4e415f7cd] spi: Remove redundant pm_runtime_mark_last_busy() calls
# good: [2bd9648d5a8d329ca734ca2c273a80934867471e] ASoC: SOF: Remove redundant pm_runtime_mark_last_busy() calls
# good: [c61e94e5e4e6bc50064119e6a779564d1d2ac0e7] regulator: stm32-vrefbuf: Remove redundant pm_runtime_mark_last_busy() calls
# good: [bc163baef57002c08b3afe64cdd2f55f55a765eb] ASoC: Use of_reserved_mem_region_to_resource() for "memory-region"
# good: [9f711c9321cffe3e03709176873c277fa911c366] regmap: get rid of redundant debugfs_file_{get,put}()
# good: [baee26a9d6cd3d3c6c3c03c56270aa647a67e4bd] ASoC: fsl_mqs: rename system manager indices for i.MX95
# good: [7105fdd54a14bee49371b39374a61b3c967d74cb] spi: dt-bindings: Convert marvell,orion-spi to DT schema
# good: [913bf8d50cbd144c87e9660b591781179182ff59] spi: spi-qpic-snand: add support for 8 bits ECC strength
# good: [34d340d48e595f8dfd4e72fe4100d2579dbe4a1a] ASoC: qcom: sc8280xp: Add support for QCS8275
# good: [0c0ef1d90967717b91cded41b00dbae05d8e521c] ASoC: amd: acp: Enable acp7.2 platform based DMIC support in machine driver
# good: [3fcd3d2fe44dc9dfca20b6aed117f314a50ba0ff] spi: offload trigger: add ADI Util Sigma-Delta SPI driver
# good: [244bc18e5f1875401a4af87d2eae3f9376d9d720] spi: stm32: delete stray tabs in stm32h7_spi_data_idleness()
# good: [7e1c28fbf235791cb5046fafdac5bc16fe8e788d] spi: spi-pci1xxxx: enable concurrent DMA read/write across SPI transfers
# good: [c4f2c05ab02952c9a56067aeb700ded95b183570] spi: stm32: fix pointer-to-pointer variables usage
# good: [b9ab3b61824190b1c6b2c59e7ba4de591f24eb92] ASoC: SDCA: Add some initial IRQ handlers
# good: [427ceac823e58813b510e585011488f603f0d891] regulator: tps6286x-regulator: Enable REGCACHE_MAPLE
# good: [29ddce17e909779633f856ad1c2f111fbf71c0df] ASoC: codecs: Add calibration function to aw88399 chip
# good: [ac4c064f67d3cdf9118b9b09c1e3b28b6c10a7ea] spi: dt-bindings: add nxp,lpc3220-spi.yaml
# good: [08bf1663c21a3e815eda28fa242d84c945ca3b94] dmaengine: Add devm_dma_request_chan()
# good: [ce57bc9771411d6d27f2ca7b40396cbd7d684ba9] regulator: core: Don't use "proxy" headers
# good: [2555691165a0285a4617230fed859f20dcc51608] spi: atmel-quadspi: Use `devm_dma_request_chan()`
# good: [0f60ecffbfe35e12eb56c99640ba2360244b5bb3] ASoC: sdw_utils: generate combined spk components string
# good: [9a944494c299fabf3cc781798eb7c02a0bece364] spi: dt-bindings: stm32: deprecate `st,spi-midi-ns` property
# good: [3e36c822506d924894ff7de549b9377d3114c2d7] spi: spi-pci1xxxx: Add support for per-instance DMA interrupt vectors
# good: [68fbc70ece40139380380dce74059afa592846b3] ASoC: hisilicon: Standardize ASoC menu
# good: [8f9cf02c8852837923f1cdacfcc92e138513325c] spi: microchip-core-qspi: Add regular transfers
# good: [17cc308b183308bf5ada36e164284fff7eb064ba] ASoC: wm8524: enable constraints when sysclk is configured.
# good: [59566923d955b69bfb1e1163f07dff437dde8c9c] ASoC: SOF: amd: add alternate machines for ACP7.0 and ACP7.1 platforms
# good: [024f39fff6d222cedde361f7fe34d9ba4e6afb92] regulator: mtk-dvfsrc: Add support for MediaTek MT8196 DVFSRC
# good: [19cbc930c209d59a2c9828de4c7b767e9f14667e] regulator: pca9450: Support PWM mode also for pca9451a
# good: [c4ca928a6db1593802cd945f075a7e21dd0430c1] ASoC: hdac_hdmi: Rate limit logging on connection and disconnection
# good: [a48352921f0b15b1f7eff83f5b5613d6ae2350d3] ASoC: codecs: wcd939x: Add defines for major/minor version decoding
# good: [3421d46440ebe0865bec71dbd2330b4e17a425ab] HID: core: Add bus define for SoundWire bus
# good: [a1d203d390e04798ccc1c3c06019cd4411885d6d] ASoC: SOF: ipc4-pcm: Enable delay reporting for ChainDMA streams
# good: [bb48117b79ebc39485f7306d09dc602981fe540f] ASoC: Intel: sof_sdw: Implement add_dai_link to filter HDMI PCMs
# good: [ace9b3daf2b4778358573d3698e34cb1c0fa7e14] ASoC: SOF: ipc4/Intel: Add support for library restore firmware functionality
# good: [2756b7f08ff6ca7c68c8c7dd61c8dc6895c9de34] ASoC: SOF: ipc4-pcm: Harmonize sof_ipc4_set_pipeline_state() dbg print
# good: [5fc2c383125c2b4b6037e02ad8796b776b25e6d0] spi: falcon: mark falcon_sflash_xfer() as static
# good: [cd4da713f99651e99fbce8ed6b6ec8f686c029a8] Documentation: PM: *_autosuspend() functions update last busy time
# good: [7f8924e8785b68c998bc1906e049bf5595865e60] ASoC: dt-bindings: cirrus,cs42xx8: add 'port' property
# good: [3e1c01d06e1f52f78fe00ef26a9cf80dbb0a3115] regulator: rpi-panel-v2: Add shutdown hook
# good: [d9f38d9824bfb1b046d2e720349d2f45959ab184] ASoC: tegra: AHUB: Remove unneeded semicolon
# good: [dce4bc30f42d313b4dc5832316196411b7f07ad0] spi: spi-fsl-dspi: Revert unintended dependency change in config SPI_FSL_DSPI
# good: [47972c1c3315672352f25c68f91dd88543541947] ASoC: Intel: Replace deprecated strcpy() with strscpy()
# good: [5eb8a0d7733d4cd32a776acf1d1aa1c7c01c8a14] ASoC: hdmi-codec: use SND_JACK_AVOUT as jack status
# good: [bb8d8ba4715cb8f997d63d90ba935f6073595df5] ASoC: mediatek: mt8183-afe-pcm: use local `dev` pointer in driver callbacks
# good: [8a5a5cecb79058b608e5562d8998123a3adb313c] ASoC: tas2781: Move the "include linux/debugfs.h" into tas2781.h
# good: [a4eb71ff98c4792f441f108910bd829da7a04092] regulator: rpi-panel-v2: Fix missing OF dependency
# good: [6cafcc53eb5fffd9b9bdfde700bb9bad21e98ed3] spi: spi-mt65xx: Add support for MT6991 Dimensity 9400 SPI IPM
# good: [7e10d7242ea8a5947878880b912ffa5806520705] ASoC: ops: dynamically allocate struct snd_ctl_elem_value
# good: [d6fa0ca959db8efd4462d7beef4bdc5568640fd0] regulator: rpi-panel-v2: Add missing GPIOLIB dependency
# good: [6ba68e5aa9d5d15c8877a655db279fcfc0b38b04] ASoC: renesas: msiof: Convert to <linux/spi/sh_msiof.h>
# good: [1f5cdb6ab45e1c06ae0953609acbb52f8946b3e8] ASoC: codecs: Add support for Richtek RTQ9124
# good: [d49305862fdc4d9ff1b1093b4ed7d8e0cb9971b4] regulator: rpi-panel-v2: Add regulator for 7" Raspberry Pi 720x1280
# good: [03b778d1994827ea5cc971dbdfbb457bbb7bfa5d] ASOC: rockchip: Use helper function devm_clk_get_enabled()
# good: [c459262159f39e6e6336797feb975799344b749b] spi: spi-pci1xxxx: Add support for 25MHz Clock frequency in C0
# good: [267be32b0a7b70cc777f8a46f0904c92c0521d89] ASoC: remove component->id
# good: [548d770c330cd1027549947a6ea899c56b5bc4e4] regulator: pca9450: Add support for mode operations
# good: [111a2c8ab462d77d1519b71b46f13ae1b46920b4] ASoC: imx-card: Use helper function for_each_child_of_node_scoped()
# good: [f6f914893d478b7ba08e5c375de1ced16deb5e92] ASoC: dt-bindings: tas57xx: add tas5753 compatibility
# good: [9a30e332c36c52e92e5316b4a012d45284dedeb5] spi: spi-fsl-dspi: Enable support for S32G platforms
# good: [c95e925daa434ee1a40a86aec6476ce588e4bd77] ASoC: Intel: avs: Add rt5640 machine board
# good: [ac209bde018fd320b79976657a44c23113181af6] ASoC: tas2781: Drop the unnecessary symbol imply
# good: [ece5d881004f041c2e1493436409dbcbea3ad5f8] ASoC: codecs: wcd939x: Drop unused 'struct wcd939x_priv' fields
# good: [b9ecde0bcf6a99a3ff08496d4ba90a385ebbfd68] ASoC: codecs: wcd939x: Add VDD_PX supply
# good: [c8c4694ede7ed42d8d4db0e8927dea9839a3e248] regmap: kunit: Constify regmap_range_cfg array
# good: [e6e8897995a9e6028563ce36c27877e5478c8571] ASoC: qcom: sm8250: Add Fairphone 5 soundcard compatible
git bisect start '58ba80c4740212c29a1cf9b48f588e60a7612209' '3a92879a3786d4f28bb3a91a07fd58359b29ca13' '08dc0f5cc26a203e8008c38d9b436c079e7dbb45' '571defe0dff3f1e4180bd0db79283d3d5bf74a71' '2fca750160f29015ab1109bb478537a4e415f7cd' '2bd9648d5a8d329ca734ca2c273a80934867471e' 'c61e94e5e4e6bc50064119e6a779564d1d2ac0e7' 'bc163baef57002c08b3afe64cdd2f55f55a765eb' '9f711c9321cffe3e03709176873c277fa911c366' 'baee26a9d6cd3d3c6c3c03c56270aa647a67e4bd' '7105fdd54a14bee49371b39374a61b3c967d74cb' '913bf8d50cbd144c87e9660b591781179182ff59' '34d340d48e595f8dfd4e72fe4100d2579dbe4a1a' '0c0ef1d90967717b91cded41b00dbae05d8e521c' '3fcd3d2fe44dc9dfca20b6aed117f314a50ba0ff' '244bc18e5f1875401a4af87d2eae3f9376d9d720' '7e1c28fbf235791cb5046fafdac5bc16fe8e788d' 'c4f2c05ab02952c9a56067aeb700ded95b183570' 'b9ab3b61824190b1c6b2c59e7ba4de591f24eb92' '427ceac823e58813b510e585011488f603f0d891' '29ddce17e909779633f856ad1c2f111fbf71c0df' 'ac4c064f67d3cdf9118b9b09c1e3b28b6c10a7ea' '08bf1663c21a3e815eda28fa242d84c945ca3b94' 'ce57bc9771411d6d27f2ca7b40396cbd7d684ba9' '2555691165a0285a4617230fed859f20dcc51608' '0f60ecffbfe35e12eb56c99640ba2360244b5bb3' '9a944494c299fabf3cc781798eb7c02a0bece364' '3e36c822506d924894ff7de549b9377d3114c2d7' '68fbc70ece40139380380dce74059afa592846b3' '8f9cf02c8852837923f1cdacfcc92e138513325c' '17cc308b183308bf5ada36e164284fff7eb064ba' '59566923d955b69bfb1e1163f07dff437dde8c9c' '024f39fff6d222cedde361f7fe34d9ba4e6afb92' '19cbc930c209d59a2c9828de4c7b767e9f14667e' 'c4ca928a6db1593802cd945f075a7e21dd0430c1' 'a48352921f0b15b1f7eff83f5b5613d6ae2350d3' '3421d46440ebe0865bec71dbd2330b4e17a425ab' 'a1d203d390e04798ccc1c3c06019cd4411885d6d' 'bb48117b79ebc39485f7306d09dc602981fe540f' 'ace9b3daf2b4778358573d3698e34cb1c0fa7e14' '2756b7f08ff6ca7c68c8c7dd61c8dc6895c9de34' '5fc2c383125c2b4b6037e02ad8796b776b25e6d0' 'cd4da713f99651e99fbce8ed6b6ec8f686c029a8' '7f8924e8785b68c998bc1906e049bf5595865e60' '3e1c01d06e1f52f78fe00ef26a9cf80dbb0a3115' 'd9f38d9824bfb1b046d2e720349d2f45959ab184' 'dce4bc30f42d313b4dc5832316196411b7f07ad0' '47972c1c3315672352f25c68f91dd88543541947' '5eb8a0d7733d4cd32a776acf1d1aa1c7c01c8a14' 'bb8d8ba4715cb8f997d63d90ba935f6073595df5' '8a5a5cecb79058b608e5562d8998123a3adb313c' 'a4eb71ff98c4792f441f108910bd829da7a04092' '6cafcc53eb5fffd9b9bdfde700bb9bad21e98ed3' '7e10d7242ea8a5947878880b912ffa5806520705' 'd6fa0ca959db8efd4462d7beef4bdc5568640fd0' '6ba68e5aa9d5d15c8877a655db279fcfc0b38b04' '1f5cdb6ab45e1c06ae0953609acbb52f8946b3e8' 'd49305862fdc4d9ff1b1093b4ed7d8e0cb9971b4' '03b778d1994827ea5cc971dbdfbb457bbb7bfa5d' 'c459262159f39e6e6336797feb975799344b749b' '267be32b0a7b70cc777f8a46f0904c92c0521d89' '548d770c330cd1027549947a6ea899c56b5bc4e4' '111a2c8ab462d77d1519b71b46f13ae1b46920b4' 'f6f914893d478b7ba08e5c375de1ced16deb5e92' '9a30e332c36c52e92e5316b4a012d45284dedeb5' 'c95e925daa434ee1a40a86aec6476ce588e4bd77' 'ac209bde018fd320b79976657a44c23113181af6' 'ece5d881004f041c2e1493436409dbcbea3ad5f8' 'b9ecde0bcf6a99a3ff08496d4ba90a385ebbfd68' 'c8c4694ede7ed42d8d4db0e8927dea9839a3e248' 'e6e8897995a9e6028563ce36c27877e5478c8571'
# test job: [08dc0f5cc26a203e8008c38d9b436c079e7dbb45] https://lava.sirena.org.uk/scheduler/job/1546279
# test job: [571defe0dff3f1e4180bd0db79283d3d5bf74a71] https://lava.sirena.org.uk/scheduler/job/1539758
# test job: [2fca750160f29015ab1109bb478537a4e415f7cd] https://lava.sirena.org.uk/scheduler/job/1540294
# test job: [2bd9648d5a8d329ca734ca2c273a80934867471e] https://lava.sirena.org.uk/scheduler/job/1539587
# test job: [c61e94e5e4e6bc50064119e6a779564d1d2ac0e7] https://lava.sirena.org.uk/scheduler/job/1538605
# test job: [bc163baef57002c08b3afe64cdd2f55f55a765eb] https://lava.sirena.org.uk/scheduler/job/1538760
# test job: [9f711c9321cffe3e03709176873c277fa911c366] https://lava.sirena.org.uk/scheduler/job/1538695
# test job: [baee26a9d6cd3d3c6c3c03c56270aa647a67e4bd] https://lava.sirena.org.uk/scheduler/job/1533838
# test job: [7105fdd54a14bee49371b39374a61b3c967d74cb] https://lava.sirena.org.uk/scheduler/job/1533505
# test job: [913bf8d50cbd144c87e9660b591781179182ff59] https://lava.sirena.org.uk/scheduler/job/1531279
# test job: [34d340d48e595f8dfd4e72fe4100d2579dbe4a1a] https://lava.sirena.org.uk/scheduler/job/1530316
# test job: [0c0ef1d90967717b91cded41b00dbae05d8e521c] https://lava.sirena.org.uk/scheduler/job/1530377
# test job: [3fcd3d2fe44dc9dfca20b6aed117f314a50ba0ff] https://lava.sirena.org.uk/scheduler/job/1528995
# test job: [244bc18e5f1875401a4af87d2eae3f9376d9d720] https://lava.sirena.org.uk/scheduler/job/1528294
# test job: [7e1c28fbf235791cb5046fafdac5bc16fe8e788d] https://lava.sirena.org.uk/scheduler/job/1525609
# test job: [c4f2c05ab02952c9a56067aeb700ded95b183570] https://lava.sirena.org.uk/scheduler/job/1526240
# test job: [b9ab3b61824190b1c6b2c59e7ba4de591f24eb92] https://lava.sirena.org.uk/scheduler/job/1526368
# test job: [427ceac823e58813b510e585011488f603f0d891] https://lava.sirena.org.uk/scheduler/job/1525674
# test job: [29ddce17e909779633f856ad1c2f111fbf71c0df] https://lava.sirena.org.uk/scheduler/job/1523960
# test job: [ac4c064f67d3cdf9118b9b09c1e3b28b6c10a7ea] https://lava.sirena.org.uk/scheduler/job/1515936
# test job: [08bf1663c21a3e815eda28fa242d84c945ca3b94] https://lava.sirena.org.uk/scheduler/job/1517680
# test job: [ce57bc9771411d6d27f2ca7b40396cbd7d684ba9] https://lava.sirena.org.uk/scheduler/job/1515829
# test job: [2555691165a0285a4617230fed859f20dcc51608] https://lava.sirena.org.uk/scheduler/job/1515774
# test job: [0f60ecffbfe35e12eb56c99640ba2360244b5bb3] https://lava.sirena.org.uk/scheduler/job/1511599
# test job: [9a944494c299fabf3cc781798eb7c02a0bece364] https://lava.sirena.org.uk/scheduler/job/1507913
# test job: [3e36c822506d924894ff7de549b9377d3114c2d7] https://lava.sirena.org.uk/scheduler/job/1506345
# test job: [68fbc70ece40139380380dce74059afa592846b3] https://lava.sirena.org.uk/scheduler/job/1504169
# test job: [8f9cf02c8852837923f1cdacfcc92e138513325c] https://lava.sirena.org.uk/scheduler/job/1502871
# test job: [17cc308b183308bf5ada36e164284fff7eb064ba] https://lava.sirena.org.uk/scheduler/job/1501545
# test job: [59566923d955b69bfb1e1163f07dff437dde8c9c] https://lava.sirena.org.uk/scheduler/job/1499651
# test job: [024f39fff6d222cedde361f7fe34d9ba4e6afb92] https://lava.sirena.org.uk/scheduler/job/1499702
# test job: [19cbc930c209d59a2c9828de4c7b767e9f14667e] https://lava.sirena.org.uk/scheduler/job/1497288
# test job: [c4ca928a6db1593802cd945f075a7e21dd0430c1] https://lava.sirena.org.uk/scheduler/job/1496256
# test job: [a48352921f0b15b1f7eff83f5b5613d6ae2350d3] https://lava.sirena.org.uk/scheduler/job/1497361
# test job: [3421d46440ebe0865bec71dbd2330b4e17a425ab] https://lava.sirena.org.uk/scheduler/job/1493081
# test job: [a1d203d390e04798ccc1c3c06019cd4411885d6d] https://lava.sirena.org.uk/scheduler/job/1491513
# test job: [bb48117b79ebc39485f7306d09dc602981fe540f] https://lava.sirena.org.uk/scheduler/job/1489350
# test job: [ace9b3daf2b4778358573d3698e34cb1c0fa7e14] https://lava.sirena.org.uk/scheduler/job/1489286
# test job: [2756b7f08ff6ca7c68c8c7dd61c8dc6895c9de34] https://lava.sirena.org.uk/scheduler/job/1489210
# test job: [5fc2c383125c2b4b6037e02ad8796b776b25e6d0] https://lava.sirena.org.uk/scheduler/job/1486896
# test job: [cd4da713f99651e99fbce8ed6b6ec8f686c029a8] https://lava.sirena.org.uk/scheduler/job/1538863
# test job: [7f8924e8785b68c998bc1906e049bf5595865e60] https://lava.sirena.org.uk/scheduler/job/1486908
# test job: [3e1c01d06e1f52f78fe00ef26a9cf80dbb0a3115] https://lava.sirena.org.uk/scheduler/job/1481717
# test job: [d9f38d9824bfb1b046d2e720349d2f45959ab184] https://lava.sirena.org.uk/scheduler/job/1481619
# test job: [dce4bc30f42d313b4dc5832316196411b7f07ad0] https://lava.sirena.org.uk/scheduler/job/1479449
# test job: [47972c1c3315672352f25c68f91dd88543541947] https://lava.sirena.org.uk/scheduler/job/1479571
# test job: [5eb8a0d7733d4cd32a776acf1d1aa1c7c01c8a14] https://lava.sirena.org.uk/scheduler/job/1474490
# test job: [bb8d8ba4715cb8f997d63d90ba935f6073595df5] https://lava.sirena.org.uk/scheduler/job/1472035
# test job: [8a5a5cecb79058b608e5562d8998123a3adb313c] https://lava.sirena.org.uk/scheduler/job/1471848
# test job: [a4eb71ff98c4792f441f108910bd829da7a04092] https://lava.sirena.org.uk/scheduler/job/1468995
# test job: [6cafcc53eb5fffd9b9bdfde700bb9bad21e98ed3] https://lava.sirena.org.uk/scheduler/job/1468942
# test job: [7e10d7242ea8a5947878880b912ffa5806520705] https://lava.sirena.org.uk/scheduler/job/1466042
# test job: [d6fa0ca959db8efd4462d7beef4bdc5568640fd0] https://lava.sirena.org.uk/scheduler/job/1464679
# test job: [6ba68e5aa9d5d15c8877a655db279fcfc0b38b04] https://lava.sirena.org.uk/scheduler/job/1463330
# test job: [1f5cdb6ab45e1c06ae0953609acbb52f8946b3e8] https://lava.sirena.org.uk/scheduler/job/1462967
# test job: [d49305862fdc4d9ff1b1093b4ed7d8e0cb9971b4] https://lava.sirena.org.uk/scheduler/job/1463039
# test job: [03b778d1994827ea5cc971dbdfbb457bbb7bfa5d] https://lava.sirena.org.uk/scheduler/job/1461893
# test job: [c459262159f39e6e6336797feb975799344b749b] https://lava.sirena.org.uk/scheduler/job/1461009
# test job: [267be32b0a7b70cc777f8a46f0904c92c0521d89] https://lava.sirena.org.uk/scheduler/job/1460419
# test job: [548d770c330cd1027549947a6ea899c56b5bc4e4] https://lava.sirena.org.uk/scheduler/job/1460085
# test job: [111a2c8ab462d77d1519b71b46f13ae1b46920b4] https://lava.sirena.org.uk/scheduler/job/1460877
# test job: [f6f914893d478b7ba08e5c375de1ced16deb5e92] https://lava.sirena.org.uk/scheduler/job/1461476
# test job: [9a30e332c36c52e92e5316b4a012d45284dedeb5] https://lava.sirena.org.uk/scheduler/job/1460560
# test job: [c95e925daa434ee1a40a86aec6476ce588e4bd77] https://lava.sirena.org.uk/scheduler/job/1460134
# test job: [ac209bde018fd320b79976657a44c23113181af6] https://lava.sirena.org.uk/scheduler/job/1461916
# test job: [ece5d881004f041c2e1493436409dbcbea3ad5f8] https://lava.sirena.org.uk/scheduler/job/1461683
# test job: [b9ecde0bcf6a99a3ff08496d4ba90a385ebbfd68] https://lava.sirena.org.uk/scheduler/job/1461078
# test job: [c8c4694ede7ed42d8d4db0e8927dea9839a3e248] https://lava.sirena.org.uk/scheduler/job/1461314
# test job: [e6e8897995a9e6028563ce36c27877e5478c8571] https://lava.sirena.org.uk/scheduler/job/1461772
# test job: [58ba80c4740212c29a1cf9b48f588e60a7612209] https://lava.sirena.org.uk/scheduler/job/1548198
# bad: [58ba80c4740212c29a1cf9b48f588e60a7612209] Add linux-next specific files for 20250708
git bisect bad 58ba80c4740212c29a1cf9b48f588e60a7612209
# test job: [ddadac3880bcacd8ae5ef9c8a975ab0f29365279] https://lava.sirena.org.uk/scheduler/job/1548466
# good: [ddadac3880bcacd8ae5ef9c8a975ab0f29365279] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
git bisect good ddadac3880bcacd8ae5ef9c8a975ab0f29365279
# test job: [e3b47c2bac46fc506ecef42040afa3a91776f722] https://lava.sirena.org.uk/scheduler/job/1548653
# good: [e3b47c2bac46fc506ecef42040afa3a91776f722] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply.git
git bisect good e3b47c2bac46fc506ecef42040afa3a91776f722
# test job: [eab3a69ec865243607c349518c09fe39ecc0d936] https://lava.sirena.org.uk/scheduler/job/1548704
# bad: [eab3a69ec865243607c349518c09fe39ecc0d936] Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/fpga/linux-fpga.git
git bisect bad eab3a69ec865243607c349518c09fe39ecc0d936
# test job: [022880fb3d8f45e408bb117e634edbe9fb1528b2] https://lava.sirena.org.uk/scheduler/job/1548782
# bad: [022880fb3d8f45e408bb117e634edbe9fb1528b2] Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git
git bisect bad 022880fb3d8f45e408bb117e634edbe9fb1528b2
# test job: [a00a9a8b710f09cc6d05a0189e3cd5e41ff8f467] https://lava.sirena.org.uk/scheduler/job/1548826
# bad: [a00a9a8b710f09cc6d05a0189e3cd5e41ff8f467] Merge branch into tip/master: 'x86/kconfig'
git bisect bad a00a9a8b710f09cc6d05a0189e3cd5e41ff8f467
# test job: [05f88a899228a24c1beba9291f63895746351a86] https://lava.sirena.org.uk/scheduler/job/1549063
# good: [05f88a899228a24c1beba9291f63895746351a86] Merge branch into tip/master: 'irq/drivers'
git bisect good 05f88a899228a24c1beba9291f63895746351a86
# test job: [7893ea1006fcbb876ddf53ad4ebba4a054add4b2] https://lava.sirena.org.uk/scheduler/job/1549165
# bad: [7893ea1006fcbb876ddf53ad4ebba4a054add4b2] vdso/gettimeofday: Add support for auxiliary clocks
git bisect bad 7893ea1006fcbb876ddf53ad4ebba4a054add4b2
# test job: [60ecc26ec5af567a55f362ad92c0cac8b894541c] https://lava.sirena.org.uk/scheduler/job/1549250
# good: [60ecc26ec5af567a55f362ad92c0cac8b894541c] timekeeping: Provide time setter for auxiliary clocks
git bisect good 60ecc26ec5af567a55f362ad92c0cac8b894541c
# test job: [d878e2960cb638faf3cc9f1409c6a2a3f9283ec1] https://lava.sirena.org.uk/scheduler/job/1549360
# good: [d878e2960cb638faf3cc9f1409c6a2a3f9283ec1] vdso/vsyscall: Introduce a helper to fill clock configurations
git bisect good d878e2960cb638faf3cc9f1409c6a2a3f9283ec1
# test job: [b5df72706b044b30b17f5d623fe040b83e98be36] https://lava.sirena.org.uk/scheduler/job/1549506
# bad: [b5df72706b044b30b17f5d623fe040b83e98be36] vdso/gettimeofday: Introduce vdso_clockid_valid()
git bisect bad b5df72706b044b30b17f5d623fe040b83e98be36
# test job: [9916785ef2ce464edd83fce80eaa11fab7792547] https://lava.sirena.org.uk/scheduler/job/1549963
# good: [9916785ef2ce464edd83fce80eaa11fab7792547] vdso/helpers: Add helpers for seqlocks of single vdso_clock
git bisect good 9916785ef2ce464edd83fce80eaa11fab7792547
# test job: [fcc8e46f768ff508dab0e3cfc2001e96dcb388e2] https://lava.sirena.org.uk/scheduler/job/1550140
# bad: [fcc8e46f768ff508dab0e3cfc2001e96dcb388e2] vdso/gettimeofday: Return bool from clock_gettime() helpers
git bisect bad fcc8e46f768ff508dab0e3cfc2001e96dcb388e2
# test job: [7413d7c640aa1d9620aa467922cfe3b8df51272e] https://lava.sirena.org.uk/scheduler/job/1550370
# good: [7413d7c640aa1d9620aa467922cfe3b8df51272e] vdso/gettimeofday: Return bool from clock_getres() helpers
git bisect good 7413d7c640aa1d9620aa467922cfe3b8df51272e
# first bad commit: [fcc8e46f768ff508dab0e3cfc2001e96dcb388e2] vdso/gettimeofday: Return bool from clock_gettime() helpers
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
2025-07-06 19:31 ` Thomas Gleixner
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
` (2 subsequent siblings)
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: dea57842479175fe0914e363b503ccff378ac54d
Gitweb: https://git.kernel.org/tip/dea57842479175fe0914e363b503ccff378ac54d
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:06 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:35 +02:00
vdso/gettimeofday: Add support for auxiliary clocks
Expose the auxiliary clocks through the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-12-df7d9f87b9b8@linutronix.de
---
include/vdso/datapage.h | 2 ++-
lib/vdso/gettimeofday.c | 49 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index f4c96d9..0253303 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
+#include <uapi/linux/bits.h>
#include <uapi/linux/time.h>
#include <uapi/linux/types.h>
#include <uapi/asm-generic/errno-base.h>
@@ -46,6 +47,7 @@ struct vdso_arch_data {
#define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
BIT(CLOCK_MONOTONIC_COARSE))
#define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
+#define VDSO_AUX __GENMASK(CLOCK_AUX_LAST, CLOCK_AUX)
#define CS_HRES_COARSE 0
#define CS_RAW 1
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index d9cb1d9..97aa905 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -2,6 +2,7 @@
/*
* Generic userspace implementations of gettimeofday() and similar.
*/
+#include <vdso/auxclock.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles)
static __always_inline bool vdso_clockid_valid(clockid_t clock)
{
/* Check for negative values or invalid clocks */
- return likely((u32) clock < MAX_CLOCKS);
+ return likely((u32) clock < CLOCK_AUX_LAST);
}
/*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
return true;
}
+static __always_inline
+bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_clock *vc;
+ u32 seq, idx;
+ u64 sec, ns;
+
+ if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
+ return false;
+
+ idx = clock - CLOCK_AUX;
+ vc = &vd->aux_clock_data[idx];
+
+ do {
+ /*
+ * Open coded function vdso_read_begin() to handle
+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
+ */
+ while ((seq = READ_ONCE(vc->seq)) & 1) {
+ if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
+ vd = __arch_get_vdso_u_timens_data(vd);
+ vc = &vd->aux_clock_data[idx];
+ /* Re-read from the real time data page */
+ continue;
+ }
+ cpu_relax();
+ }
+ smp_rmb();
+
+ /* Auxclock disabled? */
+ if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
+ return false;
+
+ if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
+ return false;
+ } while (unlikely(vdso_read_retry(vc, seq)));
+
+ vdso_set_timespec(ts, sec, ns);
+
+ return true;
+}
+
static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
+ else if (msk & VDSO_AUX)
+ return do_aux(vd, clock, ts);
else
return false;
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
* Preserves the behaviour of posix_get_coarse_res().
*/
ns = LOW_RES_NSEC;
+ } else if (msk & VDSO_AUX) {
+ ns = aux_clock_resolution_ns();
} else {
return false;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
2025-07-07 6:57 ` Thomas Gleixner
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
3 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: e0c8cdaf04a26206b96af0cc15947afd4cbb570c
Gitweb: https://git.kernel.org/tip/e0c8cdaf04a26206b96af0cc15947afd4cbb570c
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:05 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:35 +02:00
vdso/vsyscall: Update auxiliary clock data in the datapage
Expose the auxiliary clock data so it can be read from the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-11-df7d9f87b9b8@linutronix.de
---
include/linux/timekeeper_internal.h | 6 ++++-
include/vdso/datapage.h | 3 ++-
kernel/time/namespace.c | 5 ++++-
kernel/time/timekeeping.c | 12 ++++++++-
kernel/time/vsyscall.c | 40 ++++++++++++++++++++++++++++-
5 files changed, 66 insertions(+)
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index ca79938..c27aac6 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -190,4 +190,10 @@ static inline void update_vsyscall_tz(void)
}
#endif
+#if defined(CONFIG_GENERIC_GETTIMEOFDAY) && defined(CONFIG_POSIX_AUX_CLOCKS)
+extern void vdso_time_update_aux(struct timekeeper *tk);
+#else
+static inline void vdso_time_update_aux(struct timekeeper *tk) { }
+#endif
+
#endif /* _LINUX_TIMEKEEPER_INTERNAL_H */
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 1864e76..f4c96d9 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -38,6 +38,7 @@ struct vdso_arch_data {
#endif
#define VDSO_BASES (CLOCK_TAI + 1)
+#define VDSO_BASE_AUX 0
#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
BIT(CLOCK_MONOTONIC) | \
BIT(CLOCK_BOOTTIME) | \
@@ -117,6 +118,7 @@ struct vdso_clock {
* @arch_data: architecture specific data (optional, defaults
* to an empty struct)
* @clock_data: clocksource related data (array)
+ * @aux_clock_data: auxiliary clocksource related data (array)
* @tz_minuteswest: minutes west of Greenwich
* @tz_dsttime: type of DST correction
* @hrtimer_res: hrtimer resolution
@@ -133,6 +135,7 @@ struct vdso_time_data {
struct arch_vdso_time_data arch_data;
struct vdso_clock clock_data[CS_BASES];
+ struct vdso_clock aux_clock_data[MAX_AUX_CLOCKS];
s32 tz_minuteswest;
s32 tz_dsttime;
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index e364227..6674527 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -242,6 +242,11 @@ static void timens_set_vvar_page(struct task_struct *task,
for (i = 0; i < CS_BASES; i++)
timens_setup_vdso_clock_data(&vc[i], ns);
+ if (IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS)) {
+ for (i = 0; i < ARRAY_SIZE(vdata->aux_clock_data); i++)
+ timens_setup_vdso_clock_data(&vdata->aux_clock_data[i], ns);
+ }
+
out:
mutex_unlock(&offset_lock);
}
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cbcf090..243fe25 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -66,11 +66,21 @@ static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return ktime_get_aux_ts64(CLOCK_AUX + tkid - TIMEKEEPER_AUX_FIRST, ts);
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return tk->id >= TIMEKEEPER_AUX_FIRST && tk->id <= TIMEKEEPER_AUX_LAST;
+}
#else
static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return false;
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return false;
+}
#endif
/* flag for if timekeeping is suspended */
@@ -719,6 +729,8 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono);
update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw);
+ } else if (tk_is_aux(tk)) {
+ vdso_time_update_aux(tk);
}
if (action & TK_CLOCK_WAS_SET)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index df6bada..8ba8b0d 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -136,6 +136,46 @@ void update_vsyscall_tz(void)
__arch_sync_vdso_time_data(vdata);
}
+#ifdef CONFIG_POSIX_AUX_CLOCKS
+void vdso_time_update_aux(struct timekeeper *tk)
+{
+ struct vdso_time_data *vdata = vdso_k_time_data;
+ struct vdso_timestamp *vdso_ts;
+ struct vdso_clock *vc;
+ s32 clock_mode;
+ u64 nsec;
+
+ vc = &vdata->aux_clock_data[tk->id - TIMEKEEPER_AUX_FIRST];
+ vdso_ts = &vc->basetime[VDSO_BASE_AUX];
+ clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
+ if (!tk->clock_valid)
+ clock_mode = VDSO_CLOCKMODE_NONE;
+
+ /* copy vsyscall data */
+ vdso_write_begin_clock(vc);
+
+ vc->clock_mode = clock_mode;
+
+ if (clock_mode != VDSO_CLOCKMODE_NONE) {
+ fill_clock_configuration(vc, &tk->tkr_mono);
+
+ vdso_ts->sec = tk->xtime_sec;
+
+ nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
+ nsec += tk->offs_aux;
+ vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
+ nsec = nsec << tk->tkr_mono.shift;
+ vdso_ts->nsec = nsec;
+ }
+
+ __arch_update_vdso_clock(vc);
+
+ vdso_write_end_clock(vc);
+
+ __arch_sync_vdso_time_data(vdata);
+}
+#endif
+
/**
* vdso_update_begin - Start of a VDSO update section
*
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso: Introduce aux_clock_resolution_ns()
2025-07-01 8:58 ` [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: e654315fa273e456964ef51ad6983374613e0a0f
Gitweb: https://git.kernel.org/tip/e654315fa273e456964ef51ad6983374613e0a0f
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:04 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:35 +02:00
vdso: Introduce aux_clock_resolution_ns()
Move the constant resolution to a shared header,
so the vDSO can use it and return it without going through a syscall.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-10-df7d9f87b9b8@linutronix.de
---
include/vdso/auxclock.h | 13 +++++++++++++
kernel/time/timekeeping.c | 6 ++++--
2 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 include/vdso/auxclock.h
diff --git a/include/vdso/auxclock.h b/include/vdso/auxclock.h
new file mode 100644
index 0000000..6d6e74c
--- /dev/null
+++ b/include/vdso/auxclock.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VDSO_AUXCLOCK_H
+#define _VDSO_AUXCLOCK_H
+
+#include <uapi/linux/time.h>
+#include <uapi/linux/types.h>
+
+static __always_inline u64 aux_clock_resolution_ns(void)
+{
+ return 1;
+}
+
+#endif /* _VDSO_AUXCLOCK_H */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c6fe89b..cbcf090 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -26,6 +26,8 @@
#include <linux/audit.h>
#include <linux/random.h>
+#include <vdso/auxclock.h>
+
#include "tick-internal.h"
#include "ntp_internal.h"
#include "timekeeping_internal.h"
@@ -2876,8 +2878,8 @@ static int aux_get_res(clockid_t id, struct timespec64 *tp)
if (!clockid_aux_valid(id))
return -ENODEV;
- tp->tv_sec = 0;
- tp->tv_nsec = 1;
+ tp->tv_sec = aux_clock_resolution_ns() / NSEC_PER_SEC;
+ tp->tv_nsec = aux_clock_resolution_ns() % NSEC_PER_SEC;
return 0;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_get_timestamp()
2025-07-01 8:58 ` [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 1e851f508087a90ca0b5e7e6026a150144514df7
Gitweb: https://git.kernel.org/tip/1e851f508087a90ca0b5e7e6026a150144514df7
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:03 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:35 +02:00
vdso/gettimeofday: Introduce vdso_get_timestamp()
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-9-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 43 ++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 296709b..d9cb1d9 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -87,6 +87,26 @@ static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64
ts->tv_nsec = ns;
}
+static __always_inline
+bool vdso_get_timestamp(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ unsigned int clkidx, u64 *sec, u64 *ns)
+{
+ const struct vdso_timestamp *vdso_ts = &vc->basetime[clkidx];
+ u64 cycles;
+
+ if (unlikely(!vdso_clocksource_ok(vc)))
+ return false;
+
+ cycles = __arch_get_hw_counter(vc->clock_mode, vd);
+ if (unlikely(!vdso_cycles_ok(cycles)))
+ return false;
+
+ *ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
+ *sec = vdso_ts->sec;
+
+ return true;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -104,28 +124,20 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
const struct vdso_clock *vc = vd->clock_data;
- const struct vdso_timestamp *vdso_ts;
- u64 cycles, ns;
u32 seq;
s64 sec;
+ u64 ns;
if (clk != CLOCK_MONOTONIC_RAW)
vc = &vc[CS_HRES_COARSE];
else
vc = &vc[CS_RAW];
- vdso_ts = &vc->basetime[clk];
do {
seq = vdso_read_begin(vc);
- if (unlikely(!vdso_clocksource_ok(vc)))
- return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
/* Add the namespace offset */
@@ -155,8 +167,7 @@ static __always_inline
bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
- u64 cycles, sec, ns;
+ u64 sec, ns;
u32 seq;
/* Allows to compile the high resolution parts out */
@@ -183,14 +194,8 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
}
smp_rmb();
- if (unlikely(!vdso_clocksource_ok(vc)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
- return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
vdso_set_timespec(ts, sec, ns);
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_set_timespec()
2025-07-01 8:58 ` [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: b4a71f11b0ab758eb5a6d008318c80def007166b
Gitweb: https://git.kernel.org/tip/b4a71f11b0ab758eb5a6d008318c80def007166b
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:02 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:35 +02:00
vdso/gettimeofday: Introduce vdso_set_timespec()
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-8-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 87e7aae..296709b 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -77,6 +77,16 @@ static __always_inline bool vdso_clockid_valid(clockid_t clock)
return likely((u32) clock < MAX_CLOCKS);
}
+/*
+ * Must not be invoked within the sequence read section as a race inside
+ * that loop could result in __iter_div_u64_rem() being extremely slow.
+ */
+static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64 sec, u64 ns)
+{
+ ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
+ ts->tv_nsec = ns;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -122,12 +132,7 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
sec += offs->sec;
ns += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -188,12 +193,7 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -223,12 +223,8 @@ bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
sec += offs->sec;
nsec += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
- ts->tv_nsec = nsec;
+ vdso_set_timespec(ts, sec, nsec);
+
return true;
}
#else
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_clockid_valid()
2025-07-01 8:58 ` [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: a2a9c3129dd8495e48a54f19193adbac1efe673b
Gitweb: https://git.kernel.org/tip/a2a9c3129dd8495e48a54f19193adbac1efe673b
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:01 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:34 +02:00
vdso/gettimeofday: Introduce vdso_clockid_valid()
Move the clock ID validation check into a common helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-7-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 7e79b02..87e7aae 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -71,6 +71,12 @@ static inline bool vdso_cycles_ok(u64 cycles)
}
#endif
+static __always_inline bool vdso_clockid_valid(clockid_t clock)
+{
+ /* Check for negative values or invalid clocks */
+ return likely((u32) clock < MAX_CLOCKS);
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -268,8 +274,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
/*
@@ -405,8 +410,7 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
u32 msk;
u64 ns;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
` (2 preceding siblings ...)
2025-07-09 8:29 ` Mark Brown
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-09 12:42 ` CONFIG_DEVMEM=y breaks gettimeofday in next-20250708 Bert Karwatzki
2025-07-18 11:56 ` [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_gettime() helpers tip-bot2 for Thomas Weißschuh
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 75540b791bf1d9454dfd2c670943c42901382604
Gitweb: https://git.kernel.org/tip/75540b791bf1d9454dfd2c670943c42901382604
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:00 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:34 +02:00
vdso/gettimeofday: Return bool from clock_gettime() helpers
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-6-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 60 ++++++++++++++++++++--------------------
1 file changed, 31 insertions(+), 29 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 9b77f23..7e79b02 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -82,8 +82,8 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -103,11 +103,11 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
seq = vdso_read_begin(vc);
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -123,7 +123,7 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#else
static __always_inline
@@ -133,16 +133,16 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
}
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -EINVAL;
+ return false;
}
#endif
static __always_inline
-int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u64 cycles, sec, ns;
@@ -150,7 +150,7 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
/* Allows to compile the high resolution parts out */
if (!__arch_vdso_hres_capable())
- return -1;
+ return false;
do {
/*
@@ -173,11 +173,11 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
smp_rmb();
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -189,13 +189,13 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#ifdef CONFIG_TIME_NS
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -223,20 +223,20 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
*/
ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
ts->tv_nsec = nsec;
- return 0;
+ return true;
}
#else
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -1;
+ return false;
}
#endif
static __always_inline
-int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u32 seq;
@@ -258,10 +258,10 @@ int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_nsec = vdso_ts->nsec;
} while (unlikely(vdso_read_retry(vc, seq)));
- return 0;
+ return true;
}
-static __always_inline int
+static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
@@ -270,7 +270,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
/*
* Convert the clockid to a bitmask and use it to check which
@@ -284,7 +284,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
else
- return -1;
+ return false;
return do_hres(vd, vc, clock, ts);
}
@@ -293,9 +293,11 @@ static __maybe_unused int
__cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
- int ret = __cvdso_clock_gettime_common(vd, clock, ts);
+ bool ok;
- if (unlikely(ret))
+ ok = __cvdso_clock_gettime_common(vd, clock, ts);
+
+ if (unlikely(!ok))
return clock_gettime_fallback(clock, ts);
return 0;
}
@@ -342,7 +344,7 @@ __cvdso_gettimeofday_data(const struct vdso_time_data *vd,
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
- if (do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
+ if (!do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
return gettimeofday_fallback(tv, tz);
tv->tv_sec = ts.tv_sec;
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_getres() helpers
2025-07-01 8:57 ` [PATCH 05/14] vdso/gettimeofday: Return bool from clock_getres() helpers Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 34f888e3405acefc3a353227aa850dd0a37e709d
Gitweb: https://git.kernel.org/tip/34f888e3405acefc3a353227aa850dd0a37e709d
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:59 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:34 +02:00
vdso/gettimeofday: Return bool from clock_getres() helpers
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-5-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 93ef801..9b77f23 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -396,8 +396,8 @@ static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time
#ifdef VDSO_HAS_CLOCK_GETRES
static __maybe_unused
-int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
- struct __kernel_timespec *res)
+bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock,
+ struct __kernel_timespec *res)
{
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
@@ -405,7 +405,7 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
vc->clock_mode == VDSO_CLOCKMODE_TIMENS)
@@ -427,23 +427,25 @@ int __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t clock
*/
ns = LOW_RES_NSEC;
} else {
- return -1;
+ return false;
}
if (likely(res)) {
res->tv_sec = 0;
res->tv_nsec = ns;
}
- return 0;
+ return true;
}
static __maybe_unused
int __cvdso_clock_getres_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *res)
{
- int ret = __cvdso_clock_getres_common(vd, clock, res);
+ bool ok;
- if (unlikely(ret))
+ ok = __cvdso_clock_getres_common(vd, clock, res);
+
+ if (unlikely(!ok))
return clock_getres_fallback(clock, res);
return 0;
}
@@ -460,18 +462,18 @@ __cvdso_clock_getres_time32_data(const struct vdso_time_data *vd, clockid_t cloc
struct old_timespec32 *res)
{
struct __kernel_timespec ts;
- int ret;
+ bool ok;
- ret = __cvdso_clock_getres_common(vd, clock, &ts);
+ ok = __cvdso_clock_getres_common(vd, clock, &ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_getres32_fallback(clock, res);
if (likely(res)) {
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
}
- return ret;
+ return 0;
}
static __maybe_unused int
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/helpers: Add helpers for seqlocks of single vdso_clock
2025-07-01 8:57 ` [PATCH 04/14] vdso/helpers: Add helpers for seqlocks of single vdso_clock Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: ad64d71d7409a0602b50ee71c7f9663a3385c286
Gitweb: https://git.kernel.org/tip/ad64d71d7409a0602b50ee71c7f9663a3385c286
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:58 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:34 +02:00
vdso/helpers: Add helpers for seqlocks of single vdso_clock
Auxiliary clocks will have their vDSO data in a dedicated 'struct vdso_clock',
which needs to be synchronized independently.
Add a helper to synchronize a single vDSO clock.
[ tglx: Move the SMP memory barriers to the call sites and get rid of the
confusing first/last arguments and conditional barriers ]
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-4-df7d9f87b9b8@linutronix.de
---
include/vdso/helpers.h | 50 +++++++++++++++++++++++++++++++----------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/include/vdso/helpers.h b/include/vdso/helpers.h
index 0a98fed..1a5ee9d 100644
--- a/include/vdso/helpers.h
+++ b/include/vdso/helpers.h
@@ -28,17 +28,47 @@ static __always_inline u32 vdso_read_retry(const struct vdso_clock *vc,
return seq != start;
}
-static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
+static __always_inline void vdso_write_seq_begin(struct vdso_clock *vc)
{
- struct vdso_clock *vc = vd->clock_data;
+ /*
+ * WRITE_ONCE() is required otherwise the compiler can validly tear
+ * updates to vc->seq and it is possible that the value seen by the
+ * reader is inconsistent.
+ */
+ WRITE_ONCE(vc->seq, vc->seq + 1);
+}
+static __always_inline void vdso_write_seq_end(struct vdso_clock *vc)
+{
/*
* WRITE_ONCE() is required otherwise the compiler can validly tear
- * updates to vd[x].seq and it is possible that the value seen by the
+ * updates to vc->seq and it is possible that the value seen by the
* reader is inconsistent.
*/
- WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
+ WRITE_ONCE(vc->seq, vc->seq + 1);
+}
+
+static __always_inline void vdso_write_begin_clock(struct vdso_clock *vc)
+{
+ vdso_write_seq_begin(vc);
+ /* Ensure the sequence invalidation is visible before data is modified */
+ smp_wmb();
+}
+
+static __always_inline void vdso_write_end_clock(struct vdso_clock *vc)
+{
+ /* Ensure the data update is visible before the sequence is set valid again */
+ smp_wmb();
+ vdso_write_seq_end(vc);
+}
+
+static __always_inline void vdso_write_begin(struct vdso_time_data *vd)
+{
+ struct vdso_clock *vc = vd->clock_data;
+
+ vdso_write_seq_begin(&vc[CS_HRES_COARSE]);
+ vdso_write_seq_begin(&vc[CS_RAW]);
+ /* Ensure the sequence invalidation is visible before data is modified */
smp_wmb();
}
@@ -46,14 +76,10 @@ static __always_inline void vdso_write_end(struct vdso_time_data *vd)
{
struct vdso_clock *vc = vd->clock_data;
+ /* Ensure the data update is visible before the sequence is set valid again */
smp_wmb();
- /*
- * WRITE_ONCE() is required otherwise the compiler can validly tear
- * updates to vd[x].seq and it is possible that the value seen by the
- * reader is inconsistent.
- */
- WRITE_ONCE(vc[CS_HRES_COARSE].seq, vc[CS_HRES_COARSE].seq + 1);
- WRITE_ONCE(vc[CS_RAW].seq, vc[CS_RAW].seq + 1);
+ vdso_write_seq_end(&vc[CS_HRES_COARSE]);
+ vdso_write_seq_end(&vc[CS_RAW]);
}
#endif /* !__ASSEMBLY__ */
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock()
2025-07-01 8:57 ` [PATCH 03/14] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 76164ca0d113e6a9f3033f948c739586fc606ed1
Gitweb: https://git.kernel.org/tip/76164ca0d113e6a9f3033f948c739586fc606ed1
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:57 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:34 +02:00
vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock()
The upcoming auxiliary clocks need this hook, too.
To separate the architecture hooks from the timekeeper internals, refactor
the hook to only operate on a single vDSO clock.
While at it, use a more robust #define for the hook override.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-3-df7d9f87b9b8@linutronix.de
---
arch/arm64/include/asm/vdso/vsyscall.h | 7 +++----
include/asm-generic/vdso/vsyscall.h | 6 +++---
kernel/time/vsyscall.c | 3 ++-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index de58951..417aae5 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -13,12 +13,11 @@
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
static __always_inline
-void __arm64_update_vsyscall(struct vdso_time_data *vdata)
+void __arch_update_vdso_clock(struct vdso_clock *vc)
{
- vdata->clock_data[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
- vdata->clock_data[CS_RAW].mask = VDSO_PRECISION_MASK;
+ vc->mask = VDSO_PRECISION_MASK;
}
-#define __arch_update_vsyscall __arm64_update_vsyscall
+#define __arch_update_vdso_clock __arch_update_vdso_clock
/* The asm-generic header needs to be included after the definitions above */
#include <asm-generic/vdso/vsyscall.h>
diff --git a/include/asm-generic/vdso/vsyscall.h b/include/asm-generic/vdso/vsyscall.h
index b550afa..7fc0b56 100644
--- a/include/asm-generic/vdso/vsyscall.h
+++ b/include/asm-generic/vdso/vsyscall.h
@@ -22,11 +22,11 @@ static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(vo
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
-#ifndef __arch_update_vsyscall
-static __always_inline void __arch_update_vsyscall(struct vdso_time_data *vdata)
+#ifndef __arch_update_vdso_clock
+static __always_inline void __arch_update_vdso_clock(struct vdso_clock *vc)
{
}
-#endif /* __arch_update_vsyscall */
+#endif /* __arch_update_vdso_clock */
#ifndef __arch_sync_vdso_time_data
static __always_inline void __arch_sync_vdso_time_data(struct vdso_time_data *vdata)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index d655df2..df6bada 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -118,7 +118,8 @@ void update_vsyscall(struct timekeeper *tk)
if (clock_mode != VDSO_CLOCKMODE_NONE)
update_vdso_time_data(vdata, tk);
- __arch_update_vsyscall(vdata);
+ __arch_update_vdso_clock(&vc[CS_HRES_COARSE]);
+ __arch_update_vdso_clock(&vc[CS_RAW]);
vdso_write_end(vdata);
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Introduce a helper to fill clock configurations
2025-07-01 8:57 ` [PATCH 02/14] vdso/vsyscall: Introduce a helper to fill clock configurations Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
1 sibling, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-09 9:57 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 6fedaf682a5e1866efdaddc70ff0ada329825d53
Gitweb: https://git.kernel.org/tip/6fedaf682a5e1866efdaddc70ff0ada329825d53
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:57:56 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 09 Jul 2025 11:52:34 +02:00
vdso/vsyscall: Introduce a helper to fill clock configurations
The logic to configure a 'struct vdso_clock' from a
'struct tk_read_base' is copied two times.
Split it into a shared function to reduce the duplication,
especially as another user will be added for auxiliary clocks.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-2-df7d9f87b9b8@linutronix.de
---
kernel/time/vsyscall.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index 32ef27c..d655df2 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -15,26 +15,25 @@
#include "timekeeping_internal.h"
+static inline void fill_clock_configuration(struct vdso_clock *vc, const struct tk_read_base *base)
+{
+ vc->cycle_last = base->cycle_last;
+#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
+ vc->max_cycles = base->clock->max_cycles;
+#endif
+ vc->mask = base->mask;
+ vc->mult = base->mult;
+ vc->shift = base->shift;
+}
+
static inline void update_vdso_time_data(struct vdso_time_data *vdata, struct timekeeper *tk)
{
struct vdso_clock *vc = vdata->clock_data;
struct vdso_timestamp *vdso_ts;
u64 nsec, sec;
- vc[CS_HRES_COARSE].cycle_last = tk->tkr_mono.cycle_last;
-#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vc[CS_HRES_COARSE].max_cycles = tk->tkr_mono.clock->max_cycles;
-#endif
- vc[CS_HRES_COARSE].mask = tk->tkr_mono.mask;
- vc[CS_HRES_COARSE].mult = tk->tkr_mono.mult;
- vc[CS_HRES_COARSE].shift = tk->tkr_mono.shift;
- vc[CS_RAW].cycle_last = tk->tkr_raw.cycle_last;
-#ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
- vc[CS_RAW].max_cycles = tk->tkr_raw.clock->max_cycles;
-#endif
- vc[CS_RAW].mask = tk->tkr_raw.mask;
- vc[CS_RAW].mult = tk->tkr_raw.mult;
- vc[CS_RAW].shift = tk->tkr_raw.shift;
+ fill_clock_configuration(&vc[CS_HRES_COARSE], &tk->tkr_mono);
+ fill_clock_configuration(&vc[CS_RAW], &tk->tkr_raw);
/* CLOCK_MONOTONIC */
vdso_ts = &vc[CS_HRES_COARSE].basetime[CLOCK_MONOTONIC];
^ permalink raw reply related [flat|nested] 72+ messages in thread
* CONFIG_DEVMEM=y breaks gettimeofday in next-20250708
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
` (3 preceding siblings ...)
2025-07-09 9:57 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
@ 2025-07-09 12:42 ` Bert Karwatzki
2025-07-09 13:17 ` Thomas Weißschuh
2025-07-18 11:56 ` [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_gettime() helpers tip-bot2 for Thomas Weißschuh
5 siblings, 1 reply; 72+ messages in thread
From: Bert Karwatzki @ 2025-07-09 12:42 UTC (permalink / raw)
To: linux-kernel
Cc: Bert Karwatzki, linux-next, Thomas Weißschuh,
Thomas Gleixner
Recently I found that my RAM has an error (memtest86+ reproducibly reports
a failing address) (this error may lead to random crashes every few days).
To further investigate the issue I tried using memtester which needs access
to /dev/mem and so I recompiled linux next-20250708 with CONFIG_DEMEM=y
and found a strange and unusual side effect:
a) the time displayed by xfce is stuck at 1.1.1970 01:00 (UTC + 1)
b) most certificates in firefox-esr fail to work due to the date being 1.1.1970
(this includes www.google.de, www.duckduckgo.com, wikipedia and youtube and many more)
c) some certificates in firefox-esr still work (kernel.org, xkcd.com, www.spiegel.de)
d) the shell built-in time (and also /usr/bin/time) fail to work, e.g.
$ time sleep 5
real 0m0,000s
user 0m0,000s
sys 0m0,002s
(even though it actually take 5 seconds for this)
e) date still works correctly, e.g.
$ date
Mi 9. Jul 11:51:20 CEST 2025
f) This example program
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
int main()
{
int ret;
struct timeval tv;
struct timezone tz;
ret = gettimeofday(&tv, &tz);
printf("gettimeofday returns ret = %d, tv.tv_sec = %lu tv.tv_usec = %lu\n", ret, tv.tv_sec, tv.tv_usec);
return 0;
}
gives the following output on affected versions:
$
gettimeofday returns ret = 0, tv.tv_sec = 0 tv.tv_usec = 0
These errors do not occur when using v6.16-rc5 with CONFIG_DEVMEM=y, and are 100%
reproducible so are not related to the RAM error.
I bisected the issue in between
v6.16-rc5 and next-20250708 and found commit fcc8e46f768f ("vdso/gettimeofday:
Return bool from clock_gettime() helpers") as the first bad commit.
Bert Karwatzki
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: CONFIG_DEVMEM=y breaks gettimeofday in next-20250708
2025-07-09 12:42 ` CONFIG_DEVMEM=y breaks gettimeofday in next-20250708 Bert Karwatzki
@ 2025-07-09 13:17 ` Thomas Weißschuh
2025-07-09 16:40 ` Bert Karwatzki
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-09 13:17 UTC (permalink / raw)
To: Bert Karwatzki; +Cc: linux-kernel, linux-next, Thomas Gleixner
Hi Bert,
On Wed, Jul 09, 2025 at 02:42:15PM +0200, Bert Karwatzki wrote:
> Recently I found that my RAM has an error (memtest86+ reproducibly reports
> a failing address) (this error may lead to random crashes every few days).
> To further investigate the issue I tried using memtester which needs access
> to /dev/mem and so I recompiled linux next-20250708 with CONFIG_DEMEM=y
> and found a strange and unusual side effect:
>
> a) the time displayed by xfce is stuck at 1.1.1970 01:00 (UTC + 1)
> b) most certificates in firefox-esr fail to work due to the date being 1.1.1970
> (this includes www.google.de, www.duckduckgo.com, wikipedia and youtube and many more)
> c) some certificates in firefox-esr still work (kernel.org, xkcd.com, www.spiegel.de)
> d) the shell built-in time (and also /usr/bin/time) fail to work, e.g.
> $ time sleep 5
> real 0m0,000s
> user 0m0,000s
> sys 0m0,002s
> (even though it actually take 5 seconds for this)
> e) date still works correctly, e.g.
> $ date
> Mi 9. Jul 11:51:20 CEST 2025
> f) This example program
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <sys/time.h>
>
> int main()
> {
> int ret;
> struct timeval tv;
> struct timezone tz;
>
> ret = gettimeofday(&tv, &tz);
> printf("gettimeofday returns ret = %d, tv.tv_sec = %lu tv.tv_usec = %lu\n", ret, tv.tv_sec, tv.tv_usec);
>
> return 0;
> }
>
> gives the following output on affected versions:
>
> $
> gettimeofday returns ret = 0, tv.tv_sec = 0 tv.tv_usec = 0
Thanks for the report. Can you try the fix posted by Marek [0]?
It looks like the same issue where the vDSO fastpath is unavailable on your
hardware but I broke the check for it.
If it is the same issue it still leaves the question why the fastpath is
broken by CONFIG_DEVMEM. Can you describe your setup a bit?
Are there any entries in dmesg about the tsc or the clocksource subsystem?
> These errors do not occur when using v6.16-rc5 with CONFIG_DEVMEM=y, and are 100%
> reproducible so are not related to the RAM error.
>
> I bisected the issue in between
> v6.16-rc5 and next-20250708 and found commit fcc8e46f768f ("vdso/gettimeofday:
> Return bool from clock_gettime() helpers") as the first bad commit.
[0] https://lore.kernel.org/lkml/e8c6b9a7-eaa6-4947-98e1-9d6fecc958d4@samsung.com/
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: CONFIG_DEVMEM=y breaks gettimeofday in next-20250708
2025-07-09 13:17 ` Thomas Weißschuh
@ 2025-07-09 16:40 ` Bert Karwatzki
0 siblings, 0 replies; 72+ messages in thread
From: Bert Karwatzki @ 2025-07-09 16:40 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: linux-kernel, linux-next, Thomas Gleixner, spasswolf
Am Mittwoch, dem 09.07.2025 um 15:17 +0200 schrieb Thomas Weißschuh:
> Hi Bert,
>
> On Wed, Jul 09, 2025 at 02:42:15PM +0200, Bert Karwatzki wrote:
> > Recently I found that my RAM has an error (memtest86+ reproducibly reports
> > a failing address) (this error may lead to random crashes every few days).
> > To further investigate the issue I tried using memtester which needs access
> > to /dev/mem and so I recompiled linux next-20250708 with CONFIG_DEMEM=y
> > and found a strange and unusual side effect:
> >
> > a) the time displayed by xfce is stuck at 1.1.1970 01:00 (UTC + 1)
> > b) most certificates in firefox-esr fail to work due to the date being 1.1.1970
> > (this includes www.google.de, www.duckduckgo.com, wikipedia and youtube and many more)
> > c) some certificates in firefox-esr still work (kernel.org, xkcd.com, www.spiegel.de)
> > d) the shell built-in time (and also /usr/bin/time) fail to work, e.g.
> > $ time sleep 5
> > real 0m0,000s
> > user 0m0,000s
> > sys 0m0,002s
> > (even though it actually take 5 seconds for this)
> > e) date still works correctly, e.g.
> > $ date
> > Mi 9. Jul 11:51:20 CEST 2025
> > f) This example program
> >
> > #include <stdlib.h>
> > #include <stdio.h>
> > #include <sys/time.h>
> >
> > int main()
> > {
> > int ret;
> > struct timeval tv;
> > struct timezone tz;
> >
> > ret = gettimeofday(&tv, &tz);
> > printf("gettimeofday returns ret = %d, tv.tv_sec = %lu tv.tv_usec = %lu\n", ret, tv.tv_sec, tv.tv_usec);
> >
> > return 0;
> > }
> >
> > gives the following output on affected versions:
> >
> > $
> > gettimeofday returns ret = 0, tv.tv_sec = 0 tv.tv_usec = 0
>
> Thanks for the report. Can you try the fix posted by Marek [0]?
> It looks like the same issue where the vDSO fastpath is unavailable on your
> hardware but I broke the check for it.
Yes, this fixes the issue for me.
> If it is the same issue it still leaves the question why the fastpath is
> broken by CONFIG_DEVMEM. Can you describe your setup a bit?
> Are there any entries in dmesg about the tsc or the clocksource subsystem?
I use a MSI Alpha 15 B5EEK/MS-158L amd64 laptop (AMD Ryzen 7 5800H) running debian sid. When booting
without "tsc=unstable" I get this message in dmesg (this is from next-20250708 with CONFIG_DEVMEM=y):
[ C7] clocksource: timekeeping watchdog on CPU7: Marking clocksource 'tsc' as unstable because the skew is too large:
[ C7] clocksource: 'hpet' wd_nsec: 495997815 wd_now: 36f24f3 wd_last: 302c799 mask: ffffffff
[ C7] clocksource: 'tsc' cs_nsec: 497721239 cs_now: 1ea2752100 cs_last: 1e43b3e700 mask: ffffffffffffffff
[ C7] clocksource: Clocksource 'tsc' skewed 1723424 ns (1 ms) over watchdog 'hpet' interval of 495997815 ns (495 ms)
[ C7] clocksource: 'hpet' (not 'tsc') is current clocksource.
[ C7] tsc: Marking TSC unstable due to clocksource watchdog
[ T233] TSC found unstable after boot, most likely due to broken BIOS. Use 'tsc=unstable'.
[ T233] sched_clock: Marking unstable (4040049255, 1223348)<-(4058551237, -15591933)
I usually boot with "tsc=unstable" but the issue occurs there, too. I can't say yet why
this only occurs with CONFIG_DEVMEM=y.
Bert Karwatzki
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-09 8:04 ` Marek Szyprowski
@ 2025-07-16 12:25 ` Mark Brown
2025-07-16 12:34 ` Thomas Weißschuh
0 siblings, 1 reply; 72+ messages in thread
From: Mark Brown @ 2025-07-16 12:25 UTC (permalink / raw)
To: Marek Szyprowski
Cc: Thomas Weißschuh, Thomas Gleixner, Andy Lutomirski,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-kernel, linux-kselftest,
linux-arm-kernel, linux-arch, Richard Cochran, Christopher Hall,
Miroslav Lichvar, Werner Abt, David Woodhouse, Kurt Kanzenbach,
Nam Cao, Antoine Tenart
[-- Attachment #1: Type: text/plain, Size: 903 bytes --]
On Wed, Jul 09, 2025 at 10:04:21AM +0200, Marek Szyprowski wrote:
> On 09.07.2025 09:34, Thomas Weißschuh wrote:
> > On Tue, Jul 08, 2025 at 05:49:18PM +0200, Marek Szyprowski wrote:
> > This fix looks correct to me.
> > tglx:
> > Are you going to fold the fix into the commit or do you want a proper patch?
> > Marek:
> > If a new patch is required, do you want to send it? You found and fixed the
> > issue after all. If not, I'll take care of it.
> If it is possible to fold it into original patch then go ahead, it would
> make less noise imho. If you need a formal patch, I can send it in a few
> minutes.
This issue has been present in -next for a week and is causing a bunch
of disruption to tests that end up relying on the vDSO - do we have any
news on getting a fix merged? Perhaps it makes sense for Marek to just
send his patch so that it's there if needed?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-16 12:25 ` Mark Brown
@ 2025-07-16 12:34 ` Thomas Weißschuh
2025-07-16 12:50 ` Mark Brown
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-16 12:34 UTC (permalink / raw)
To: Mark Brown
Cc: Marek Szyprowski, Thomas Gleixner, Andy Lutomirski,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-kernel, linux-kselftest,
linux-arm-kernel, linux-arch, Richard Cochran, Christopher Hall,
Miroslav Lichvar, Werner Abt, David Woodhouse, Kurt Kanzenbach,
Nam Cao, Antoine Tenart
On Wed, Jul 16, 2025 at 01:25:06PM +0100, Mark Brown wrote:
> On Wed, Jul 09, 2025 at 10:04:21AM +0200, Marek Szyprowski wrote:
> > On 09.07.2025 09:34, Thomas Weißschuh wrote:
> > > On Tue, Jul 08, 2025 at 05:49:18PM +0200, Marek Szyprowski wrote:
>
> > > This fix looks correct to me.
>
> > > tglx:
>
> > > Are you going to fold the fix into the commit or do you want a proper patch?
>
> > > Marek:
>
> > > If a new patch is required, do you want to send it? You found and fixed the
> > > issue after all. If not, I'll take care of it.
>
> > If it is possible to fold it into original patch then go ahead, it would
> > make less noise imho. If you need a formal patch, I can send it in a few
> > minutes.
>
> This issue has been present in -next for a week and is causing a bunch
> of disruption to tests that end up relying on the vDSO - do we have any
> news on getting a fix merged? Perhaps it makes sense for Marek to just
> send his patch so that it's there if needed?
That fix has been in -next since next-20250710.
If you still have issues, I'll take a look.
Thomas
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-16 12:34 ` Thomas Weißschuh
@ 2025-07-16 12:50 ` Mark Brown
2025-07-16 13:23 ` Thomas Weißschuh
0 siblings, 1 reply; 72+ messages in thread
From: Mark Brown @ 2025-07-16 12:50 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Marek Szyprowski, Thomas Gleixner, Andy Lutomirski,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-kernel, linux-kselftest,
linux-arm-kernel, linux-arch, Richard Cochran, Christopher Hall,
Miroslav Lichvar, Werner Abt, David Woodhouse, Kurt Kanzenbach,
Nam Cao, Antoine Tenart
[-- Attachment #1: Type: text/plain, Size: 1424 bytes --]
On Wed, Jul 16, 2025 at 02:34:52PM +0200, Thomas Weißschuh wrote:
> On Wed, Jul 16, 2025 at 01:25:06PM +0100, Mark Brown wrote:
> > This issue has been present in -next for a week and is causing a bunch
> > of disruption to tests that end up relying on the vDSO - do we have any
> > news on getting a fix merged? Perhaps it makes sense for Marek to just
> > send his patch so that it's there if needed?
> That fix has been in -next since next-20250710.
> If you still have issues, I'll take a look.
Ah, sorry - I'd not seen followup mails in the thread and was still
seeing issues that appeared at the same time that had previously
bisected here. One is:
| INFO: Generating a skipfile based on /lava-4170058/1/tests/6_kselftest-dev-errlogs/automated/linux/kselftest/skipfile-lkft.yaml
| fatal error: nanotime returning zero
| goroutine 1 [running, locked to thread]:
| runtime.throw(0x132d83, 0x17)
| /usr/lib/golang/src/runtime/panic.go:774 +0x5c fp=0x42c7a4 sp=0x42c790 pc=0x3b740
| runtime.main()
| /usr/lib/golang/src/runtime/proc.go:152 +0x350 fp=0x42c7e4 sp=0x42c7a4 pc=0x3d308
|A runtime.goexit()
| /usr/lib/golang/src/runtime/asm_arm.s:868 +0x4 fp=0x42c7e4 sp=0x42c7e4 pc=0x645dc
| ERROR: skipgen failed to generate a skipfile: 2
I'll just kick of a clean bisect for that and see what it comes up with.
Full log:
https://validation.linaro.org/scheduler/job/4170058#L2215
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-16 12:50 ` Mark Brown
@ 2025-07-16 13:23 ` Thomas Weißschuh
2025-07-16 14:35 ` Mark Brown
0 siblings, 1 reply; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-16 13:23 UTC (permalink / raw)
To: Mark Brown
Cc: Marek Szyprowski, Thomas Gleixner, Andy Lutomirski,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-kernel, linux-kselftest,
linux-arm-kernel, linux-arch, Richard Cochran, Christopher Hall,
Miroslav Lichvar, Werner Abt, David Woodhouse, Kurt Kanzenbach,
Nam Cao, Antoine Tenart
On Wed, Jul 16, 2025 at 01:50:22PM +0100, Mark Brown wrote:
> On Wed, Jul 16, 2025 at 02:34:52PM +0200, Thomas Weißschuh wrote:
> > On Wed, Jul 16, 2025 at 01:25:06PM +0100, Mark Brown wrote:
>
> > > This issue has been present in -next for a week and is causing a bunch
> > > of disruption to tests that end up relying on the vDSO - do we have any
> > > news on getting a fix merged? Perhaps it makes sense for Marek to just
> > > send his patch so that it's there if needed?
>
> > That fix has been in -next since next-20250710.
> > If you still have issues, I'll take a look.
>
> Ah, sorry - I'd not seen followup mails in the thread and was still
> seeing issues that appeared at the same time that had previously
> bisected here. One is:
>
> | INFO: Generating a skipfile based on /lava-4170058/1/tests/6_kselftest-dev-errlogs/automated/linux/kselftest/skipfile-lkft.yaml
> | fatal error: nanotime returning zero
> | goroutine 1 [running, locked to thread]:
> | runtime.throw(0x132d83, 0x17)
> | /usr/lib/golang/src/runtime/panic.go:774 +0x5c fp=0x42c7a4 sp=0x42c790 pc=0x3b740
> | runtime.main()
> | /usr/lib/golang/src/runtime/proc.go:152 +0x350 fp=0x42c7e4 sp=0x42c7a4 pc=0x3d308
> |A runtime.goexit()
> | /usr/lib/golang/src/runtime/asm_arm.s:868 +0x4 fp=0x42c7e4 sp=0x42c7e4 pc=0x645dc
> | ERROR: skipgen failed to generate a skipfile: 2
>
> I'll just kick of a clean bisect for that and see what it comes up with.
Can you try the following?
I missed this despite the double-checking after the last reported issue.
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 97aa9059a5c9..5e0106130e07 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -365,14 +365,14 @@ __cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
struct old_timespec32 *res)
{
struct __kernel_timespec ts;
- int ret;
+ bool ok;
- ret = __cvdso_clock_gettime_common(vd, clock, &ts);
+ ok = __cvdso_clock_gettime_common(vd, clock, &ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_gettime32_fallback(clock, res);
- /* For ret == 0 */
+ /* For ok == true */
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
Sorry for all the breakage.
Thomas
^ permalink raw reply related [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-16 13:23 ` Thomas Weißschuh
@ 2025-07-16 14:35 ` Mark Brown
2025-07-18 12:02 ` Thomas Weißschuh
2025-07-19 11:16 ` David Laight
0 siblings, 2 replies; 72+ messages in thread
From: Mark Brown @ 2025-07-16 14:35 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Marek Szyprowski, Thomas Gleixner, Andy Lutomirski,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-kernel, linux-kselftest,
linux-arm-kernel, linux-arch, Richard Cochran, Christopher Hall,
Miroslav Lichvar, Werner Abt, David Woodhouse, Kurt Kanzenbach,
Nam Cao, Antoine Tenart
[-- Attachment #1: Type: text/plain, Size: 1211 bytes --]
On Wed, Jul 16, 2025 at 03:23:24PM +0200, Thomas Weißschuh wrote:
> Can you try the following?
> I missed this despite the double-checking after the last reported issue.
I needed to fix that up a bit, it was missing an update of the final ret
in the function and didn't apply directly to -next for some reason so I
had to manually apply but it seems to do the trick, thanks!
Tested-by: Mark Brown <broonie@kernel.org>
with this against -next:
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 97aa9059a5c97..487e3458e536e 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -365,18 +365,18 @@ __cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
struct old_timespec32 *res)
{
struct __kernel_timespec ts;
- int ret;
+ bool ok;
- ret = __cvdso_clock_gettime_common(vd, clock, &ts);
+ ok = __cvdso_clock_gettime_common(vd, clock, &ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_gettime32_fallback(clock, res);
- /* For ret == 0 */
+ /* For ok == true */
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
- return ret;
+ return 0;
}
static __maybe_unused int
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
` (2 preceding siblings ...)
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-18 12:14 ` tip-bot2 for Thomas Weißschuh
2025-08-20 8:03 ` [PATCH 12/14] " John Stultz
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 5b8c75d424fad4d7b295f50021e9fd9c1022e6a8
Gitweb: https://git.kernel.org/tip/5b8c75d424fad4d7b295f50021e9fd9c1022e6a8
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:06 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:33 +02:00
vdso/gettimeofday: Add support for auxiliary clocks
Expose the auxiliary clocks through the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-12-df7d9f87b9b8@linutronix.de
---
include/vdso/datapage.h | 2 ++-
lib/vdso/gettimeofday.c | 49 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index f4c96d9..0253303 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
+#include <uapi/linux/bits.h>
#include <uapi/linux/time.h>
#include <uapi/linux/types.h>
#include <uapi/asm-generic/errno-base.h>
@@ -46,6 +47,7 @@ struct vdso_arch_data {
#define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
BIT(CLOCK_MONOTONIC_COARSE))
#define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
+#define VDSO_AUX __GENMASK(CLOCK_AUX_LAST, CLOCK_AUX)
#define CS_HRES_COARSE 0
#define CS_RAW 1
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index fc0038e..487e345 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -2,6 +2,7 @@
/*
* Generic userspace implementations of gettimeofday() and similar.
*/
+#include <vdso/auxclock.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles)
static __always_inline bool vdso_clockid_valid(clockid_t clock)
{
/* Check for negative values or invalid clocks */
- return likely((u32) clock < MAX_CLOCKS);
+ return likely((u32) clock < CLOCK_AUX_LAST);
}
/*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
return true;
}
+static __always_inline
+bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_clock *vc;
+ u32 seq, idx;
+ u64 sec, ns;
+
+ if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
+ return false;
+
+ idx = clock - CLOCK_AUX;
+ vc = &vd->aux_clock_data[idx];
+
+ do {
+ /*
+ * Open coded function vdso_read_begin() to handle
+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
+ */
+ while ((seq = READ_ONCE(vc->seq)) & 1) {
+ if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
+ vd = __arch_get_vdso_u_timens_data(vd);
+ vc = &vd->aux_clock_data[idx];
+ /* Re-read from the real time data page */
+ continue;
+ }
+ cpu_relax();
+ }
+ smp_rmb();
+
+ /* Auxclock disabled? */
+ if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
+ return false;
+
+ if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
+ return false;
+ } while (unlikely(vdso_read_retry(vc, seq)));
+
+ vdso_set_timespec(ts, sec, ns);
+
+ return true;
+}
+
static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
+ else if (msk & VDSO_AUX)
+ return do_aux(vd, clock, ts);
else
return false;
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
* Preserves the behaviour of posix_get_coarse_res().
*/
ns = LOW_RES_NSEC;
+ } else if (msk & VDSO_AUX) {
+ ns = aux_clock_resolution_ns();
} else {
return false;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/vsyscall: Update auxiliary clock data in the datapage
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
` (2 preceding siblings ...)
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
3 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 380b84e168e57c54d0a9e053a5558fddc43f0c1a
Gitweb: https://git.kernel.org/tip/380b84e168e57c54d0a9e053a5558fddc43f0c1a
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:05 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:33 +02:00
vdso/vsyscall: Update auxiliary clock data in the datapage
Expose the auxiliary clock data so it can be read from the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-11-df7d9f87b9b8@linutronix.de
---
include/linux/timekeeper_internal.h | 6 ++++-
include/vdso/datapage.h | 3 ++-
kernel/time/namespace.c | 5 ++++-
kernel/time/timekeeping.c | 12 ++++++++-
kernel/time/vsyscall.c | 40 ++++++++++++++++++++++++++++-
5 files changed, 66 insertions(+)
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h
index ca79938..c27aac6 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -190,4 +190,10 @@ static inline void update_vsyscall_tz(void)
}
#endif
+#if defined(CONFIG_GENERIC_GETTIMEOFDAY) && defined(CONFIG_POSIX_AUX_CLOCKS)
+extern void vdso_time_update_aux(struct timekeeper *tk);
+#else
+static inline void vdso_time_update_aux(struct timekeeper *tk) { }
+#endif
+
#endif /* _LINUX_TIMEKEEPER_INTERNAL_H */
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index 1864e76..f4c96d9 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -38,6 +38,7 @@ struct vdso_arch_data {
#endif
#define VDSO_BASES (CLOCK_TAI + 1)
+#define VDSO_BASE_AUX 0
#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
BIT(CLOCK_MONOTONIC) | \
BIT(CLOCK_BOOTTIME) | \
@@ -117,6 +118,7 @@ struct vdso_clock {
* @arch_data: architecture specific data (optional, defaults
* to an empty struct)
* @clock_data: clocksource related data (array)
+ * @aux_clock_data: auxiliary clocksource related data (array)
* @tz_minuteswest: minutes west of Greenwich
* @tz_dsttime: type of DST correction
* @hrtimer_res: hrtimer resolution
@@ -133,6 +135,7 @@ struct vdso_time_data {
struct arch_vdso_time_data arch_data;
struct vdso_clock clock_data[CS_BASES];
+ struct vdso_clock aux_clock_data[MAX_AUX_CLOCKS];
s32 tz_minuteswest;
s32 tz_dsttime;
diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c
index e364227..6674527 100644
--- a/kernel/time/namespace.c
+++ b/kernel/time/namespace.c
@@ -242,6 +242,11 @@ static void timens_set_vvar_page(struct task_struct *task,
for (i = 0; i < CS_BASES; i++)
timens_setup_vdso_clock_data(&vc[i], ns);
+ if (IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS)) {
+ for (i = 0; i < ARRAY_SIZE(vdata->aux_clock_data); i++)
+ timens_setup_vdso_clock_data(&vdata->aux_clock_data[i], ns);
+ }
+
out:
mutex_unlock(&offset_lock);
}
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index cbcf090..243fe25 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -66,11 +66,21 @@ static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return ktime_get_aux_ts64(CLOCK_AUX + tkid - TIMEKEEPER_AUX_FIRST, ts);
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return tk->id >= TIMEKEEPER_AUX_FIRST && tk->id <= TIMEKEEPER_AUX_LAST;
+}
#else
static inline bool tk_get_aux_ts64(unsigned int tkid, struct timespec64 *ts)
{
return false;
}
+
+static inline bool tk_is_aux(const struct timekeeper *tk)
+{
+ return false;
+}
#endif
/* flag for if timekeeping is suspended */
@@ -719,6 +729,8 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
update_fast_timekeeper(&tk->tkr_mono, &tk_fast_mono);
update_fast_timekeeper(&tk->tkr_raw, &tk_fast_raw);
+ } else if (tk_is_aux(tk)) {
+ vdso_time_update_aux(tk);
}
if (action & TK_CLOCK_WAS_SET)
diff --git a/kernel/time/vsyscall.c b/kernel/time/vsyscall.c
index df6bada..8ba8b0d 100644
--- a/kernel/time/vsyscall.c
+++ b/kernel/time/vsyscall.c
@@ -136,6 +136,46 @@ void update_vsyscall_tz(void)
__arch_sync_vdso_time_data(vdata);
}
+#ifdef CONFIG_POSIX_AUX_CLOCKS
+void vdso_time_update_aux(struct timekeeper *tk)
+{
+ struct vdso_time_data *vdata = vdso_k_time_data;
+ struct vdso_timestamp *vdso_ts;
+ struct vdso_clock *vc;
+ s32 clock_mode;
+ u64 nsec;
+
+ vc = &vdata->aux_clock_data[tk->id - TIMEKEEPER_AUX_FIRST];
+ vdso_ts = &vc->basetime[VDSO_BASE_AUX];
+ clock_mode = tk->tkr_mono.clock->vdso_clock_mode;
+ if (!tk->clock_valid)
+ clock_mode = VDSO_CLOCKMODE_NONE;
+
+ /* copy vsyscall data */
+ vdso_write_begin_clock(vc);
+
+ vc->clock_mode = clock_mode;
+
+ if (clock_mode != VDSO_CLOCKMODE_NONE) {
+ fill_clock_configuration(vc, &tk->tkr_mono);
+
+ vdso_ts->sec = tk->xtime_sec;
+
+ nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift;
+ nsec += tk->offs_aux;
+ vdso_ts->sec += __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
+ nsec = nsec << tk->tkr_mono.shift;
+ vdso_ts->nsec = nsec;
+ }
+
+ __arch_update_vdso_clock(vc);
+
+ vdso_write_end_clock(vc);
+
+ __arch_sync_vdso_time_data(vdata);
+}
+#endif
+
/**
* vdso_update_begin - Start of a VDSO update section
*
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso: Introduce aux_clock_resolution_ns()
2025-07-01 8:58 ` [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 9b7fc3f14576c268f62fe0b882fac5e61239b659
Gitweb: https://git.kernel.org/tip/9b7fc3f14576c268f62fe0b882fac5e61239b659
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:04 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:32 +02:00
vdso: Introduce aux_clock_resolution_ns()
Move the constant resolution to a shared header,
so the vDSO can use it and return it without going through a syscall.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-10-df7d9f87b9b8@linutronix.de
---
include/vdso/auxclock.h | 13 +++++++++++++
kernel/time/timekeeping.c | 6 ++++--
2 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 include/vdso/auxclock.h
diff --git a/include/vdso/auxclock.h b/include/vdso/auxclock.h
new file mode 100644
index 0000000..6d6e74c
--- /dev/null
+++ b/include/vdso/auxclock.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _VDSO_AUXCLOCK_H
+#define _VDSO_AUXCLOCK_H
+
+#include <uapi/linux/time.h>
+#include <uapi/linux/types.h>
+
+static __always_inline u64 aux_clock_resolution_ns(void)
+{
+ return 1;
+}
+
+#endif /* _VDSO_AUXCLOCK_H */
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index c6fe89b..cbcf090 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -26,6 +26,8 @@
#include <linux/audit.h>
#include <linux/random.h>
+#include <vdso/auxclock.h>
+
#include "tick-internal.h"
#include "ntp_internal.h"
#include "timekeeping_internal.h"
@@ -2876,8 +2878,8 @@ static int aux_get_res(clockid_t id, struct timespec64 *tp)
if (!clockid_aux_valid(id))
return -ENODEV;
- tp->tv_sec = 0;
- tp->tv_nsec = 1;
+ tp->tv_sec = aux_clock_resolution_ns() / NSEC_PER_SEC;
+ tp->tv_nsec = aux_clock_resolution_ns() % NSEC_PER_SEC;
return 0;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_get_timestamp()
2025-07-01 8:58 ` [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 562f03ed967dc65e513a3e2e9821f656d5333b8e
Gitweb: https://git.kernel.org/tip/562f03ed967dc65e513a3e2e9821f656d5333b8e
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:03 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:32 +02:00
vdso/gettimeofday: Introduce vdso_get_timestamp()
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-9-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 43 ++++++++++++++++++++++------------------
1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 9d7ac98..fc0038e 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -87,6 +87,26 @@ static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64
ts->tv_nsec = ns;
}
+static __always_inline
+bool vdso_get_timestamp(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ unsigned int clkidx, u64 *sec, u64 *ns)
+{
+ const struct vdso_timestamp *vdso_ts = &vc->basetime[clkidx];
+ u64 cycles;
+
+ if (unlikely(!vdso_clocksource_ok(vc)))
+ return false;
+
+ cycles = __arch_get_hw_counter(vc->clock_mode, vd);
+ if (unlikely(!vdso_cycles_ok(cycles)))
+ return false;
+
+ *ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
+ *sec = vdso_ts->sec;
+
+ return true;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -104,28 +124,20 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
const struct vdso_clock *vc = vd->clock_data;
- const struct vdso_timestamp *vdso_ts;
- u64 cycles, ns;
u32 seq;
s64 sec;
+ u64 ns;
if (clk != CLOCK_MONOTONIC_RAW)
vc = &vc[CS_HRES_COARSE];
else
vc = &vc[CS_RAW];
- vdso_ts = &vc->basetime[clk];
do {
seq = vdso_read_begin(vc);
- if (unlikely(!vdso_clocksource_ok(vc)))
- return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
/* Add the namespace offset */
@@ -155,8 +167,7 @@ static __always_inline
bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
clockid_t clk, struct __kernel_timespec *ts)
{
- const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
- u64 cycles, sec, ns;
+ u64 sec, ns;
u32 seq;
/* Allows to compile the high resolution parts out */
@@ -183,14 +194,8 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
}
smp_rmb();
- if (unlikely(!vdso_clocksource_ok(vc)))
+ if (!vdso_get_timestamp(vd, vc, clk, &sec, &ns))
return false;
-
- cycles = __arch_get_hw_counter(vc->clock_mode, vd);
- if (unlikely(!vdso_cycles_ok(cycles)))
- return false;
- ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
- sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
vdso_set_timespec(ts, sec, ns);
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_set_timespec()
2025-07-01 8:58 ` [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 381d96ccc1a52237e03ac97b4d2945997c9356e6
Gitweb: https://git.kernel.org/tip/381d96ccc1a52237e03ac97b4d2945997c9356e6
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:02 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:32 +02:00
vdso/gettimeofday: Introduce vdso_set_timespec()
This code is duplicated and with the introduction of auxiliary clocks will
be duplicated even more.
Introduce a helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-8-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 32 ++++++++++++++------------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 0271226..9d7ac98 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -77,6 +77,16 @@ static __always_inline bool vdso_clockid_valid(clockid_t clock)
return likely((u32) clock < MAX_CLOCKS);
}
+/*
+ * Must not be invoked within the sequence read section as a race inside
+ * that loop could result in __iter_div_u64_rem() being extremely slow.
+ */
+static __always_inline void vdso_set_timespec(struct __kernel_timespec *ts, u64 sec, u64 ns)
+{
+ ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
+ ts->tv_nsec = ns;
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -122,12 +132,7 @@ bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *
sec += offs->sec;
ns += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -188,12 +193,7 @@ bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
- ts->tv_nsec = ns;
+ vdso_set_timespec(ts, sec, ns);
return true;
}
@@ -223,12 +223,8 @@ bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
sec += offs->sec;
nsec += offs->nsec;
- /*
- * Do this outside the loop: a race inside the loop could result
- * in __iter_div_u64_rem() being extremely slow.
- */
- ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
- ts->tv_nsec = nsec;
+ vdso_set_timespec(ts, sec, nsec);
+
return true;
}
#else
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Introduce vdso_clockid_valid()
2025-07-01 8:58 ` [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: 1a1cd5fe881fdf7b0391e5426f6bfcb663c90dde
Gitweb: https://git.kernel.org/tip/1a1cd5fe881fdf7b0391e5426f6bfcb663c90dde
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:01 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:32 +02:00
vdso/gettimeofday: Introduce vdso_clockid_valid()
Move the clock ID validation check into a common helper.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-7-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 32e568d..0271226 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -71,6 +71,12 @@ static inline bool vdso_cycles_ok(u64 cycles)
}
#endif
+static __always_inline bool vdso_clockid_valid(clockid_t clock)
+{
+ /* Check for negative values or invalid clocks */
+ return likely((u32) clock < MAX_CLOCKS);
+}
+
#ifdef CONFIG_TIME_NS
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
@@ -268,8 +274,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
const struct vdso_clock *vc = vd->clock_data;
u32 msk;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
/*
@@ -405,8 +410,7 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
u32 msk;
u64 ns;
- /* Check for negative values or invalid clocks */
- if (unlikely((u32) clock >= MAX_CLOCKS))
+ if (!vdso_clockid_valid(clock))
return false;
if (IS_ENABLED(CONFIG_TIME_NS) &&
^ permalink raw reply related [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
` (4 preceding siblings ...)
2025-07-09 12:42 ` CONFIG_DEVMEM=y breaks gettimeofday in next-20250708 Bert Karwatzki
@ 2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 11:56 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: fb61bdb27fd730c393a8bddbda2401c37a919667
Gitweb: https://git.kernel.org/tip/fb61bdb27fd730c393a8bddbda2401c37a919667
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:00 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 13:45:32 +02:00
vdso/gettimeofday: Return bool from clock_gettime() helpers
The internal helpers are effectively using boolean results,
while pretending to use error numbers.
Switch the return type to bool for more clarity.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-6-df7d9f87b9b8@linutronix.de
---
lib/vdso/gettimeofday.c | 70 ++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 34 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 9b77f23..32e568d 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -82,8 +82,8 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
#endif /* CONFIG_GENERIC_VDSO_DATA_STORE */
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -103,11 +103,11 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
seq = vdso_read_begin(vc);
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -123,7 +123,7 @@ int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *v
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#else
static __always_inline
@@ -133,16 +133,16 @@ const struct vdso_time_data *__arch_get_vdso_u_timens_data(const struct vdso_tim
}
static __always_inline
-int do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -EINVAL;
+ return false;
}
#endif
static __always_inline
-int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u64 cycles, sec, ns;
@@ -150,7 +150,7 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
/* Allows to compile the high resolution parts out */
if (!__arch_vdso_hres_capable())
- return -1;
+ return false;
do {
/*
@@ -173,11 +173,11 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
smp_rmb();
if (unlikely(!vdso_clocksource_ok(vc)))
- return -1;
+ return false;
cycles = __arch_get_hw_counter(vc->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
- return -1;
+ return false;
ns = vdso_calc_ns(vc, cycles, vdso_ts->nsec);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vc, seq)));
@@ -189,13 +189,13 @@ int do_hres(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_sec = sec + __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns);
ts->tv_nsec = ns;
- return 0;
+ return true;
}
#ifdef CONFIG_TIME_NS
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_time_data *vd = __arch_get_vdso_u_timens_data(vdns);
const struct timens_offset *offs = &vcns->offset[clk];
@@ -223,20 +223,20 @@ int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock
*/
ts->tv_sec = sec + __iter_div_u64_rem(nsec, NSEC_PER_SEC, &nsec);
ts->tv_nsec = nsec;
- return 0;
+ return true;
}
#else
static __always_inline
-int do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse_timens(const struct vdso_time_data *vdns, const struct vdso_clock *vcns,
+ clockid_t clk, struct __kernel_timespec *ts)
{
- return -1;
+ return false;
}
#endif
static __always_inline
-int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
- clockid_t clk, struct __kernel_timespec *ts)
+bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
+ clockid_t clk, struct __kernel_timespec *ts)
{
const struct vdso_timestamp *vdso_ts = &vc->basetime[clk];
u32 seq;
@@ -258,10 +258,10 @@ int do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
ts->tv_nsec = vdso_ts->nsec;
} while (unlikely(vdso_read_retry(vc, seq)));
- return 0;
+ return true;
}
-static __always_inline int
+static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
@@ -270,7 +270,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
/* Check for negative values or invalid clocks */
if (unlikely((u32) clock >= MAX_CLOCKS))
- return -1;
+ return false;
/*
* Convert the clockid to a bitmask and use it to check which
@@ -284,7 +284,7 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
else
- return -1;
+ return false;
return do_hres(vd, vc, clock, ts);
}
@@ -293,9 +293,11 @@ static __maybe_unused int
__cvdso_clock_gettime_data(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
{
- int ret = __cvdso_clock_gettime_common(vd, clock, ts);
+ bool ok;
+
+ ok = __cvdso_clock_gettime_common(vd, clock, ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_gettime_fallback(clock, ts);
return 0;
}
@@ -312,18 +314,18 @@ __cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
struct old_timespec32 *res)
{
struct __kernel_timespec ts;
- int ret;
+ bool ok;
- ret = __cvdso_clock_gettime_common(vd, clock, &ts);
+ ok = __cvdso_clock_gettime_common(vd, clock, &ts);
- if (unlikely(ret))
+ if (unlikely(!ok))
return clock_gettime32_fallback(clock, res);
- /* For ret == 0 */
+ /* For ok == true */
res->tv_sec = ts.tv_sec;
res->tv_nsec = ts.tv_nsec;
- return ret;
+ return 0;
}
static __maybe_unused int
@@ -342,7 +344,7 @@ __cvdso_gettimeofday_data(const struct vdso_time_data *vd,
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
- if (do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
+ if (!do_hres(vd, &vc[CS_HRES_COARSE], CLOCK_REALTIME, &ts))
return gettimeofday_fallback(tv, tz);
tv->tv_sec = ts.tv_sec;
^ permalink raw reply related [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-16 14:35 ` Mark Brown
@ 2025-07-18 12:02 ` Thomas Weißschuh
2025-07-19 11:16 ` David Laight
1 sibling, 0 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-07-18 12:02 UTC (permalink / raw)
To: Mark Brown
Cc: Marek Szyprowski, Thomas Gleixner, Andy Lutomirski,
Vincenzo Frascino, Shuah Khan, Anna-Maria Behnsen,
Frederic Weisbecker, John Stultz, Stephen Boyd, Catalin Marinas,
Will Deacon, Arnd Bergmann, linux-kernel, linux-kselftest,
linux-arm-kernel, linux-arch, Richard Cochran, Christopher Hall,
Miroslav Lichvar, Werner Abt, David Woodhouse, Kurt Kanzenbach,
Nam Cao, Antoine Tenart
Hi Mark,
On Wed, Jul 16, 2025 at 03:35:09PM +0100, Mark Brown wrote:
> On Wed, Jul 16, 2025 at 03:23:24PM +0200, Thomas Weißschuh wrote:
>
> > Can you try the following?
> > I missed this despite the double-checking after the last reported issue.
>
> I needed to fix that up a bit, it was missing an update of the final ret
> in the function and didn't apply directly to -next for some reason so I
> had to manually apply but it seems to do the trick, thanks!
>
> Tested-by: Mark Brown <broonie@kernel.org>
The fix for this is now in tip/timers/ptp and should be in -next tomorrow.
Thanks again for the report and sorry for the breakage.
(...)
Thomas
^ permalink raw reply [flat|nested] 72+ messages in thread
* [tip: timers/ptp] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
` (3 preceding siblings ...)
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
@ 2025-07-18 12:14 ` tip-bot2 for Thomas Weißschuh
2025-08-20 8:03 ` [PATCH 12/14] " John Stultz
5 siblings, 0 replies; 72+ messages in thread
From: tip-bot2 for Thomas Weißschuh @ 2025-07-18 12:14 UTC (permalink / raw)
To: linux-tip-commits; +Cc: thomas.weissschuh, Thomas Gleixner, x86, linux-kernel
The following commit has been merged into the timers/ptp branch of tip:
Commit-ID: cd3557a7618bf5c1935e9f66b58a329f1f1f4b27
Gitweb: https://git.kernel.org/tip/cd3557a7618bf5c1935e9f66b58a329f1f1f4b27
Author: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
AuthorDate: Tue, 01 Jul 2025 10:58:06 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Fri, 18 Jul 2025 14:09:39 +02:00
vdso/gettimeofday: Add support for auxiliary clocks
Expose the auxiliary clocks through the vDSO.
Architectures not using the generic vDSO time framework,
namely SPARC64, are not supported.
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-12-df7d9f87b9b8@linutronix.de
---
include/vdso/datapage.h | 2 ++-
lib/vdso/gettimeofday.c | 49 +++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index f4c96d9..0253303 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -5,6 +5,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
+#include <uapi/linux/bits.h>
#include <uapi/linux/time.h>
#include <uapi/linux/types.h>
#include <uapi/asm-generic/errno-base.h>
@@ -46,6 +47,7 @@ struct vdso_arch_data {
#define VDSO_COARSE (BIT(CLOCK_REALTIME_COARSE) | \
BIT(CLOCK_MONOTONIC_COARSE))
#define VDSO_RAW (BIT(CLOCK_MONOTONIC_RAW))
+#define VDSO_AUX __GENMASK(CLOCK_AUX_LAST, CLOCK_AUX)
#define CS_HRES_COARSE 0
#define CS_RAW 1
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index fc0038e..02ea19f 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -2,6 +2,7 @@
/*
* Generic userspace implementations of gettimeofday() and similar.
*/
+#include <vdso/auxclock.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -74,7 +75,7 @@ static inline bool vdso_cycles_ok(u64 cycles)
static __always_inline bool vdso_clockid_valid(clockid_t clock)
{
/* Check for negative values or invalid clocks */
- return likely((u32) clock < MAX_CLOCKS);
+ return likely((u32) clock <= CLOCK_AUX_LAST);
}
/*
@@ -268,6 +269,48 @@ bool do_coarse(const struct vdso_time_data *vd, const struct vdso_clock *vc,
return true;
}
+static __always_inline
+bool do_aux(const struct vdso_time_data *vd, clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_clock *vc;
+ u32 seq, idx;
+ u64 sec, ns;
+
+ if (!IS_ENABLED(CONFIG_POSIX_AUX_CLOCKS))
+ return false;
+
+ idx = clock - CLOCK_AUX;
+ vc = &vd->aux_clock_data[idx];
+
+ do {
+ /*
+ * Open coded function vdso_read_begin() to handle
+ * VDSO_CLOCK_TIMENS. See comment in do_hres().
+ */
+ while ((seq = READ_ONCE(vc->seq)) & 1) {
+ if (IS_ENABLED(CONFIG_TIME_NS) && vc->clock_mode == VDSO_CLOCKMODE_TIMENS) {
+ vd = __arch_get_vdso_u_timens_data(vd);
+ vc = &vd->aux_clock_data[idx];
+ /* Re-read from the real time data page */
+ continue;
+ }
+ cpu_relax();
+ }
+ smp_rmb();
+
+ /* Auxclock disabled? */
+ if (vc->clock_mode == VDSO_CLOCKMODE_NONE)
+ return false;
+
+ if (!vdso_get_timestamp(vd, vc, VDSO_BASE_AUX, &sec, &ns))
+ return false;
+ } while (unlikely(vdso_read_retry(vc, seq)));
+
+ vdso_set_timespec(ts, sec, ns);
+
+ return true;
+}
+
static __always_inline bool
__cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
struct __kernel_timespec *ts)
@@ -289,6 +332,8 @@ __cvdso_clock_gettime_common(const struct vdso_time_data *vd, clockid_t clock,
return do_coarse(vd, &vc[CS_HRES_COARSE], clock, ts);
else if (msk & VDSO_RAW)
vc = &vc[CS_RAW];
+ else if (msk & VDSO_AUX)
+ return do_aux(vd, clock, ts);
else
return false;
@@ -433,6 +478,8 @@ bool __cvdso_clock_getres_common(const struct vdso_time_data *vd, clockid_t cloc
* Preserves the behaviour of posix_get_coarse_res().
*/
ns = LOW_RES_NSEC;
+ } else if (msk & VDSO_AUX) {
+ ns = aux_clock_resolution_ns();
} else {
return false;
}
^ permalink raw reply related [flat|nested] 72+ messages in thread
* Re: [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers
2025-07-16 14:35 ` Mark Brown
2025-07-18 12:02 ` Thomas Weißschuh
@ 2025-07-19 11:16 ` David Laight
1 sibling, 0 replies; 72+ messages in thread
From: David Laight @ 2025-07-19 11:16 UTC (permalink / raw)
To: Mark Brown
Cc: Thomas Weißschuh, Marek Szyprowski, Thomas Gleixner,
Andy Lutomirski, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, John Stultz,
Stephen Boyd, Catalin Marinas, Will Deacon, Arnd Bergmann,
linux-kernel, linux-kselftest, linux-arm-kernel, linux-arch,
Richard Cochran, Christopher Hall, Miroslav Lichvar, Werner Abt,
David Woodhouse, Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Wed, 16 Jul 2025 15:35:09 +0100
Mark Brown <broonie@kernel.org> wrote:
> On Wed, Jul 16, 2025 at 03:23:24PM +0200, Thomas Weißschuh wrote:
>
> > Can you try the following?
> > I missed this despite the double-checking after the last reported issue.
>
> I needed to fix that up a bit, it was missing an update of the final ret
> in the function and didn't apply directly to -next for some reason so I
> had to manually apply but it seems to do the trick, thanks!
>
> Tested-by: Mark Brown <broonie@kernel.org>
>
> with this against -next:
>
> diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
> index 97aa9059a5c97..487e3458e536e 100644
> --- a/lib/vdso/gettimeofday.c
> +++ b/lib/vdso/gettimeofday.c
> @@ -365,18 +365,18 @@ __cvdso_clock_gettime32_data(const struct vdso_time_data *vd, clockid_t clock,
> struct old_timespec32 *res)
> {
> struct __kernel_timespec ts;
> - int ret;
> + bool ok;
>
> - ret = __cvdso_clock_gettime_common(vd, clock, &ts);
> + ok = __cvdso_clock_gettime_common(vd, clock, &ts);
>
> - if (unlikely(ret))
> + if (unlikely(!ok))
Do you even need 'ok' at all, just:
if (unlikely(!__cvdso_clock_gettime_common(vd, clock, &ts)))
> return clock_gettime32_fallback(clock, res);
>
> - /* For ret == 0 */
> + /* For ok == true */
> res->tv_sec = ts.tv_sec;
> res->tv_nsec = ts.tv_nsec;
>
> - return ret;
> + return 0;
> }
>
> static __maybe_unused int
David
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
` (4 preceding siblings ...)
2025-07-18 12:14 ` tip-bot2 for Thomas Weißschuh
@ 2025-08-20 8:03 ` John Stultz
2025-08-20 10:15 ` Thomas Weißschuh
5 siblings, 1 reply; 72+ messages in thread
From: John Stultz @ 2025-08-20 8:03 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, Stephen Boyd,
Catalin Marinas, Will Deacon, Arnd Bergmann, linux-kernel,
linux-kselftest, linux-arm-kernel, linux-arch, Richard Cochran,
Christopher Hall, Miroslav Lichvar, Werner Abt, David Woodhouse,
Kurt Kanzenbach, Nam Cao, Antoine Tenart
On Tue, Jul 1, 2025 at 1:58 AM Thomas Weißschuh
<thomas.weissschuh@linutronix.de> wrote:
>
> Expose the auxiliary clocks through the vDSO.
>
> Architectures not using the generic vDSO time framework,
> namely SPARC64, are not supported.
>
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Just as a heads up, I've just been bisecting and this commit seems to
be causing problems on arm64 devices, running 32bit versions of
kselftest nanosleep or inconsistency-check tests. Running the 64bit
versions of the tests are not showing issues.
From my initial digging, it looks like clockids that aren't vdso
enabled (CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID,
CLOCK_REALTIME_ALARM, CLOCK_BOOTTIME_ALARM) are somehow getting caught
in the vdso logic and are *not* falling back to the syscall (stracing
the test I don't see syscalls happen before the failure), and the
values returned don't look to be correct.
The inconsistency-check output looks like:
# 5983032:0
# 5983317:0
# 5983561:0
# 5983846:0
# 5984130:0
# 5984415:0
# --------------------
# 5984659:0
# 2009440:0
# --------------------
# 2009724:0
# 2009969:0
# 2010253:0
# 2010538:0
# 2010782:0
# 2011067:0
Which hints we're returning nanosecond values in the tv_sec field somehow.
Reverting just this change gets things back to working.
It's pretty late here, so I'm going to try to dig a bit further to
understand what's going on tomorrow, but wanted to raise this in case
it's more obvious to less tired eyes. :)
thanks
-john
^ permalink raw reply [flat|nested] 72+ messages in thread
* Re: [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks
2025-08-20 8:03 ` [PATCH 12/14] " John Stultz
@ 2025-08-20 10:15 ` Thomas Weißschuh
0 siblings, 0 replies; 72+ messages in thread
From: Thomas Weißschuh @ 2025-08-20 10:15 UTC (permalink / raw)
To: John Stultz
Cc: Andy Lutomirski, Thomas Gleixner, Vincenzo Frascino, Shuah Khan,
Anna-Maria Behnsen, Frederic Weisbecker, Stephen Boyd,
Catalin Marinas, Will Deacon, Arnd Bergmann, linux-kernel,
linux-kselftest, linux-arm-kernel, linux-arch, Richard Cochran,
Christopher Hall, Miroslav Lichvar, Werner Abt, David Woodhouse,
Kurt Kanzenbach, Nam Cao, Antoine Tenart
Hi John,
On Wed, Aug 20, 2025 at 01:03:56AM -0700, John Stultz wrote:
> On Tue, Jul 1, 2025 at 1:58 AM Thomas Weißschuh
> <thomas.weissschuh@linutronix.de> wrote:
> >
> > Expose the auxiliary clocks through the vDSO.
> >
> > Architectures not using the generic vDSO time framework,
> > namely SPARC64, are not supported.
> >
> > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
>
> Just as a heads up, I've just been bisecting and this commit seems to
> be causing problems on arm64 devices, running 32bit versions of
> kselftest nanosleep or inconsistency-check tests. Running the 64bit
> versions of the tests are not showing issues.
Thanks for the report, I can reproduce the issue.
> From my initial digging, it looks like clockids that aren't vdso
> enabled (CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID,
> CLOCK_REALTIME_ALARM, CLOCK_BOOTTIME_ALARM) are somehow getting caught
> in the vdso logic and are *not* falling back to the syscall (stracing
> the test I don't see syscalls happen before the failure), and the
> values returned don't look to be correct.
The generic vDSO code assumes that it can use the UAPI headers, also in the
compat vDSO. This is true for most architectures, as the UAPI headers work
correctly in 32-bit and 64-bit mode. On arm64 this is different, as the headers
from arm64/ are never used by regular 32-bit userpspace. So
arch/arm64/include/uapi/asm/bitsperlong.h defines __BITS_PER_LONG=64 even when
used by the 32-bit compat vDSO. The commit you identified uses __GENMASK()
which uses __BITS_PER_LONG. Due to the mismatch between __BITS_PER_LONG and the
real long datatype we run into an out-of-bounds shift and therefore undefined
behaviour. And of course -Wshift-count-overflow is explicitly disabled.
There are a few possible fixes, none of which is really great.
I'll send some patches.
> The inconsistency-check output looks like:
(...)
> Which hints we're returning nanosecond values in the tv_sec field somehow.
That seems to be an artifact of the UB from above, this happens even if
do_aux() just returns 'false'.
Thomas
^ permalink raw reply [flat|nested] 72+ messages in thread
end of thread, other threads:[~2025-08-20 10:15 UTC | newest]
Thread overview: 72+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-01 8:57 [PATCH 00/14] vdso: Add support for auxiliary clocks Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 01/14] selftests/timers: Add testcase " Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 02/14] vdso/vsyscall: Introduce a helper to fill clock configurations Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 03/14] vdso/vsyscall: Split up __arch_update_vsyscall() into __arch_update_vdso_clock() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 04/14] vdso/helpers: Add helpers for seqlocks of single vdso_clock Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:57 ` [PATCH 05/14] vdso/gettimeofday: Return bool from clock_getres() helpers Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 06/14] vdso/gettimeofday: Return bool from clock_gettime() helpers Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
[not found] ` <CGME20250708151720eucas1p260f984fd95d3460d3e9f6c9b48e0e25c@eucas1p2.samsung.com>
2025-07-08 15:17 ` [PATCH 06/14] " Marek Szyprowski
[not found] ` <CGME20250708154921eucas1p1fd8fa4374610a991ca5c67bd612ca0c2@eucas1p1.samsung.com>
2025-07-08 15:49 ` Marek Szyprowski
2025-07-09 7:34 ` Thomas Weißschuh
2025-07-09 8:04 ` Marek Szyprowski
2025-07-16 12:25 ` Mark Brown
2025-07-16 12:34 ` Thomas Weißschuh
2025-07-16 12:50 ` Mark Brown
2025-07-16 13:23 ` Thomas Weißschuh
2025-07-16 14:35 ` Mark Brown
2025-07-18 12:02 ` Thomas Weißschuh
2025-07-19 11:16 ` David Laight
2025-07-09 8:29 ` Mark Brown
2025-07-09 9:57 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 12:42 ` CONFIG_DEVMEM=y breaks gettimeofday in next-20250708 Bert Karwatzki
2025-07-09 13:17 ` Thomas Weißschuh
2025-07-09 16:40 ` Bert Karwatzki
2025-07-18 11:56 ` [tip: timers/ptp] vdso/gettimeofday: Return bool from clock_gettime() helpers tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 07/14] vdso/gettimeofday: Introduce vdso_clockid_valid() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 08/14] vdso/gettimeofday: Introduce vdso_set_timespec() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 09/14] vdso/gettimeofday: Introduce vdso_get_timestamp() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 10/14] vdso: Introduce aux_clock_resolution_ns() Thomas Weißschuh
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 11/14] vdso/vsyscall: Update auxiliary clock data in the datapage Thomas Weißschuh
2025-07-07 6:57 ` Thomas Gleixner
2025-07-07 11:34 ` Arnd Bergmann
2025-07-07 13:16 ` Thomas Gleixner
2025-07-07 14:48 ` Arnd Bergmann
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 12/14] vdso/gettimeofday: Add support for auxiliary clocks Thomas Weißschuh
2025-07-06 19:31 ` Thomas Gleixner
2025-07-07 7:11 ` [tip: timers/ptp] " tip-bot2 for Thomas Weißschuh
2025-07-09 9:57 ` tip-bot2 for Thomas Weißschuh
2025-07-18 11:56 ` tip-bot2 for Thomas Weißschuh
2025-07-18 12:14 ` tip-bot2 for Thomas Weißschuh
2025-08-20 8:03 ` [PATCH 12/14] " John Stultz
2025-08-20 10:15 ` Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 13/14] Revert "selftests: vDSO: parse_vdso: Use UAPI headers instead of libc headers" Thomas Weißschuh
2025-07-06 20:43 ` Thomas Gleixner
2025-07-07 6:21 ` Thomas Weißschuh
2025-07-01 8:58 ` [PATCH 14/14] selftests/timers/auxclock: Test vDSO functionality Thomas Weißschuh
2025-07-06 20:26 ` Thomas Gleixner
2025-07-07 7:17 ` Thomas Weißschuh
2025-07-07 13:18 ` Thomas Gleixner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).