On Thu, Apr 17, 2025 at 11:37 PM Thomas Gleixner <t...@linutronix.de> wrote: > On Thu, Apr 17 2025 at 17:46, John Stultz wrote: > > On Sat, Apr 5, 2025 at 2:40 PM Thomas Gleixner <t...@linutronix.de> wrote: > >> +static inline void tk_update_coarse_nsecs(struct timekeeper *tk, u64 > >> offset) > >> +{ > >> + offset *= tk->tkr_mono.mult; > >> + tk->coarse_nsec = (tk->tkr_mono.xtime_nsec + offset) >> > >> tk->tkr_mono.shift; > >> +} > > > > Thinking more on this, I get that you're providing the offset to save > > the "at the point" time into the coarse value, but I think this ends > > up complicating things. > > > > Instead it seems like we should just do: > > tk->coarse_nsec = tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift; > > You end up with the same problem again because xtime_nsec can move > backwards when the multiplier is updated, no?
That's assuming you update coarse_nsec on every call to do_adjtimex, which I don't think is necessary (or wanted - as it would sort of be a behavior change to the COARSE clockids). The root issue here has been that there was a mistaken assumption that the small negative adjustment done to the xtime_nsec base to match the mult adjustment would only happen after a larger accumulation, but the timekeeping_advance() call from do_adjtimex() doesn't actually intend to advance the clock (just change the frequency), so those small negative adjustments made via do_adjtimex() between accumulations become visible to the coarse clockids. Since the coarse clockids are expected to provide ~tick-granular time, if we are keeping separate state, we should only be incrementing/setting that state when we accumulate (with each cycle_interval). We don't need to be making updates to the coarse clock between ticks on every do_adjtime call. So saving off the tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift value after we actually accumulated something should be fine. Any inter-tick frequency adjustments to xtime_nsec can be ignored by the coarse clockid state. I'll test with your updated patch here, as I suspect it will avoid the problem I'm seeing, but I do think things can be further simplified. thanks -john