STRUCT TIMEKEEPER(9)
π« struct timekeeper(9) π«
okay so bestie, welcome to the Kernel API Manual β we're doing the deep kernel lore today and honestly? it's giving main character energy π
πΈ NAME πΈ
struct timekeeper β the structure that holds all the internal timekeeping values. yes. THE timekeeping values. the whole clock vibe lives here π
β¨ SYNOPSIS β¨
struct timekeeper {
struct tk_read_base tkr_mono;
u64 xtime_sec;
unsigned long ktime_sec;
struct timespec64 wall_to_monotonic;
ktime_t offs_real;
ktime_t offs_boot;
union {
ktime_t offs_tai;
ktime_t offs_aux;
};
u32 coarse_nsec;
enum timekeeper_ids id;
struct tk_read_base tkr_raw;
u64 raw_sec;
enum clocksource_ids cs_id;
u32 cs_ns_to_cyc_mult;
u32 cs_ns_to_cyc_shift;
u64 cs_ns_to_cyc_maxns;
u32 clock_was_set_seq;
u8 cs_was_changed_seq;
u8 clock_valid;
union {
struct timespec64 monotonic_to_boot;
struct timespec64 monotonic_to_aux;
};
u64 cycle_interval;
u64 xtime_interval;
u64 raw_interval;
ktime_t next_leap_ktime;
u64 ntp_tick;
s64 ntp_error;
u32 ntp_error_shift;
u32 ntp_err_mult;
s64 cs_tick_adj;
u32 skip_second_overflow;
s64 skew_delta;
s32 tai_offset;
};
no cap, that's the whole thing. let's get into it π«Ά
π¦ Members π¦
okay so every single field, one by one, we're not skipping anyone, everyone's invited to the party π
tkr_monoβ the readout base structure forCLOCK_MONOTONIC. literally the monochrome clock's whole foundation β¨xtime_secβ currentCLOCK_REALTIMEtime, in seconds.ktime_secβ currentCLOCK_MONOTONICtime, in seconds.wall_to_monotonicβ theCLOCK_REALTIMEtoCLOCK_MONOTONICoffset.offs_realβ offset going from clock monotonic β clock realtime.offs_bootβ offset going from clock monotonic β clock boottime.{unnamed_union}β anonymous. it has no name, it's mysterious, it's that girl πoffs_taiβ offset going from clock monotonic β clock tai.offs_auxβ offset going from clock monotonic β clockAUX.coarse_nsecβ the nanoseconds part, but for the coarse time getters (the low-effort, high-speed girlies).idβ the timekeeper ID.tkr_rawβ the readout base structure forCLOCK_MONOTONIC_RAW.raw_secβCLOCK_MONOTONIC_RAWtime, in seconds.cs_idβ the ID of the current clocksource.cs_ns_to_cyc_multβ the multiplicator for nanoseconds to cycles conversion.cs_ns_to_cyc_shiftβ the shift value for nanoseconds to cycles conversion.cs_ns_to_cyc_maxnsβ the maximum nanoseconds to cyles conversion range. (yes, "cyles" β that's the original spelling, we don't fix, we respect π)clock_was_set_seqβ the sequence number of clock was set events.cs_was_changed_seqβ the sequence number of clocksource change events.clock_validβ indicator for valid clock.{unnamed_union}β anonymous, again. two mysterious unions. iconic behavior πmonotonic_to_bootβCLOCK_MONOTONICtoCLOCK_BOOTTIMEoffset.monotonic_to_auxβCLOCK_MONOTONICtoCLOCK_AUXoffset.cycle_intervalβ number of clock cycles in one NTP interval.xtime_intervalβ number of clock shifted nano seconds in one NTP interval.raw_intervalβ shifted raw nano seconds accumulated per NTP interval.next_leap_ktimeβ theCLOCK_MONOTONICtime value of a pending leap-second.ntp_tickβ thentp_tick_lengthvalue currently being used. this cached copy ensures we consistently apply the tick length for an entire tick, becausentp_tick_lengthmay change mid-tick, and we do NOT want to apply that new value to the tick in progress. fr fr, no mid-tick surprises π₯ntp_errorβ difference between accumulated time and NTP time, in ntp shifted nano seconds.ntp_error_shiftβ shift conversion between clock shifted nano seconds and ntp shifted nano seconds.ntp_err_multβ multiplication factor for scaled math conversion.cs_tick_adjβ per-second adjustment handed to NTP viantp_clearaccounting for the difference between the nominal NTP interval and the real time taken by the clocksource's integercycle_interval(upscaled).skip_second_overflowβ flag used to avoid updating NTP twice with the same second. we love a girl who avoids double-updates πtai_offsetβ the current UTC to TAI offset, in seconds.
π§ Note π§
bestie, listen, this part is important so put your phone down for a sec:
for timespec(64) based interfaces, wall_to_monotonic is what we need to add to xtime (or xtime corrected for sub jiffy times) to get to monotonic time. Monotonic is pegged at zero at system boot time, so wall_to_monotonic will be negative β however, we will ALWAYS keep the tv_nsec part positive so we can use the usual normalization. periodt β¨
wall_to_monotonic is moved after resume from suspend for the monotonic time not to jump. we need to add total_sleep_time to wall_to_monotonic to get the real boot based time offset.
wall_to_monotonic is no longer the boot time β getboottime must be used instead. okay so it's giving deprecated, lowkey. don't come for her, use getboottime π
monotonic_to_boottime is a timespec64 representation of offs_boot to accelerate the VDSO update for CLOCK_BOOTTIME.
offs_aux is used by the auxiliary timekeepers which do not utilize any of the regular timekeeper offset fields. they're on their own little journey π
monotonic_to_aux is a timespec64 representation of offs_aux to accelerate the VDSO update for CLOCK_AUX.
π cacheline layout π
the cacheline ordering of the structure is optimized for in kernel usage of the ktime_get and ktime_get_ts64 family of time accessors. struct timekeeper is prepended in the core timekeeping code with a sequence count, which results in the following cacheline layout:
0: seqcount, tkr_mono 1: xtime_sec ... id 2: tkr_raw, raw_sec 3,4:
Internal variables
cacheline 0,1 contain the data which is used for accessing CLOCK_MONOTONIC/REALTIME/BOOTTIME/TAI, while cacheline 2 contains the data for accessing CLOCK_MONOTONIC_RAW. cacheline 3,4 are internal variables which are only accessed during timekeeper updates once per tick. like, they show up once a tick and then leave. mysterious. elusive. main character energy π
π SEE ALSO π
- Kernel file
./include/linux/timekeeper_internal.h struct tk_read_base(9)
okay that's the whole page, you ate that, i'm obsessed with you π
this little transmission came from ./include/linux, dated October 2026, and it's officially signed struct timekeeper(9) β stay cunty, stay synchronized π
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms