<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/linux.git/include/linux/timekeeper_internal.h, branch v7.3-rc1</title>
<subtitle>Linux kernel stable tree (mirror)</subtitle>
<id>https://git.radix-linux.su/kernel/linux.git/atom?h=v7.3-rc1</id>
<link rel='self' href='https://git.radix-linux.su/kernel/linux.git/atom?h=v7.3-rc1'/>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/'/>
<updated>2026-08-11T16:11:20+00:00</updated>
<entry>
<title>timekeeping: Use u32 for clock_was_set_seq</title>
<updated>2026-08-11T16:11:20+00:00</updated>
<author>
<name>Thomas Weißschuh (Schneider Electric)</name>
<email>thomas.weissschuh@linutronix.de</email>
</author>
<published>2026-08-03T10:04:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=406a037ce7a03a37bf2b03010791ea9343ecc233'/>
<id>urn:sha1:406a037ce7a03a37bf2b03010791ea9343ecc233</id>
<content type='text'>
Use an explicitly sized type to make the code a bit more consistent
with other fields of the datastructure and other sequence counters.

Signed-off-by: Thomas Weißschuh (Schneider Electric) &lt;thomas.weissschuh@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Link: https://patch.msgid.link/20260803-auxclock-nanosleep-prep-v2-2-910cbd485390@linutronix.de
</content>
</entry>
<entry>
<title>timekeeping: Drive time_offset skew via per-tick ntp_error transfer</title>
<updated>2026-07-10T07:20:54+00:00</updated>
<author>
<name>David Woodhouse</name>
<email>dwmw@amazon.co.uk</email>
</author>
<published>2026-06-21T21:53:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=d375af58990902e73dd62bd7c049e759bcff92a5'/>
<id>urn:sha1:d375af58990902e73dd62bd7c049e759bcff92a5</id>
<content type='text'>
Currently, the phase offset of time_offset and time_adjust is delivered
by adjusting tick_length in second_overflow(), and immediately draining
time_offset/time_adjust by the amount that the tick_length adjustment is
*estimated* to cause. This is fairly approximate, in part because it is
not always correct to assume that precisely NTP_INTERVAL_FREQ ticks will
occur between one call to second_overflow() and the next. It could also
over and under-run in the final second of delivery.

Instead of inflating tick_length, transfer the intended skew directly
into ntp_error each tick to achieve the desired rate.

In second_overflow(), calculate skew_delta which is the per-tick slew
rate, in the same units as time_offset: (ns &lt;&lt; NTP_SCALE_SHIFT) / HZ.

In logarithmic_accumulation(), drain up to 'skew_delta' time units from
time_offset into ntp_error to drive the overall effective rate. The new
ntp_drain_skew() function returns the amount which is actually 'claimed'
by time_offset (and in a future patch, time_adjust). Any overrun which
is delivered by the changed 'mult' (as described below) but not claimed
by ntp_drain_skew() will remain in ntp_error to be corrected away in
subsequent ticks.

Simply transferring the precise amount from time_offset to ntp_error
would be sufficent to make the time *eventually* converge, however the
skew delivered is limited by the choice of { mult, mult+1 } each tick
and thus the convergence would be extremely slow.

In theory we could inflate ntp_err_mult with the magnitude of ntp_error
in the general case — but that would cause overcorrection in a tickless
kernel. Instead, in timekeeping_adjust(), take skew_delta into account
when calculating 'mult', such that the available {mult, mult+1} choices
bracket the overall effective rate *including* the skew, to avoid the
delta just building up in ntp_error.

The effect is that the inflated 'mult' causes ntp_error to grow because
xtime_interval is (e.g.) longer than the true tick_length. But then the
same delta is removed again as it's drained from time_offset.

This gives behaviour equivalent to the old tick_length += delta approach
but with exact per-tick accounting of the time_offset actually imparted
to the clock, and no overrun.

Signed-off-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Assisted-by: Kiro:claude-opus-4.8
Link: https://patch.msgid.link/20260621220051.1030462-5-dwmw2@infradead.org
</content>
</entry>
<entry>
<title>timekeeping: Account for clocksource tick quantisation via NTP</title>
<updated>2026-07-10T07:20:54+00:00</updated>
<author>
<name>David Woodhouse</name>
<email>dwmw@amazon.co.uk</email>
</author>
<published>2026-06-21T21:53:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=869a55e662a080a5c6618b68ae320231c720eeee'/>
<id>urn:sha1:869a55e662a080a5c6618b68ae320231c720eeee</id>
<content type='text'>
cycle_interval is an integer number of counter cycles per NTP interval,
so the real time it represents differs from the nominal
NTP_INTERVAL_LENGTH by up to half a counter period. For coarse
clocksources this is significant: the 3.579545 MHz ACPI PM timer at
HZ=1000 rounds 3579.545 cycles up to 3580, making each tick 1.000127 ms
(+127 PPM).

Commit a386b5af8edd ("time: Compensate for rounding on odd-frequency
clocksources") introduced xtime_remainder to compensate for exactly
this, citing the same 127 PPM ACPI PM example. The compensation is
correct and necessary, but it was applied inside the timekeeping
accumulation in timekeeping.c: subtracted in the mult computation in
timekeeping_adjust() and folded into the ntp_error update in
logarithmic_accumulation(). That keeps the base rate correct and leaves
NTP its full symmetric +/-MAXFREQ range rather than +373/-627 PPM, but
the NTP code in ntp.c never sees it: tick_length is computed without the
correction, so ntp.c's notion of how long a tick is disagrees with the
rate timekeeping actually produces.

Make the offset an explicit part of the NTP tick_length instead. Add
ntp_data::cs_tick_adj, a fixed per-second addend that
ntp_update_frequency() includes alongside ntp_tick_adj and time_freq.
tk_setup_internals() computes it from the difference between the real
cycle_interval duration and the nominal interval, stores it in the
timekeeper, and hands it to NTP through a new argument to ntp_clear() --
which already recomputes the frequency and is invoked after every
clocksource (re)configuration. timekeeping_init() now uses TK_UPDATE_ALL
for this; clearing NTP there is otherwise redundant since ntp_init() has
just initialised it.

ntp.c now computes the true tick rate, giving a single source of truth.
Like ntp_tick_adj, cs_tick_adj stays internal to the kernel: userspace
still sees the nominal 1.000000 ms tick via adjtimex and is unaware of
the addends. timekeeping_adjust() and logarithmic_accumulation() use
ntp_tick / xtime_interval directly, and xtime_remainder is removed.

The base-rate arithmetic is unchanged: ntp_tick becomes
xtime_interval &lt;&lt; ntp_error_shift, so the mult division yields the same
base mult and the ntp_error accumulation still nets to zero per tick.

Beyond the cleanup of treating all the tick_length contributions
(nominal interval, ntp_tick_adj, cs_tick_adj, time_freq) consistently
as addends in one place, it also prepares for feed-forward discipline:
a future timekeeping_set_reference() will set tick_length to track an
absolute external reference such as a vmclock, and that path needs
ntp.c to own a tick_length that already reflects the clocksource
quantisation, with no hidden correction applied elsewhere.

Signed-off-by: David Woodhouse &lt;dwmw@amazon.co.uk&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Assisted-by: Kiro:claude-opus-4.8
Acked-by: John Stultz &lt;jstultz@google.com&gt;
Link: https://patch.msgid.link/20260621220051.1030462-4-dwmw2@infradead.org
</content>
</entry>
<entry>
<title>timekeeping: Move the vDSO update declarations into a private header</title>
<updated>2026-07-07T21:48:08+00:00</updated>
<author>
<name>Thomas Weißschuh</name>
<email>thomas.weissschuh@linutronix.de</email>
</author>
<published>2026-07-07T06:07:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=79bd39c58f2c6fdbc5fb6300d309606f3cb84ab8'/>
<id>urn:sha1:79bd39c58f2c6fdbc5fb6300d309606f3cb84ab8</id>
<content type='text'>
All architectures are now fully using the generic vDSO infrastructure.
They don't need these declarations anymore to implement the functions
in architecture-specific code.

Move them to the private header.

Signed-off-by: Thomas Weißschuh &lt;thomas.weissschuh@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Link: https://patch.msgid.link/20260707-timekeeping-header-cleanup-v1-2-e85ad96409a9@linutronix.de
</content>
</entry>
<entry>
<title>timekeeping: Fold vdso_time_update_aux() declarations into the generic ifdeffery</title>
<updated>2026-07-07T21:48:08+00:00</updated>
<author>
<name>Thomas Weißschuh</name>
<email>thomas.weissschuh@linutronix.de</email>
</author>
<published>2026-07-07T06:07:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=6e435911394b05c91b92d4c332c455ec569e22fb'/>
<id>urn:sha1:6e435911394b05c91b92d4c332c455ec569e22fb</id>
<content type='text'>
The only caller of vdso_time_update_aux() is already gated behind
CONFIG_POSIX_AUX. The additional check in the header files is not
necessary.

Remove it and then fold the declarations into the existing
CONFIG_GENERIC_GETTIMEOFDAY ifdeffery.

Signed-off-by: Thomas Weißschuh &lt;thomas.weissschuh@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Link: https://patch.msgid.link/20260707-timekeeping-header-cleanup-v1-1-e85ad96409a9@linutronix.de
</content>
</entry>
<entry>
<title>vdso/vsyscall: Gate update_vsyscall() behind CONFIG_GENERIC_GETTIMEOFDAY</title>
<updated>2026-06-02T19:41:23+00:00</updated>
<author>
<name>Thomas Weißschuh</name>
<email>thomas.weissschuh@linutronix.de</email>
</author>
<published>2026-05-19T06:26:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=bf8f968a63159661acc20254ccdf0dc3c9f1bac2'/>
<id>urn:sha1:bf8f968a63159661acc20254ccdf0dc3c9f1bac2</id>
<content type='text'>
Both the compilation of kernel/time/vsyscall.c, which contains the real
definition of update_vsyscall() and the other vDSO definitions in
timekeeper_internal.h use CONFIG_GENERIC_GETTIMEOFDAY and not
CONFIG_GENERIC_TIME_VSYSCALL.

Align the code to use a single Kconfig symbol.

Signed-off-by: Thomas Weißschuh &lt;thomas.weissschuh@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Link: https://patch.msgid.link/20260519-vdso-generic_time_vsyscal-v1-2-5c2a5905d5f5@linutronix.de
</content>
</entry>
<entry>
<title>timekeeping: Provide infrastructure for coupled clockevents</title>
<updated>2026-02-27T15:40:08+00:00</updated>
<author>
<name>Thomas Gleixner</name>
<email>tglx@kernel.org</email>
</author>
<published>2026-02-24T16:36:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=cd38bdb8e696a1a1eb12fc6662a6e420977aacfd'/>
<id>urn:sha1:cd38bdb8e696a1a1eb12fc6662a6e420977aacfd</id>
<content type='text'>
Some architectures have clockevent devices which are coupled to the system
clocksource by implementing a less than or equal comparator which compares
the programmed absolute expiry time against the underlying time
counter. Well known examples are TSC/TSC deadline timer and the S390 TOD
clocksource/comparator.

While the concept is nice it has some downsides:

  1) The clockevents core code is strictly based on relative expiry times
     as that's the most common case for clockevent device hardware. That
     requires to convert the absolute expiry time provided by the caller
     (hrtimers, NOHZ code) to a relative expiry time by reading and
     substracting the current time.

     The clockevent::set_next_event() callback must then read the counter
     again to convert the relative expiry back into a absolute one.

  2) The conversion factors from nanoseconds to counter clock cycles are
     set up when the clockevent is registered. When NTP applies corrections
     then the clockevent conversion factors can deviate from the
     clocksource conversion substantially which either results in timers
     firing late or in the worst case early. The early expiry then needs to
     do a reprogam with a short delta.

     In most cases this is papered over by the fact that the read in the
     set_next_event() callback happens after the read which is used to
     calculate the delta. So the tendency is that timers expire mostly
     late.

