Skip to content

Commit

Permalink
Merge tag 'timers-urgent-2023-06-21' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull timer fix from Thomas Gleixner:
 "A single regression fix for a regression fix:

  For a long time the tick was aligned to clock MONOTONIC so that the
  tick event happened at a multiple of nanoseconds per tick starting
  from clock MONOTONIC = 0.

  At some point this changed as the refined jiffies clocksource which is
  used during boot before the TSC or other clocksources becomes usable,
  was adjusted with a boot offset, so that time 0 is closer to the point
  where the kernel starts.

  This broke the assumption in the tick code that when the tick setup
  happens early on ktime_get() will return a multiple of nanoseconds per
  tick. As a consequence applications which aligned their periodic
  execution so that it does not collide with the tick were not longer
  guaranteed that the tick period starts from time 0.

  The fix for this regression was to realign the tick when it is
  initially set up to a multiple of tick periods. That works as long as
  the underlying tick device supports periodic mode, but breaks under
  certain conditions when the tick device supports only one shot mode.

  Depending on the offset, the alignment delta to clock MONOTONIC can
  get in a range where the minimal programming delta of the underlying
  clock event device is larger than the calculated delta to the next
  tick. This results in a boot hang as the tick code tries to play catch
  up, but as the tick never fires jiffies are not advanced so it keeps
  trying for ever.

  Solve this by moving the tick alignement into the NOHZ / HIGHRES
  enablement code because at that point it is guaranteed that the
  underlying clocksource is high resolution capable and not longer
  depending on the tick.

  This is far before user space starts, so at the point where
  applications try to align their timers, the old behaviour of the tick
  happening at a multiple of nanoseconds per tick starting from clock
  MONOTONIC = 0 is restored"

* tag 'timers-urgent-2023-06-21' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  tick/common: Align tick period during sched_timer setup
  • Loading branch information
torvalds committed Jun 21, 2023
2 parents 0070349 + 13bb06f commit dad9774
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 13 deletions.
13 changes: 1 addition & 12 deletions kernel/time/tick-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,19 +218,8 @@ static void tick_setup_device(struct tick_device *td,
* this cpu:
*/
if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
ktime_t next_p;
u32 rem;

tick_do_timer_cpu = cpu;

next_p = ktime_get();
div_u64_rem(next_p, TICK_NSEC, &rem);
if (rem) {
next_p -= rem;
next_p += TICK_NSEC;
}

tick_next_period = next_p;
tick_next_period = ktime_get();
#ifdef CONFIG_NO_HZ_FULL
/*
* The boot CPU may be nohz_full, in which case set
Expand Down
13 changes: 12 additions & 1 deletion kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,19 @@ static ktime_t tick_init_jiffy_update(void)
raw_spin_lock(&jiffies_lock);
write_seqcount_begin(&jiffies_seq);
/* Did we start the jiffies update yet ? */
if (last_jiffies_update == 0)
if (last_jiffies_update == 0) {
u32 rem;

/*
* Ensure that the tick is aligned to a multiple of
* TICK_NSEC.
*/
div_u64_rem(tick_next_period, TICK_NSEC, &rem);
if (rem)
tick_next_period += TICK_NSEC - rem;

last_jiffies_update = tick_next_period;
}
period = last_jiffies_update;
write_seqcount_end(&jiffies_seq);
raw_spin_unlock(&jiffies_lock);
Expand Down

0 comments on commit dad9774

Please sign in to comment.