]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Drop timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
authorSasha Levin <sashal@kernel.org>
Tue, 8 Apr 2025 01:10:01 +0000 (21:10 -0400)
committerSasha Levin <sashal@kernel.org>
Tue, 8 Apr 2025 01:10:01 +0000 (21:10 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.13/series
queue-6.13/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch [deleted file]
queue-6.14/series
queue-6.14/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch [deleted file]

index e68fbeca1cfa76c51cbd457dd8c74645fa947023..079a893966f4296af40a35b82d5d55e422ee3e4f 100644 (file)
@@ -40,7 +40,6 @@ x86-traps-make-exc_double_fault-consistently-noretur.patch
 x86-fpu-xstate-fix-inconsistencies-in-guest-fpu-xfea.patch
 x86-entry-add-__init-to-ia32_emulation_override_cmdl.patch
 risc-v-kvm-teardown-riscv-specific-bits-after-kvm_ex.patch
-timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
 regulator-pca9450-fix-enable-register-for-ldo5.patch
 auxdisplay-max6959-should-select-bitreverse.patch
 media-verisilicon-hevc-initialize-start_bit-field.patch
diff --git a/queue-6.13/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch b/queue-6.13/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
deleted file mode 100644 (file)
index 114ffa3..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-From 0e80b7b345f17792f3727fba372d9560f4a79fd4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 20 Mar 2025 13:03:00 -0700
-Subject: timekeeping: Fix possible inconsistencies in _COARSE clockids
-
-From: John Stultz <jstultz@google.com>
-
-[ Upstream commit 757b000f7b936edf79311ab0971fe465bbda75ea ]
-
-Lei Chen raised an issue with CLOCK_MONOTONIC_COARSE seeing time
-inconsistencies.
-
-Lei tracked down that this was being caused by the adjustment
-
-    tk->tkr_mono.xtime_nsec -= offset;
-
-which is made to compensate for the unaccumulated cycles in offset when the
-multiplicator is adjusted forward, so that the non-_COARSE clockids don't
-see inconsistencies.
-
-However, the _COARSE clockid getter functions use the adjusted xtime_nsec
-value directly and do not compensate the negative offset via the
-clocksource delta multiplied with the new multiplicator. In that case the
-caller can observe time going backwards in consecutive calls.
-
-By design, this negative adjustment should be fine, because the logic run
-from timekeeping_adjust() is done after it accumulated approximately
-
-     multiplicator * interval_cycles
-
-into xtime_nsec.  The accumulated value is always larger then the
-
-     mult_adj * offset
-
-value, which is subtracted from xtime_nsec. Both operations are done
-together under the tk_core.lock, so the net change to xtime_nsec is always
-always be positive.
-
-However, do_adjtimex() calls into timekeeping_advance() as well, to to
-apply the NTP frequency adjustment immediately. In this case,
-timekeeping_advance() does not return early when the offset is smaller then
-interval_cycles. In that case there is no time accumulated into
-xtime_nsec. But the subsequent call into timekeeping_adjust(), which
-modifies the multiplicator, subtracts from xtime_nsec to correct
-for the new multiplicator.
-
-Here because there was no accumulation, xtime_nsec becomes smaller than
-before, which opens a window up to the next accumulation, where the _COARSE
-clockid getters, which don't compensate for the offset, can observe the
-inconsistency.
-
-To fix this, rework the timekeeping_advance() logic so that when invoked
-from do_adjtimex(), the time is immediately forwarded to accumulate also
-the sub-interval portion into xtime. That means the remaining offset
-becomes zero and the subsequent multiplier adjustment therefore does not
-modify xtime_nsec.
-
-There is another related inconsistency. If xtime is forwarded due to the
-instantaneous multiplier adjustment, the NTP error, which was accumulated
-with the previous setting, becomes meaningless.
-
-Therefore clear the NTP error as well, after forwarding the clock for the
-instantaneous multiplier update.
-
-Fixes: da15cfdae033 ("time: Introduce CLOCK_REALTIME_COARSE")
-Reported-by: Lei Chen <lei.chen@smartx.com>
-Signed-off-by: John Stultz <jstultz@google.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Link: https://lore.kernel.org/all/20250320200306.1712599-1-jstultz@google.com
-Closes: https://lore.kernel.org/lkml/20250310030004.3705801-1-lei.chen@smartx.com/
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- kernel/time/timekeeping.c | 94 ++++++++++++++++++++++++++++-----------
- 1 file changed, 69 insertions(+), 25 deletions(-)
-
-diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
-index 3d128825d3437..6959f5d341d42 100644
---- a/kernel/time/timekeeping.c
-+++ b/kernel/time/timekeeping.c
-@@ -743,20 +743,19 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
- }
- /**
-- * timekeeping_forward_now - update clock to the current time
-+ * timekeeping_forward - update clock to given cycle now value
-  * @tk:               Pointer to the timekeeper to update
-+ * @cycle_now:  Current clocksource read value
-  *
-  * Forward the current clock to update its state since the last call to
-  * update_wall_time(). This is useful before significant clock changes,
-  * as it avoids having to deal with this time offset explicitly.
-  */
--static void timekeeping_forward_now(struct timekeeper *tk)
-+static void timekeeping_forward(struct timekeeper *tk, u64 cycle_now)
- {
--      u64 cycle_now, delta;
-+      u64 delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask,
-+                                    tk->tkr_mono.clock->max_raw_delta);
--      cycle_now = tk_clock_read(&tk->tkr_mono);
--      delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask,
--                                tk->tkr_mono.clock->max_raw_delta);
-       tk->tkr_mono.cycle_last = cycle_now;
-       tk->tkr_raw.cycle_last  = cycle_now;
-@@ -771,6 +770,21 @@ static void timekeeping_forward_now(struct timekeeper *tk)
-       }
- }
-+/**
-+ * timekeeping_forward_now - update clock to the current time
-+ * @tk:               Pointer to the timekeeper to update
-+ *
-+ * Forward the current clock to update its state since the last call to
-+ * update_wall_time(). This is useful before significant clock changes,
-+ * as it avoids having to deal with this time offset explicitly.
-+ */
-+static void timekeeping_forward_now(struct timekeeper *tk)
-+{
-+      u64 cycle_now = tk_clock_read(&tk->tkr_mono);
-+
-+      timekeeping_forward(tk, cycle_now);
-+}
-+
- /**
-  * ktime_get_real_ts64 - Returns the time of day in a timespec64.
-  * @ts:               pointer to the timespec to be set
-@@ -2212,6 +2226,54 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
-       return offset;
- }
-+static u64 timekeeping_accumulate(struct timekeeper *tk, u64 offset,
-+                                enum timekeeping_adv_mode mode,
-+                                unsigned int *clock_set)
-+{
-+      int shift = 0, maxshift;
-+
-+      /*
-+       * TK_ADV_FREQ indicates that adjtimex(2) directly set the
-+       * frequency or the tick length.
-+       *
-+       * Accumulate the offset, so that the new multiplier starts from
-+       * now. This is required as otherwise for offsets, which are
-+       * smaller than tk::cycle_interval, timekeeping_adjust() could set
-+       * xtime_nsec backwards, which subsequently causes time going
-+       * backwards in the coarse time getters. But even for the case
-+       * where offset is greater than tk::cycle_interval the periodic
-+       * accumulation does not have much value.
-+       *
-+       * Also reset tk::ntp_error as it does not make sense to keep the
-+       * old accumulated error around in this case.
-+       */
-+      if (mode == TK_ADV_FREQ) {
-+              timekeeping_forward(tk, tk->tkr_mono.cycle_last + offset);
-+              tk->ntp_error = 0;
-+              return 0;
-+      }
-+
-+      /*
-+       * With NO_HZ we may have to accumulate many cycle_intervals
-+       * (think "ticks") worth of time at once. To do this efficiently,
-+       * we calculate the largest doubling multiple of cycle_intervals
-+       * that is smaller than the offset.  We then accumulate that
-+       * chunk in one go, and then try to consume the next smaller
-+       * doubled multiple.
-+       */
-+      shift = ilog2(offset) - ilog2(tk->cycle_interval);
-+      shift = max(0, shift);
-+      /* Bound shift to one less than what overflows tick_length */
-+      maxshift = (64 - (ilog2(ntp_tick_length()) + 1)) - 1;
-+      shift = min(shift, maxshift);
-+      while (offset >= tk->cycle_interval) {
-+              offset = logarithmic_accumulation(tk, offset, shift, clock_set);
-+              if (offset < tk->cycle_interval << shift)
-+                      shift--;
-+      }
-+      return offset;
-+}
-+
- /*
-  * timekeeping_advance - Updates the timekeeper to the current time and
-  * current NTP tick length
-@@ -2221,7 +2283,6 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
-       struct timekeeper *tk = &tk_core.shadow_timekeeper;
-       struct timekeeper *real_tk = &tk_core.timekeeper;
-       unsigned int clock_set = 0;
--      int shift = 0, maxshift;
-       u64 offset;
-       guard(raw_spinlock_irqsave)(&tk_core.lock);
-@@ -2238,24 +2299,7 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
-       if (offset < real_tk->cycle_interval && mode == TK_ADV_TICK)
-               return false;
--      /*
--       * With NO_HZ we may have to accumulate many cycle_intervals
--       * (think "ticks") worth of time at once. To do this efficiently,
--       * we calculate the largest doubling multiple of cycle_intervals
--       * that is smaller than the offset.  We then accumulate that
--       * chunk in one go, and then try to consume the next smaller
--       * doubled multiple.
--       */
--      shift = ilog2(offset) - ilog2(tk->cycle_interval);
--      shift = max(0, shift);
--      /* Bound shift to one less than what overflows tick_length */
--      maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1;
--      shift = min(shift, maxshift);
--      while (offset >= tk->cycle_interval) {
--              offset = logarithmic_accumulation(tk, offset, shift, &clock_set);
--              if (offset < tk->cycle_interval<<shift)
--                      shift--;
--      }
-+      offset = timekeeping_accumulate(tk, offset, mode, &clock_set);
-       /* Adjust the multiplier to correct NTP error */
-       timekeeping_adjust(tk, offset);
--- 
-2.39.5
-
index 6652f5690c1da8822f0d5ced6544f858266065c8..e05297f3b48afc3490b928ca27f91fda53f072bb 100644 (file)
@@ -54,7 +54,6 @@ x86-traps-make-exc_double_fault-consistently-noretur.patch
 x86-fpu-xstate-fix-inconsistencies-in-guest-fpu-xfea.patch
 x86-entry-add-__init-to-ia32_emulation_override_cmdl.patch
 risc-v-kvm-teardown-riscv-specific-bits-after-kvm_ex.patch
-timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
 regulator-pca9450-fix-enable-register-for-ldo5.patch
 auxdisplay-max6959-should-select-bitreverse.patch
 media-verisilicon-hevc-initialize-start_bit-field.patch
diff --git a/queue-6.14/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch b/queue-6.14/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch
deleted file mode 100644 (file)
index 7a26769..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-From cb6ae383145403c779d9dd8dc6fdfc2bcdc42d32 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 20 Mar 2025 13:03:00 -0700
-Subject: timekeeping: Fix possible inconsistencies in _COARSE clockids
-
-From: John Stultz <jstultz@google.com>
-
-[ Upstream commit 757b000f7b936edf79311ab0971fe465bbda75ea ]
-
-Lei Chen raised an issue with CLOCK_MONOTONIC_COARSE seeing time
-inconsistencies.
-
-Lei tracked down that this was being caused by the adjustment
-
-    tk->tkr_mono.xtime_nsec -= offset;
-
-which is made to compensate for the unaccumulated cycles in offset when the
-multiplicator is adjusted forward, so that the non-_COARSE clockids don't
-see inconsistencies.
-
-However, the _COARSE clockid getter functions use the adjusted xtime_nsec
-value directly and do not compensate the negative offset via the
-clocksource delta multiplied with the new multiplicator. In that case the
-caller can observe time going backwards in consecutive calls.
-
-By design, this negative adjustment should be fine, because the logic run
-from timekeeping_adjust() is done after it accumulated approximately
-
-     multiplicator * interval_cycles
-
-into xtime_nsec.  The accumulated value is always larger then the
-
-     mult_adj * offset
-
-value, which is subtracted from xtime_nsec. Both operations are done
-together under the tk_core.lock, so the net change to xtime_nsec is always
-always be positive.
-
-However, do_adjtimex() calls into timekeeping_advance() as well, to to
-apply the NTP frequency adjustment immediately. In this case,
-timekeeping_advance() does not return early when the offset is smaller then
-interval_cycles. In that case there is no time accumulated into
-xtime_nsec. But the subsequent call into timekeeping_adjust(), which
-modifies the multiplicator, subtracts from xtime_nsec to correct
-for the new multiplicator.
-
-Here because there was no accumulation, xtime_nsec becomes smaller than
-before, which opens a window up to the next accumulation, where the _COARSE
-clockid getters, which don't compensate for the offset, can observe the
-inconsistency.
-
-To fix this, rework the timekeeping_advance() logic so that when invoked
-from do_adjtimex(), the time is immediately forwarded to accumulate also
-the sub-interval portion into xtime. That means the remaining offset
-becomes zero and the subsequent multiplier adjustment therefore does not
-modify xtime_nsec.
-
-There is another related inconsistency. If xtime is forwarded due to the
-instantaneous multiplier adjustment, the NTP error, which was accumulated
-with the previous setting, becomes meaningless.
-
-Therefore clear the NTP error as well, after forwarding the clock for the
-instantaneous multiplier update.
-
-Fixes: da15cfdae033 ("time: Introduce CLOCK_REALTIME_COARSE")
-Reported-by: Lei Chen <lei.chen@smartx.com>
-Signed-off-by: John Stultz <jstultz@google.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Link: https://lore.kernel.org/all/20250320200306.1712599-1-jstultz@google.com
-Closes: https://lore.kernel.org/lkml/20250310030004.3705801-1-lei.chen@smartx.com/
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- kernel/time/timekeeping.c | 94 ++++++++++++++++++++++++++++-----------
- 1 file changed, 69 insertions(+), 25 deletions(-)
-
-diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
-index 1e67d076f1955..929846b8b45ab 100644
---- a/kernel/time/timekeeping.c
-+++ b/kernel/time/timekeeping.c
-@@ -682,20 +682,19 @@ static void timekeeping_update_from_shadow(struct tk_data *tkd, unsigned int act
- }
- /**
-- * timekeeping_forward_now - update clock to the current time
-+ * timekeeping_forward - update clock to given cycle now value
-  * @tk:               Pointer to the timekeeper to update
-+ * @cycle_now:  Current clocksource read value
-  *
-  * Forward the current clock to update its state since the last call to
-  * update_wall_time(). This is useful before significant clock changes,
-  * as it avoids having to deal with this time offset explicitly.
-  */
--static void timekeeping_forward_now(struct timekeeper *tk)
-+static void timekeeping_forward(struct timekeeper *tk, u64 cycle_now)
- {
--      u64 cycle_now, delta;
-+      u64 delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask,
-+                                    tk->tkr_mono.clock->max_raw_delta);
--      cycle_now = tk_clock_read(&tk->tkr_mono);
--      delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask,
--                                tk->tkr_mono.clock->max_raw_delta);
-       tk->tkr_mono.cycle_last = cycle_now;
-       tk->tkr_raw.cycle_last  = cycle_now;
-@@ -710,6 +709,21 @@ static void timekeeping_forward_now(struct timekeeper *tk)
-       }
- }
-+/**
-+ * timekeeping_forward_now - update clock to the current time
-+ * @tk:               Pointer to the timekeeper to update
-+ *
-+ * Forward the current clock to update its state since the last call to
-+ * update_wall_time(). This is useful before significant clock changes,
-+ * as it avoids having to deal with this time offset explicitly.
-+ */
-+static void timekeeping_forward_now(struct timekeeper *tk)
-+{
-+      u64 cycle_now = tk_clock_read(&tk->tkr_mono);
-+
-+      timekeeping_forward(tk, cycle_now);
-+}
-+
- /**
-  * ktime_get_real_ts64 - Returns the time of day in a timespec64.
-  * @ts:               pointer to the timespec to be set
-@@ -2151,6 +2165,54 @@ static u64 logarithmic_accumulation(struct timekeeper *tk, u64 offset,
-       return offset;
- }
-+static u64 timekeeping_accumulate(struct timekeeper *tk, u64 offset,
-+                                enum timekeeping_adv_mode mode,
-+                                unsigned int *clock_set)
-+{
-+      int shift = 0, maxshift;
-+
-+      /*
-+       * TK_ADV_FREQ indicates that adjtimex(2) directly set the
-+       * frequency or the tick length.
-+       *
-+       * Accumulate the offset, so that the new multiplier starts from
-+       * now. This is required as otherwise for offsets, which are
-+       * smaller than tk::cycle_interval, timekeeping_adjust() could set
-+       * xtime_nsec backwards, which subsequently causes time going
-+       * backwards in the coarse time getters. But even for the case
-+       * where offset is greater than tk::cycle_interval the periodic
-+       * accumulation does not have much value.
-+       *
-+       * Also reset tk::ntp_error as it does not make sense to keep the
-+       * old accumulated error around in this case.
-+       */
-+      if (mode == TK_ADV_FREQ) {
-+              timekeeping_forward(tk, tk->tkr_mono.cycle_last + offset);
-+              tk->ntp_error = 0;
-+              return 0;
-+      }
-+
-+      /*
-+       * With NO_HZ we may have to accumulate many cycle_intervals
-+       * (think "ticks") worth of time at once. To do this efficiently,
-+       * we calculate the largest doubling multiple of cycle_intervals
-+       * that is smaller than the offset.  We then accumulate that
-+       * chunk in one go, and then try to consume the next smaller
-+       * doubled multiple.
-+       */
-+      shift = ilog2(offset) - ilog2(tk->cycle_interval);
-+      shift = max(0, shift);
-+      /* Bound shift to one less than what overflows tick_length */
-+      maxshift = (64 - (ilog2(ntp_tick_length()) + 1)) - 1;
-+      shift = min(shift, maxshift);
-+      while (offset >= tk->cycle_interval) {
-+              offset = logarithmic_accumulation(tk, offset, shift, clock_set);
-+              if (offset < tk->cycle_interval << shift)
-+                      shift--;
-+      }
-+      return offset;
-+}
-+
- /*
-  * timekeeping_advance - Updates the timekeeper to the current time and
-  * current NTP tick length
-@@ -2160,7 +2222,6 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
-       struct timekeeper *tk = &tk_core.shadow_timekeeper;
-       struct timekeeper *real_tk = &tk_core.timekeeper;
-       unsigned int clock_set = 0;
--      int shift = 0, maxshift;
-       u64 offset;
-       guard(raw_spinlock_irqsave)(&tk_core.lock);
-@@ -2177,24 +2238,7 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
-       if (offset < real_tk->cycle_interval && mode == TK_ADV_TICK)
-               return false;
--      /*
--       * With NO_HZ we may have to accumulate many cycle_intervals
--       * (think "ticks") worth of time at once. To do this efficiently,
--       * we calculate the largest doubling multiple of cycle_intervals
--       * that is smaller than the offset.  We then accumulate that
--       * chunk in one go, and then try to consume the next smaller
--       * doubled multiple.
--       */
--      shift = ilog2(offset) - ilog2(tk->cycle_interval);
--      shift = max(0, shift);
--      /* Bound shift to one less than what overflows tick_length */
--      maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1;
--      shift = min(shift, maxshift);
--      while (offset >= tk->cycle_interval) {
--              offset = logarithmic_accumulation(tk, offset, shift, &clock_set);
--              if (offset < tk->cycle_interval<<shift)
--                      shift--;
--      }
-+      offset = timekeeping_accumulate(tk, offset, mode, &clock_set);
-       /* Adjust the multiplier to correct NTP error */
-       timekeeping_adjust(tk, offset);
--- 
-2.39.5
-