All of this can be avoided by providing support for these devices in the
core code:

  1) The timekeeping core keeps track of the last update to the clocksource
     by storing the base nanoseconds and the corresponding clocksource
     counter value. That's used to keep the conversion math for reading the
     time within 64-bit in the common case.

     This information can be used to avoid both reads of the underlying
     clocksource in the clockevents reprogramming path:

     delta = expiry - base_ns;
     cycles = base_cycles + ((delta * clockevent::mult) &gt;&gt; clockevent::shift);

     The resulting cycles value can be directly used to program the
     comparator.

  2) As #1 does not longer provide the "compensation" through the second
     read the deviation of the clocksource and clockevent conversions
     caused by NTP become more prominent.

     This can be cured by letting the timekeeping core compute and store
     the reverse conversion factors when the clocksource cycles to
     nanoseconds factors are modified by NTP:

         CS::MULT      (1 &lt;&lt; NS_TO_CYC_SHIFT)
     --------------- = ----------------------
     (1 &lt;&lt; CS:SHIFT)       NS_TO_CYC_MULT

     Ergo: NS_TO_CYC_MULT = (1 &lt;&lt; (CS::SHIFT + NS_TO_CYC_SHIFT)) / CS::MULT

     The NS_TO_CYC_SHIFT value is calculated when the clocksource is
     installed so that it aims for a one hour maximum sleep time.

