[PATCH v2 0/3] vdso: Keep the CLOCK_AUX base at full precision
From: Zhan Xusheng
Date: Mon Aug 31 2026 - 13:47:55 EST
v1: https://lore.kernel.org/all/20260831125557.1490398-1-zhanxusheng@xxxxxxxxxx
Changes in v2, all from Thomas' review of 1/3:
- Drop the nsec_per_sec local and spell the divisor out at each site.
- Store the remainder straight into the basetime, as the coarse clocks
already do. It works at every site including CLOCK_MONOTONIC, whose
remainder feeds CLOCK_BOOTTIME, because the copy can read it back from
the CLOCK_MONOTONIC basetime. That also makes the copy take sec and
nsec from the same place instead of one from the basetime and one from
a local left over from the division. It is not a codegen win: gcc 13
emits the same 419 instructions either way, with two movs scheduled a
slot later.
- Keep "vdso_ts->sec = sec;" on its own line under the copy comment.
- Keep the asm() barrier rather than OPTIMIZER_HIDE_VAR(), matching
__iter_div_u64_rem().
- 2/3 drops the same local and stores into the basetime too.
- Picked up the Reviewed-by on 3/3, which is unchanged.
The problem 2/3 fixes: the CLOCK_AUX basetime is shifted down to
nanoseconds and back up, which drops the fractional nanoseconds of
xtime_nsec, so the vDSO floors the base and the cycle delta separately
where ktime_get_aux() floors their sum. The vDSO reading ends up 0 or
1 ns below the syscall for the same clock, and clock_getres() advertises
1 ns for these clocks. Thomas confirmed this was unintentional.
Checked under QEMU with an auxiliary clock enabled through
/sys/kernel/time/aux_clocks/0/aux_clock_enable, comparing CLOCK_AUX via
the vDSO against the raw syscall at offset 0, at +5.123456789 s, and with
offs_aux driven negative. The two agree within read latency in all three,
and over 100000 interleaved pairs each the vDSO reading is never ahead of
a syscall reading taken after it.
The 1 ns bias itself is not measurable that way: a pair of reads costs
several hundred nanoseconds, so it cannot be separated from read latency.
The argument for it is the algebra in 2/3, plus a sweep over
(xtime_nsec, delta) which puts the 1 ns case at 60% for shift 24.
Zhan Xusheng (3):
vdso/math64: Add and use __iter_div64_u64_rem()
vdso/vsyscall: Keep the CLOCK_AUX base scaled
vdso/gettimeofday: Assert that the clock id fits the dispatch mask
include/vdso/math64.h | 21 +++++++++++++++++++++
kernel/time/vsyscall.c | 28 ++++++++++++----------------
lib/vdso/gettimeofday.c | 2 ++
3 files changed, 35 insertions(+), 16 deletions(-)
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
--
2.43.0