Re: [PATCH v3 1/3] vdso/math64: Add and use __iter_div64_u64_rem()
From: Thomas Weißschuh
Date: Tue Sep 01 2026 - 09:05:19 EST
On Tue, Sep 01, 2026 at 01:48:20PM +0100, David Laight wrote:
> On Tue, 1 Sep 2026 10:35:30 +0200
> Thomas Weißschuh <thomas.weissschuh@xxxxxxxxxxxxx> wrote:
> > thanks for the new version. However please slow down a bit with sending new
> > revisions to give people time to respond.
> >
> > On Tue, Sep 01, 2026 at 10:06:34AM +0800, Zhan Xusheng wrote:
> > > The vDSO basetimes for CLOCK_MONOTONIC and CLOCK_BOOTTIME are kept in the
> > > scaled nanoseconds of tkr_mono, so normalising them means dividing by
> > > NSEC_PER_SEC << shift, which does not fit the u32 divisor of
> > > __iter_div_u64_rem().
> > >
> > > update_vdso_time_data() therefore open-codes the iterative division twice.
> > > Turning the loops into a plain modulo is not an option either, as the vDSO
> > > has no 64-bit division helpers on 32-bit.
> >
> > This is not vDSO userspace code, but on the kernel side.
> > The problem is that divisions are unnecessarily slow.
>
> Until you get to (on x86) zen3 or cannon lake when they drop to ~15 clocks.
> (I think someone finally allocated a bit of silicon to integer divide.)
This code needs to work more or less everywhere, not only x86.
> > Also a module alone would not be enough, as we need the division result.
>
> Isn't the divisor constant? (or rather a constant shifted left some).
> In that case you can do a 'multiply by reciprocal'.
> The simple 'multiply an shift right 32' will give slightly low quotient.
> But you need to calculate the remainder - so can fixup the overlarge
> remainder it can generate.
> Of course, even that is only worthwhile if the quotient is more than
> (a guess) 4.
It never is. As per patch 2:
monotonic_to_aux.tv_nsec is a normalised timespec64 fraction, so it stays
below NSEC_PER_SEC even for a negative offset, and the sum stays below
2 * (NSEC_PER_SEC << shift).
The same is true for the users in this patch.
Thomas