From 9669160e65e18a3e121894ab674d5c60418c398d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 16 Oct 2025 10:54:56 +0200 Subject: [PATCH] 6.1-stable patches added patches: cpuidle-governors-menu-avoid-using-invalid-recent-intervals-data.patch --- ...-using-invalid-recent-intervals-data.patch | 87 +++++++++++++++++++ queue-6.1/series | 1 + 2 files changed, 88 insertions(+) create mode 100644 queue-6.1/cpuidle-governors-menu-avoid-using-invalid-recent-intervals-data.patch diff --git a/queue-6.1/cpuidle-governors-menu-avoid-using-invalid-recent-intervals-data.patch b/queue-6.1/cpuidle-governors-menu-avoid-using-invalid-recent-intervals-data.patch new file mode 100644 index 0000000000..128d5a3749 --- /dev/null +++ b/queue-6.1/cpuidle-governors-menu-avoid-using-invalid-recent-intervals-data.patch @@ -0,0 +1,87 @@ +From fa3fa55de0d6177fdcaf6fc254f13cc8f33c3eed Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Mon, 11 Aug 2025 17:03:11 +0200 +Subject: cpuidle: governors: menu: Avoid using invalid recent intervals data + +From: Rafael J. Wysocki + +commit fa3fa55de0d6177fdcaf6fc254f13cc8f33c3eed upstream. + +Marc has reported that commit 85975daeaa4d ("cpuidle: menu: Avoid +discarding useful information") caused the number of wakeup interrupts +to increase on an idle system [1], which was not expected to happen +after merely allowing shallower idle states to be selected by the +governor in some cases. + +However, on the system in question, all of the idle states deeper than +WFI are rejected by the driver due to a firmware issue [2]. This causes +the governor to only consider the recent interval duriation data +corresponding to attempts to enter WFI that are successful and the +recent invervals table is filled with values lower than the scheduler +tick period. Consequently, the governor predicts an idle duration +below the scheduler tick period length and avoids stopping the tick +more often which leads to the observed symptom. + +Address it by modifying the governor to update the recent intervals +table also when entering the previously selected idle state fails, so +it knows that the short idle intervals might have been the minority +had the selected idle states been actually entered every time. + +Fixes: 85975daeaa4d ("cpuidle: menu: Avoid discarding useful information") +Link: https://lore.kernel.org/linux-pm/86o6sv6n94.wl-maz@kernel.org/ [1] +Link: https://lore.kernel.org/linux-pm/7ffcb716-9a1b-48c2-aaa4-469d0df7c792@arm.com/ [2] +Signed-off-by: Rafael J. Wysocki +Tested-by: Christian Loehle +Tested-by: Marc Zyngier +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/2793874.mvXUDI8C0e@rafael.j.wysocki +Cc: Sergey Senozhatsky +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpuidle/governors/menu.c | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +--- a/drivers/cpuidle/governors/menu.c ++++ b/drivers/cpuidle/governors/menu.c +@@ -158,6 +158,14 @@ static inline int performance_multiplier + + static DEFINE_PER_CPU(struct menu_device, menu_devices); + ++static void menu_update_intervals(struct menu_device *data, unsigned int interval_us) ++{ ++ /* Update the repeating-pattern data. */ ++ data->intervals[data->interval_ptr++] = interval_us; ++ if (data->interval_ptr >= INTERVALS) ++ data->interval_ptr = 0; ++} ++ + static void menu_update(struct cpuidle_driver *drv, struct cpuidle_device *dev); + + /* +@@ -288,6 +296,14 @@ static int menu_select(struct cpuidle_dr + if (data->needs_update) { + menu_update(drv, dev); + data->needs_update = 0; ++ } else if (!dev->last_residency_ns) { ++ /* ++ * This happens when the driver rejects the previously selected ++ * idle state and returns an error, so update the recent ++ * intervals table to prevent invalid information from being ++ * used going forward. ++ */ ++ menu_update_intervals(data, UINT_MAX); + } + + /* determine the expected residency time, round up */ +@@ -542,10 +558,7 @@ static void menu_update(struct cpuidle_d + + data->correction_factor[data->bucket] = new_factor; + +- /* update the repeating-pattern data */ +- data->intervals[data->interval_ptr++] = ktime_to_us(measured_ns); +- if (data->interval_ptr >= INTERVALS) +- data->interval_ptr = 0; ++ menu_update_intervals(data, ktime_to_us(measured_ns)); + } + + /** diff --git a/queue-6.1/series b/queue-6.1/series index 46b379b224..aedd655d4a 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -56,3 +56,4 @@ arm64-dts-qcom-sdm845-fix-slimbam-num-channels-ees.patch arm64-dts-ti-k3-am62a-main-fix-main-padcfg-length.patch arm64-kprobes-call-set_memory_rox-for-kprobe-page.patch arm-omap2-pm33xx-core-ix-device-node-reference-leaks-in-amx3_idle_init.patch +cpuidle-governors-menu-avoid-using-invalid-recent-intervals-data.patch -- 2.47.3