Signed-off-by: Thomas Gleixner &lt;tglx@kernel.org&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Link: https://patch.msgid.link/20260224163429.944763521@kernel.org
</content>
</entry>
<entry>
<title>vdso/vsyscall: Avoid slow division loop in auxiliary clock update</title>
<updated>2025-09-03T09:55:11+00:00</updated>
<author>
<name>Thomas Weißschuh</name>
<email>thomas.weissschuh@linutronix.de</email>
</author>
<published>2025-08-25T13:26:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=762af5a2aa0ad18da1316666dae30d369268d44c'/>
<id>urn:sha1:762af5a2aa0ad18da1316666dae30d369268d44c</id>
<content type='text'>
The call to __iter_div_u64_rem() in vdso_time_update_aux() is a wrapper
around subtraction. It cannot be used to divide large numbers, as that
introduces long, computationally expensive delays.  A regular u64 division
is also not possible in the timekeeper update path as it can be too slow.

Instead of splitting the ktime_t offset into into second and subsecond
components during the timekeeper update fast-path, do it together with the
adjustment of tk-&gt;offs_aux in the slow-path. Equivalent to the handling of
offs_boot and monotonic_to_boot.

Reuse the storage of monotonic_to_boot for the new field, as it is not used
by auxiliary timekeepers.

Fixes: 380b84e168e5 ("vdso/vsyscall: Update auxiliary clock data in the datapage")
Reported-by: Miroslav Lichvar &lt;mlichvar@redhat.com&gt;
Signed-off-by: Thomas Weißschuh &lt;thomas.weissschuh@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lore.kernel.org/all/20250825-vdso-auxclock-division-v1-1-a1d32a16a313@linutronix.de
Closes: https://lore.kernel.org/lkml/aKwsNNWsHJg8IKzj@localhost/
</content>
</entry>
<entry>
<title>vdso/vsyscall: Update auxiliary clock data in the datapage</title>
<updated>2025-07-18T11:45:33+00:00</updated>
<author>
<name>Thomas Weißschuh</name>
<email>thomas.weissschuh@linutronix.de</email>
</author>
<published>2025-07-01T08:58:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=380b84e168e57c54d0a9e053a5558fddc43f0c1a'/>
<id>urn:sha1:380b84e168e57c54d0a9e053a5558fddc43f0c1a</id>
<content type='text'>
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 &lt;thomas.weissschuh@linutronix.de&gt;
Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Link: https://lore.kernel.org/all/20250701-vdso-auxclock-v1-11-df7d9f87b9b8@linutronix.de

</content>
</entry>
<entry>
<title>timekeeping: Add AUX offset to struct timekeeper</title>
<updated>2025-06-19T12:28:24+00:00</updated>
<author>
<name>Thomas Gleixner</name>
<email>tglx@linutronix.de</email>
</author>
<published>2025-05-19T08:33:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.radix-linux.su/kernel/linux.git/commit/?id=180d8b4ce91fe0cf7a9cb236bb01f14587ba4bf0'/>
<id>urn:sha1:180d8b4ce91fe0cf7a9cb236bb01f14587ba4bf0</id>
<content type='text'>
This offset will be used in the time getters of auxiliary clocks. It is
added to the "monotonic" clock readout.

As auxiliary clocks do not utilize the offset fields of the core time
keeper, this is just an alias for offs_tai, so that the cache line layout
stays the same.

Signed-off-by: Thomas Gleixner &lt;tglx@linutronix.de&gt;
Acked-by: John Stultz &lt;jstultz@google.com&gt;
Link: https://lore.kernel.org/all/20250519083026.533486349@linutronix.de

</content>
</entry>
</feed>
