diff options
| author | Zhan Xusheng <zhanxusheng1024@gmail.com> | 2026-10-02 23:31:00 +0800 |
|---|---|---|
| committer | Thomas Gleixner <tglx@kernel.org> | 2026-10-15 17:33:20 +0200 |
| commit | dcd65074e2c593a06bed36178bba6d49d6b6883c (patch) | |
| tree | d7dfb52f4cd5270c70ff62535f7357778e4ce7c0 /include | |
| parent | c1b910b270fee8930865410455f71e273f4c602c (diff) | |
| download | linux-dcd65074e2c593a06bed36178bba6d49d6b6883c.tar.gz linux-dcd65074e2c593a06bed36178bba6d49d6b6883c.zip | |
vdso/math64: Add and use __iter_div64_u64_rem()
The vDSO basetimes for CLOCK_MONOTONIC and CLOCK_BOOTTIME are stored in
the scaled nanoseconds of tkr_mono, so normalising them requires a
division by NSEC_PER_SEC << shift. That divisor does not fit the u32
parameter of __iter_div_u64_rem(), so update_vdso_time_data() open-codes
the same iterative division twice.
Repeated subtraction is the appropriate form at these two sites because
the quotient never exceeds one. accumulate_nsecs_to_secs() keeps
xtime_nsec below one scaled second, and the offset added to it is a
normalised timespec64 fraction, so the dividend stays below twice the
divisor. That bound holds on every architecture, which matters more here
than the cost of a division on any particular one.
Add __iter_div64_u64_rem(), the u64-divisor counterpart of
__iter_div_u64_rem(), and use it at both sites. Return the quotient as a
u32 for consistency with the u32-divisor variant; the bound above leaves
no use for a wider type.
Store the remainder directly into the basetime, as the coarse clocks
already do. The CLOCK_BOOTTIME copy of the CLOCK_MONOTONIC values then
takes both fields from the same place.
Folding the two open-coded loops into one inlined helper removes 16 bytes
of vsyscall.o text on x86-64 with gcc 13.
No functional change.
Suggested-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://patch.msgid.link/20261002153104.1347978-3-zhanxusheng@xiaomi.com
Diffstat (limited to 'include')
| -rw-r--r-- | include/vdso/math64.h | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/include/vdso/math64.h b/include/vdso/math64.h index 3c08909e742b..6f1e311cfdbd 100644 --- a/include/vdso/math64.h +++ b/include/vdso/math64.h @@ -24,6 +24,26 @@ static __always_inline u32 __iter_div_u64_rem(u64 dividend, u32 divisor, u64 *re return ret; } +static __always_inline u32 __iter_div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder) +{ + u32 ret = 0; + + while (dividend >= divisor) { + /* + * Prevent the compiler from optimising this loop into a + * modulo operation. + */ + OPTIMIZER_HIDE_VAR(dividend); + + dividend -= divisor; + ret++; + } + + *remainder = dividend; + + return ret; +} + #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__) #ifndef mul_u64_u32_add_u64_shr |
