From: Sasha Levin Date: Tue, 8 Apr 2025 01:10:01 +0000 (-0400) Subject: Drop timekeeping-fix-possible-inconsistencies-in-_coarse-.patch X-Git-Tag: v5.4.292~67 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a5b3c1ed27e6e855e927b0d6d5ac938fb993a7be;p=thirdparty%2Fkernel%2Fstable-queue.git Drop timekeeping-fix-possible-inconsistencies-in-_coarse-.patch Signed-off-by: Sasha Levin --- diff --git a/queue-6.13/series b/queue-6.13/series index e68fbeca1c..079a893966 100644 --- a/queue-6.13/series +++ b/queue-6.13/series @@ -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 index 114ffa3366..0000000000 --- a/queue-6.13/timekeeping-fix-possible-inconsistencies-in-_coarse-.patch +++ /dev/null @@ -1,219 +0,0 @@ -From 0e80b7b345f17792f3727fba372d9560f4a79fd4 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 20 Mar 2025 13:03:00 -0700 -Subject: timekeeping: Fix possible inconsistencies in _COARSE clockids - -From: John Stultz - -[ 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 -Signed-off-by: John Stultz -Signed-off-by: Thomas Gleixner -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 ---- - 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< -Date: Thu, 20 Mar 2025 13:03:00 -0700 -Subject: timekeeping: Fix possible inconsistencies in _COARSE clockids - -From: John Stultz - -[ 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 -Signed-off-by: John Stultz -Signed-off-by: Thomas Gleixner -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 ---- - 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<