[GIT,pull] timers/urgent for v6.4

Message ID 168737611661.277769.2194490737572202840.tglx@xen13
State New
Headers
Series [GIT,pull] timers/urgent for v6.4 |

Commit Message

Thomas Gleixner June 21, 2023, 7:36 p.m. UTC
  Linus,

please pull the latest timers/urgent branch from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-2023-06-21

up to:  13bb06f8dd42: tick/common: Align tick period during sched_timer setup


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.

Thanks,

	tglx

------------------>
Thomas Gleixner (1):
      tick/common: Align tick period during sched_timer setup


 kernel/time/tick-common.c | 13 +------------
 kernel/time/tick-sched.c  | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 13 deletions(-)
  

Comments

pr-tracker-bot@kernel.org June 21, 2023, 7:53 p.m. UTC | #1
The pull request you sent on Wed, 21 Jun 2023 21:36:08 +0200 (CEST):

> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-urgent-2023-06-21

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/dad9774deaf1cf8e8f7483310dfb2690310193d2

Thank you!
  

Patch

diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 65b8658da829..e9138cd7a0f5 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -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
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 52254679ec48..42c0be3080bd 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -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);