]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Aug 2025 09:04:33 +0000 (11:04 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 22 Aug 2025 09:04:33 +0000 (11:04 +0200)
added patches:
arm64-amu-use-capacity_ref_freq-to-set-amu-ratio.patch
cpufreq-cppc-set-the-frequency-used-for-computing-the-capacity.patch
cpufreq-schedutil-use-a-fixed-reference-frequency.patch
cpufreq-use-the-fixed-and-coherent-frequency-for-scaling-capacity.patch
energy_model-use-a-fixed-reference-frequency.patch
sched-fair-fix-frequency-selection-for-non-invariant-case.patch
sched-topology-add-a-new-arch_scale_freq_ref-method.patch
topology-set-capacity_freq_ref-in-all-cases.patch

queue-6.6/arm64-amu-use-capacity_ref_freq-to-set-amu-ratio.patch [new file with mode: 0644]
queue-6.6/cpufreq-cppc-set-the-frequency-used-for-computing-the-capacity.patch [new file with mode: 0644]
queue-6.6/cpufreq-schedutil-use-a-fixed-reference-frequency.patch [new file with mode: 0644]
queue-6.6/cpufreq-use-the-fixed-and-coherent-frequency-for-scaling-capacity.patch [new file with mode: 0644]
queue-6.6/energy_model-use-a-fixed-reference-frequency.patch [new file with mode: 0644]
queue-6.6/sched-fair-fix-frequency-selection-for-non-invariant-case.patch [new file with mode: 0644]
queue-6.6/sched-topology-add-a-new-arch_scale_freq_ref-method.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/topology-set-capacity_freq_ref-in-all-cases.patch [new file with mode: 0644]

diff --git a/queue-6.6/arm64-amu-use-capacity_ref_freq-to-set-amu-ratio.patch b/queue-6.6/arm64-amu-use-capacity_ref_freq-to-set-amu-ratio.patch
new file mode 100644 (file)
index 0000000..1c4b155
--- /dev/null
@@ -0,0 +1,140 @@
+From 1f023007f5e782bda19ad9104830c404fd622c5d Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 11 Dec 2023 11:48:55 +0100
+Subject: arm64/amu: Use capacity_ref_freq() to set AMU ratio
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit 1f023007f5e782bda19ad9104830c404fd622c5d upstream.
+
+Use the new capacity_ref_freq() method to set the ratio that is used by AMU for
+computing the arch_scale_freq_capacity().
+This helps to keep everything aligned using the same reference for
+computing CPUs capacity.
+
+The default value of the ratio (stored in per_cpu(arch_max_freq_scale))
+ensures that arch_scale_freq_capacity() returns max capacity until it is
+set to its correct value with the cpu capacity and capacity_ref_freq().
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20231211104855.558096-8-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kernel/topology.c  |   26 +++++++++++++-------------
+ drivers/base/arch_topology.c  |   12 +++++++++++-
+ include/linux/arch_topology.h |    1 +
+ 3 files changed, 25 insertions(+), 14 deletions(-)
+
+--- a/arch/arm64/kernel/topology.c
++++ b/arch/arm64/kernel/topology.c
+@@ -82,7 +82,12 @@ int __init parse_acpi_topology(void)
+ #undef pr_fmt
+ #define pr_fmt(fmt) "AMU: " fmt
+-static DEFINE_PER_CPU_READ_MOSTLY(unsigned long, arch_max_freq_scale);
++/*
++ * Ensure that amu_scale_freq_tick() will return SCHED_CAPACITY_SCALE until
++ * the CPU capacity and its associated frequency have been correctly
++ * initialized.
++ */
++static DEFINE_PER_CPU_READ_MOSTLY(unsigned long, arch_max_freq_scale) =  1UL << (2 * SCHED_CAPACITY_SHIFT);
+ static DEFINE_PER_CPU(u64, arch_const_cycles_prev);
+ static DEFINE_PER_CPU(u64, arch_core_cycles_prev);
+ static cpumask_var_t amu_fie_cpus;
+@@ -112,14 +117,14 @@ static inline bool freq_counters_valid(i
+       return true;
+ }
+-static int freq_inv_set_max_ratio(int cpu, u64 max_rate, u64 ref_rate)
++void freq_inv_set_max_ratio(int cpu, u64 max_rate)
+ {
+-      u64 ratio;
++      u64 ratio, ref_rate = arch_timer_get_rate();
+       if (unlikely(!max_rate || !ref_rate)) {
+-              pr_debug("CPU%d: invalid maximum or reference frequency.\n",
++              WARN_ONCE(1, "CPU%d: invalid maximum or reference frequency.\n",
+                        cpu);
+-              return -EINVAL;
++              return;
+       }
+       /*
+@@ -139,12 +144,10 @@ static int freq_inv_set_max_ratio(int cp
+       ratio = div64_u64(ratio, max_rate);
+       if (!ratio) {
+               WARN_ONCE(1, "Reference frequency too low.\n");
+-              return -EINVAL;
++              return;
+       }
+-      per_cpu(arch_max_freq_scale, cpu) = (unsigned long)ratio;
+-
+-      return 0;
++      WRITE_ONCE(per_cpu(arch_max_freq_scale, cpu), (unsigned long)ratio);
+ }
+ static void amu_scale_freq_tick(void)
+@@ -195,10 +198,7 @@ static void amu_fie_setup(const struct c
+               return;
+       for_each_cpu(cpu, cpus) {
+-              if (!freq_counters_valid(cpu) ||
+-                  freq_inv_set_max_ratio(cpu,
+-                                         cpufreq_get_hw_max_freq(cpu) * 1000ULL,
+-                                         arch_timer_get_rate()))
++              if (!freq_counters_valid(cpu))
+                       return;
+       }
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -344,6 +344,10 @@ bool __init topology_parse_cpu_capacity(
+       return !ret;
+ }
++void __weak freq_inv_set_max_ratio(int cpu, u64 max_rate)
++{
++}
++
+ #ifdef CONFIG_ACPI_CPPC_LIB
+ #include <acpi/cppc_acpi.h>
+@@ -381,6 +385,9 @@ void topology_init_cpu_capacity_cppc(voi
+       }
+       for_each_possible_cpu(cpu) {
++              freq_inv_set_max_ratio(cpu,
++                                     per_cpu(capacity_freq_ref, cpu) * HZ_PER_KHZ);
++
+               capacity = raw_capacity[cpu];
+               capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
+                                    capacity_scale);
+@@ -422,8 +429,11 @@ init_cpu_capacity_callback(struct notifi
+       cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
+-      for_each_cpu(cpu, policy->related_cpus)
++      for_each_cpu(cpu, policy->related_cpus) {
+               per_cpu(capacity_freq_ref, cpu) = policy->cpuinfo.max_freq;
++              freq_inv_set_max_ratio(cpu,
++                                     per_cpu(capacity_freq_ref, cpu) * HZ_PER_KHZ);
++      }
+       if (cpumask_empty(cpus_to_visit)) {
+               topology_normalize_cpu_scale();
+--- a/include/linux/arch_topology.h
++++ b/include/linux/arch_topology.h
+@@ -99,6 +99,7 @@ void update_siblings_masks(unsigned int
+ void remove_cpu_topology(unsigned int cpuid);
+ void reset_cpu_topology(void);
+ int parse_acpi_topology(void);
++void freq_inv_set_max_ratio(int cpu, u64 max_rate);
+ #endif
+ #endif /* _LINUX_ARCH_TOPOLOGY_H_ */
diff --git a/queue-6.6/cpufreq-cppc-set-the-frequency-used-for-computing-the-capacity.patch b/queue-6.6/cpufreq-cppc-set-the-frequency-used-for-computing-the-capacity.patch
new file mode 100644 (file)
index 0000000..8adbd33
--- /dev/null
@@ -0,0 +1,66 @@
+From 5477fa249b56c59c3baa1b237bf083cffa64c84a Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 11 Dec 2023 11:48:54 +0100
+Subject: cpufreq/cppc: Set the frequency used for computing the capacity
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit 5477fa249b56c59c3baa1b237bf083cffa64c84a upstream.
+
+Save the frequency associated to the performance that has been used when
+initializing the capacity of CPUs.
+
+Also, cppc cpufreq driver can register an artificial energy model. In such
+case, it needs the frequency for this compute capacity.
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Pierre Gondois <pierre.gondois@arm.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://lore.kernel.org/r/20231211104855.558096-7-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/arch_topology.c |   15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -349,6 +349,7 @@ bool __init topology_parse_cpu_capacity(
+ void topology_init_cpu_capacity_cppc(void)
+ {
++      u64 capacity, capacity_scale = 0;
+       struct cppc_perf_caps perf_caps;
+       int cpu;
+@@ -365,6 +366,10 @@ void topology_init_cpu_capacity_cppc(voi
+                   (perf_caps.highest_perf >= perf_caps.nominal_perf) &&
+                   (perf_caps.highest_perf >= perf_caps.lowest_perf)) {
+                       raw_capacity[cpu] = perf_caps.highest_perf;
++                      capacity_scale = max_t(u64, capacity_scale, raw_capacity[cpu]);
++
++                      per_cpu(capacity_freq_ref, cpu) = cppc_perf_to_khz(&perf_caps, raw_capacity[cpu]);
++
+                       pr_debug("cpu_capacity: CPU%d cpu_capacity=%u (raw).\n",
+                                cpu, raw_capacity[cpu]);
+                       continue;
+@@ -375,7 +380,15 @@ void topology_init_cpu_capacity_cppc(voi
+               goto exit;
+       }
+-      topology_normalize_cpu_scale();
++      for_each_possible_cpu(cpu) {
++              capacity = raw_capacity[cpu];
++              capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
++                                   capacity_scale);
++              topology_set_cpu_scale(cpu, capacity);
++              pr_debug("cpu_capacity: CPU%d cpu_capacity=%lu\n",
++                      cpu, topology_get_cpu_scale(cpu));
++      }
++
+       schedule_work(&update_topology_flags_work);
+       pr_debug("cpu_capacity: cpu_capacity initialization done\n");
diff --git a/queue-6.6/cpufreq-schedutil-use-a-fixed-reference-frequency.patch b/queue-6.6/cpufreq-schedutil-use-a-fixed-reference-frequency.patch
new file mode 100644 (file)
index 0000000..5a2096b
--- /dev/null
@@ -0,0 +1,77 @@
+From b3edde44e5d4504c23a176819865cd603fd16d6c Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 11 Dec 2023 11:48:51 +0100
+Subject: cpufreq/schedutil: Use a fixed reference frequency
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit b3edde44e5d4504c23a176819865cd603fd16d6c upstream.
+
+cpuinfo.max_freq can change at runtime because of boost as an example. This
+implies that the value could be different than the one that has been
+used when computing the capacity of a CPU.
+
+The new arch_scale_freq_ref() returns a fixed and coherent reference
+frequency that can be used when computing a frequency based on utilization.
+
+Use this arch_scale_freq_ref() when available and fallback to
+policy otherwise.
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Lukasz Luba <lukasz.luba@arm.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Acked-by: Rafael J. Wysocki <rafael@kernel.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Link: https://lore.kernel.org/r/20231211104855.558096-4-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sched/cpufreq_schedutil.c |   26 ++++++++++++++++++++++++--
+ 1 file changed, 24 insertions(+), 2 deletions(-)
+
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -138,6 +138,28 @@ static void sugov_deferred_update(struct
+ }
+ /**
++ * get_capacity_ref_freq - get the reference frequency that has been used to
++ * correlate frequency and compute capacity for a given cpufreq policy. We use
++ * the CPU managing it for the arch_scale_freq_ref() call in the function.
++ * @policy: the cpufreq policy of the CPU in question.
++ *
++ * Return: the reference CPU frequency to compute a capacity.
++ */
++static __always_inline
++unsigned long get_capacity_ref_freq(struct cpufreq_policy *policy)
++{
++      unsigned int freq = arch_scale_freq_ref(policy->cpu);
++
++      if (freq)
++              return freq;
++
++      if (arch_scale_freq_invariant())
++              return policy->cpuinfo.max_freq;
++
++      return policy->cur;
++}
++
++/**
+  * get_next_freq - Compute a new frequency for a given cpufreq policy.
+  * @sg_policy: schedutil policy object to compute the new frequency for.
+  * @util: Current CPU utilization.
+@@ -163,9 +185,9 @@ static unsigned int get_next_freq(struct
+                                 unsigned long util, unsigned long max)
+ {
+       struct cpufreq_policy *policy = sg_policy->policy;
+-      unsigned int freq = arch_scale_freq_invariant() ?
+-                              policy->cpuinfo.max_freq : policy->cur;
++      unsigned int freq;
++      freq = get_capacity_ref_freq(policy);
+       freq = map_util_freq(util, freq, max);
+       if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update)
diff --git a/queue-6.6/cpufreq-use-the-fixed-and-coherent-frequency-for-scaling-capacity.patch b/queue-6.6/cpufreq-use-the-fixed-and-coherent-frequency-for-scaling-capacity.patch
new file mode 100644 (file)
index 0000000..da4e0cf
--- /dev/null
@@ -0,0 +1,63 @@
+From 599457ba15403037b489fe536266a3d5f9efaed7 Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 11 Dec 2023 11:48:50 +0100
+Subject: cpufreq: Use the fixed and coherent frequency for scaling capacity
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit 599457ba15403037b489fe536266a3d5f9efaed7 upstream.
+
+cpuinfo.max_freq can change at runtime because of boost as an example. This
+implies that the value could be different from the frequency that has been
+used to compute the capacity of a CPU.
+
+The new arch_scale_freq_ref() returns a fixed and coherent frequency
+that can be used to compute the capacity for a given frequency.
+
+[ Also fix a arch_set_freq_scale()  newline style wart in <linux/cpufreq.h>. ]
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Lukasz Luba <lukasz.luba@arm.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Acked-by: Rafael J. Wysocki <rafael@kernel.org>
+Link: https://lore.kernel.org/r/20231211104855.558096-3-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cpufreq/cpufreq.c |    4 ++--
+ include/linux/cpufreq.h   |    1 +
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -454,7 +454,7 @@ void cpufreq_freq_transition_end(struct
+       arch_set_freq_scale(policy->related_cpus,
+                           policy->cur,
+-                          policy->cpuinfo.max_freq);
++                          arch_scale_freq_ref(policy->cpu));
+       spin_lock(&policy->transition_lock);
+       policy->transition_ongoing = false;
+@@ -2205,7 +2205,7 @@ unsigned int cpufreq_driver_fast_switch(
+       policy->cur = freq;
+       arch_set_freq_scale(policy->related_cpus, freq,
+-                          policy->cpuinfo.max_freq);
++                          arch_scale_freq_ref(policy->cpu));
+       cpufreq_stats_record_transition(policy, freq);
+       if (trace_cpu_frequency_enabled()) {
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -1245,6 +1245,7 @@ void arch_set_freq_scale(const struct cp
+ {
+ }
+ #endif
++
+ /* the following are really really optional */
+ extern struct freq_attr cpufreq_freq_attr_scaling_available_freqs;
+ extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs;
diff --git a/queue-6.6/energy_model-use-a-fixed-reference-frequency.patch b/queue-6.6/energy_model-use-a-fixed-reference-frequency.patch
new file mode 100644 (file)
index 0000000..b1342f4
--- /dev/null
@@ -0,0 +1,59 @@
+From 15cbbd1d317e07b4e5c6aca5d4c5579539a82784 Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 11 Dec 2023 11:48:52 +0100
+Subject: energy_model: Use a fixed reference frequency
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit 15cbbd1d317e07b4e5c6aca5d4c5579539a82784 upstream.
+
+The last item of a performance domain is not always the performance point
+that has been used to compute CPU's capacity. This can lead to different
+target frequency compared with other part of the system like schedutil and
+would result in wrong energy estimation.
+
+A new arch_scale_freq_ref() is available to return a fixed and coherent
+frequency reference that can be used when computing the CPU's frequency
+for an level of utilization. Use this function to get this reference
+frequency.
+
+Energy model is never used without defining arch_scale_freq_ref() but
+can be compiled. Define a default arch_scale_freq_ref() returning 0
+in such case.
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Lukasz Luba <lukasz.luba@arm.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Link: https://lore.kernel.org/r/20231211104855.558096-5-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/energy_model.h |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/include/linux/energy_model.h
++++ b/include/linux/energy_model.h
+@@ -224,7 +224,7 @@ static inline unsigned long em_cpu_energ
+                               unsigned long max_util, unsigned long sum_util,
+                               unsigned long allowed_cpu_cap)
+ {
+-      unsigned long freq, scale_cpu;
++      unsigned long freq, ref_freq, scale_cpu;
+       struct em_perf_state *ps;
+       int cpu;
+@@ -241,10 +241,10 @@ static inline unsigned long em_cpu_energ
+        */
+       cpu = cpumask_first(to_cpumask(pd->cpus));
+       scale_cpu = arch_scale_cpu_capacity(cpu);
+-      ps = &pd->table[pd->nr_perf_states - 1];
++      ref_freq = arch_scale_freq_ref(cpu);
+       max_util = min(max_util, allowed_cpu_cap);
+-      freq = map_util_freq(max_util, ps->frequency, scale_cpu);
++      freq = map_util_freq(max_util, ref_freq, scale_cpu);
+       /*
+        * Find the lowest performance state of the Energy Model above the
diff --git a/queue-6.6/sched-fair-fix-frequency-selection-for-non-invariant-case.patch b/queue-6.6/sched-fair-fix-frequency-selection-for-non-invariant-case.patch
new file mode 100644 (file)
index 0000000..9499821
--- /dev/null
@@ -0,0 +1,60 @@
+From e37617c8e53a1f7fcba6d5e1041f4fd8a2425c27 Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Sun, 14 Jan 2024 19:36:00 +0100
+Subject: sched/fair: Fix frequency selection for non-invariant case
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit e37617c8e53a1f7fcba6d5e1041f4fd8a2425c27 upstream.
+
+Linus reported a ~50% performance regression on single-threaded
+workloads on his AMD Ryzen system, and bisected it to:
+
+  9c0b4bb7f630 ("sched/cpufreq: Rework schedutil governor performance estimation")
+
+When frequency invariance is not enabled, get_capacity_ref_freq(policy)
+is supposed to return the current frequency and the performance margin
+applied by map_util_perf(), enabling the utilization to go above the
+maximum compute capacity and to select a higher frequency than the current one.
+
+After the changes in 9c0b4bb7f630, the performance margin was applied
+earlier in the path to take into account utilization clampings and
+we couldn't get a utilization higher than the maximum compute capacity,
+and the CPU remained 'stuck' at lower frequencies.
+
+To fix this, we must use a frequency above the current frequency to
+get a chance to select a higher OPP when the current one becomes fully used.
+Apply the same margin and return a frequency 25% higher than the current
+one in order to switch to the next OPP before we fully use the CPU
+at the current one.
+
+[ mingo: Clarified the changelog. ]
+
+Fixes: 9c0b4bb7f630 ("sched/cpufreq: Rework schedutil governor performance estimation")
+Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
+Bisected-by: Linus Torvalds <torvalds@linux-foundation.org>
+Reported-by: Wyes Karny <wkarny@gmail.com>
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Wyes Karny <wkarny@gmail.com>
+Link: https://lore.kernel.org/r/20240114183600.135316-1-vincent.guittot@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sched/cpufreq_schedutil.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/kernel/sched/cpufreq_schedutil.c
++++ b/kernel/sched/cpufreq_schedutil.c
+@@ -156,7 +156,11 @@ unsigned long get_capacity_ref_freq(stru
+       if (arch_scale_freq_invariant())
+               return policy->cpuinfo.max_freq;
+-      return policy->cur;
++      /*
++       * Apply a 25% margin so that we select a higher frequency than
++       * the current one before the CPU is fully busy:
++       */
++      return policy->cur + (policy->cur >> 2);
+ }
+ /**
diff --git a/queue-6.6/sched-topology-add-a-new-arch_scale_freq_ref-method.patch b/queue-6.6/sched-topology-add-a-new-arch_scale_freq_ref-method.patch
new file mode 100644 (file)
index 0000000..b46b8f8
--- /dev/null
@@ -0,0 +1,202 @@
+From 9942cb22ea458c34fa17b73d143ea32d4df1caca Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Mon, 11 Dec 2023 11:48:49 +0100
+Subject: sched/topology: Add a new arch_scale_freq_ref() method
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit 9942cb22ea458c34fa17b73d143ea32d4df1caca upstream.
+
+Create a new method to get a unique and fixed max frequency. Currently
+cpuinfo.max_freq or the highest (or last) state of performance domain are
+used as the max frequency when computing the frequency for a level of
+utilization, but:
+
+  - cpuinfo_max_freq can change at runtime. boost is one example of
+    such change.
+
+  - cpuinfo.max_freq and last item of the PD can be different leading to
+    different results between cpufreq and energy model.
+
+We need to save the reference frequency that has been used when computing
+the CPUs capacity and use this fixed and coherent value to convert between
+frequency and CPU's capacity.
+
+In fact, we already save the frequency that has been used when computing
+the capacity of each CPU. We extend the precision to save kHz instead of
+MHz currently and we modify the type to be aligned with other variables
+used when converting frequency to capacity and the other way.
+
+[ mingo: Minor edits. ]
+
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: Lukasz Luba <lukasz.luba@arm.com>
+Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Link: https://lore.kernel.org/r/20231211104855.558096-2-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/include/asm/topology.h   |    1 +
+ arch/arm64/include/asm/topology.h |    1 +
+ arch/riscv/include/asm/topology.h |    1 +
+ drivers/base/arch_topology.c      |   29 ++++++++++++++---------------
+ include/linux/arch_topology.h     |    7 +++++++
+ include/linux/sched/topology.h    |    8 ++++++++
+ 6 files changed, 32 insertions(+), 15 deletions(-)
+
+--- a/arch/arm/include/asm/topology.h
++++ b/arch/arm/include/asm/topology.h
+@@ -13,6 +13,7 @@
+ #define arch_set_freq_scale topology_set_freq_scale
+ #define arch_scale_freq_capacity topology_get_freq_scale
+ #define arch_scale_freq_invariant topology_scale_freq_invariant
++#define arch_scale_freq_ref topology_get_freq_ref
+ #endif
+ /* Replace task scheduler's default cpu-invariant accounting */
+--- a/arch/arm64/include/asm/topology.h
++++ b/arch/arm64/include/asm/topology.h
+@@ -23,6 +23,7 @@ void update_freq_counters_refs(void);
+ #define arch_set_freq_scale topology_set_freq_scale
+ #define arch_scale_freq_capacity topology_get_freq_scale
+ #define arch_scale_freq_invariant topology_scale_freq_invariant
++#define arch_scale_freq_ref topology_get_freq_ref
+ #ifdef CONFIG_ACPI_CPPC_LIB
+ #define arch_init_invariance_cppc topology_init_cpu_capacity_cppc
+--- a/arch/riscv/include/asm/topology.h
++++ b/arch/riscv/include/asm/topology.h
+@@ -9,6 +9,7 @@
+ #define arch_set_freq_scale           topology_set_freq_scale
+ #define arch_scale_freq_capacity      topology_get_freq_scale
+ #define arch_scale_freq_invariant     topology_scale_freq_invariant
++#define arch_scale_freq_ref           topology_get_freq_ref
+ /* Replace task scheduler's default cpu-invariant accounting */
+ #define arch_scale_cpu_capacity       topology_get_cpu_scale
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -19,6 +19,7 @@
+ #include <linux/init.h>
+ #include <linux/rcupdate.h>
+ #include <linux/sched.h>
++#include <linux/units.h>
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/thermal_pressure.h>
+@@ -26,7 +27,8 @@
+ static DEFINE_PER_CPU(struct scale_freq_data __rcu *, sft_data);
+ static struct cpumask scale_freq_counters_mask;
+ static bool scale_freq_invariant;
+-static DEFINE_PER_CPU(u32, freq_factor) = 1;
++DEFINE_PER_CPU(unsigned long, capacity_freq_ref) = 1;
++EXPORT_PER_CPU_SYMBOL_GPL(capacity_freq_ref);
+ static bool supports_scale_freq_counters(const struct cpumask *cpus)
+ {
+@@ -170,9 +172,9 @@ DEFINE_PER_CPU(unsigned long, thermal_pr
+  * operating on stale data when hot-plug is used for some CPUs. The
+  * @capped_freq reflects the currently allowed max CPUs frequency due to
+  * thermal capping. It might be also a boost frequency value, which is bigger
+- * than the internal 'freq_factor' max frequency. In such case the pressure
+- * value should simply be removed, since this is an indication that there is
+- * no thermal throttling. The @capped_freq must be provided in kHz.
++ * than the internal 'capacity_freq_ref' max frequency. In such case the
++ * pressure value should simply be removed, since this is an indication that
++ * there is no thermal throttling. The @capped_freq must be provided in kHz.
+  */
+ void topology_update_thermal_pressure(const struct cpumask *cpus,
+                                     unsigned long capped_freq)
+@@ -183,10 +185,7 @@ void topology_update_thermal_pressure(co
+       cpu = cpumask_first(cpus);
+       max_capacity = arch_scale_cpu_capacity(cpu);
+-      max_freq = per_cpu(freq_factor, cpu);
+-
+-      /* Convert to MHz scale which is used in 'freq_factor' */
+-      capped_freq /= 1000;
++      max_freq = arch_scale_freq_ref(cpu);
+       /*
+        * Handle properly the boost frequencies, which should simply clean
+@@ -279,13 +278,13 @@ void topology_normalize_cpu_scale(void)
+       capacity_scale = 1;
+       for_each_possible_cpu(cpu) {
+-              capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
++              capacity = raw_capacity[cpu] * per_cpu(capacity_freq_ref, cpu);
+               capacity_scale = max(capacity, capacity_scale);
+       }
+       pr_debug("cpu_capacity: capacity_scale=%llu\n", capacity_scale);
+       for_each_possible_cpu(cpu) {
+-              capacity = raw_capacity[cpu] * per_cpu(freq_factor, cpu);
++              capacity = raw_capacity[cpu] * per_cpu(capacity_freq_ref, cpu);
+               capacity = div64_u64(capacity << SCHED_CAPACITY_SHIFT,
+                       capacity_scale);
+               topology_set_cpu_scale(cpu, capacity);
+@@ -321,15 +320,15 @@ bool __init topology_parse_cpu_capacity(
+                       cpu_node, raw_capacity[cpu]);
+               /*
+-               * Update freq_factor for calculating early boot cpu capacities.
++               * Update capacity_freq_ref for calculating early boot CPU capacities.
+                * For non-clk CPU DVFS mechanism, there's no way to get the
+                * frequency value now, assuming they are running at the same
+-               * frequency (by keeping the initial freq_factor value).
++               * frequency (by keeping the initial capacity_freq_ref value).
+                */
+               cpu_clk = of_clk_get(cpu_node, 0);
+               if (!PTR_ERR_OR_ZERO(cpu_clk)) {
+-                      per_cpu(freq_factor, cpu) =
+-                              clk_get_rate(cpu_clk) / 1000;
++                      per_cpu(capacity_freq_ref, cpu) =
++                              clk_get_rate(cpu_clk) / HZ_PER_KHZ;
+                       clk_put(cpu_clk);
+               }
+       } else {
+@@ -411,7 +410,7 @@ init_cpu_capacity_callback(struct notifi
+       cpumask_andnot(cpus_to_visit, cpus_to_visit, policy->related_cpus);
+       for_each_cpu(cpu, policy->related_cpus)
+-              per_cpu(freq_factor, cpu) = policy->cpuinfo.max_freq / 1000;
++              per_cpu(capacity_freq_ref, cpu) = policy->cpuinfo.max_freq;
+       if (cpumask_empty(cpus_to_visit)) {
+               topology_normalize_cpu_scale();
+--- a/include/linux/arch_topology.h
++++ b/include/linux/arch_topology.h
+@@ -27,6 +27,13 @@ static inline unsigned long topology_get
+ void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity);
++DECLARE_PER_CPU(unsigned long, capacity_freq_ref);
++
++static inline unsigned long topology_get_freq_ref(int cpu)
++{
++      return per_cpu(capacity_freq_ref, cpu);
++}
++
+ DECLARE_PER_CPU(unsigned long, arch_freq_scale);
+ static inline unsigned long topology_get_freq_scale(int cpu)
+--- a/include/linux/sched/topology.h
++++ b/include/linux/sched/topology.h
+@@ -275,6 +275,14 @@ void arch_update_thermal_pressure(const
+ { }
+ #endif
++#ifndef arch_scale_freq_ref
++static __always_inline
++unsigned int arch_scale_freq_ref(int cpu)
++{
++      return 0;
++}
++#endif
++
+ static inline int task_node(const struct task_struct *p)
+ {
+       return cpu_to_node(task_cpu(p));
index 470342081ef84ca0dc1c9cc88062c31ac7a8be56..0b982c5690eb6cfb234c1d0a7e60486bbe7a0dfe 100644 (file)
@@ -468,3 +468,11 @@ pm-runtime-simplify-pm_runtime_get_if_active-usage.patch
 pm-runtime-take-active-children-into-account-in-pm_runtime_get_if_in_use.patch
 ata-libata-scsi-return-aborted-command-when-missing-sense-and-result-tf.patch
 kbuild-userprogs-use-correct-linker-when-mixing-clang-and-gnu-ld.patch
+sched-topology-add-a-new-arch_scale_freq_ref-method.patch
+cpufreq-use-the-fixed-and-coherent-frequency-for-scaling-capacity.patch
+cpufreq-schedutil-use-a-fixed-reference-frequency.patch
+energy_model-use-a-fixed-reference-frequency.patch
+cpufreq-cppc-set-the-frequency-used-for-computing-the-capacity.patch
+arm64-amu-use-capacity_ref_freq-to-set-amu-ratio.patch
+topology-set-capacity_freq_ref-in-all-cases.patch
+sched-fair-fix-frequency-selection-for-non-invariant-case.patch
diff --git a/queue-6.6/topology-set-capacity_freq_ref-in-all-cases.patch b/queue-6.6/topology-set-capacity_freq_ref-in-all-cases.patch
new file mode 100644 (file)
index 0000000..69ac963
--- /dev/null
@@ -0,0 +1,66 @@
+From 98323e9d70172f1b46d1cadb20d6c54abf62870d Mon Sep 17 00:00:00 2001
+From: Vincent Guittot <vincent.guittot@linaro.org>
+Date: Wed, 17 Jan 2024 20:05:45 +0100
+Subject: topology: Set capacity_freq_ref in all cases
+
+From: Vincent Guittot <vincent.guittot@linaro.org>
+
+commit 98323e9d70172f1b46d1cadb20d6c54abf62870d upstream.
+
+If "capacity-dmips-mhz" is not set, raw_capacity is null and we skip the
+normalization step which includes setting per_cpu capacity_freq_ref.
+Always register the notifier but skip the capacity normalization if
+raw_capacity is null.
+
+Fixes: 9942cb22ea45 ("sched/topology: Add a new arch_scale_freq_ref() method")
+Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
+Acked-by: Sudeep Holla <sudeep.holla@arm.com>
+Tested-by: Pierre Gondois <pierre.gondois@arm.com>
+Tested-by: Mark Brown <broonie@kernel.org>
+Tested-by: Paul Barker <paul.barker.ct@bp.renesas.com>
+Reviewed-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Tested-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Link: https://lore.kernel.org/r/20240117190545.596057-1-vincent.guittot@linaro.org
+Stable-dep-of: e37617c8e53a ("sched/fair: Fix frequency selection for non-invariant case")
+Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/arch_topology.c |   13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+--- a/drivers/base/arch_topology.c
++++ b/drivers/base/arch_topology.c
+@@ -417,9 +417,6 @@ init_cpu_capacity_callback(struct notifi
+       struct cpufreq_policy *policy = data;
+       int cpu;
+-      if (!raw_capacity)
+-              return 0;
+-
+       if (val != CPUFREQ_CREATE_POLICY)
+               return 0;
+@@ -436,9 +433,11 @@ init_cpu_capacity_callback(struct notifi
+       }
+       if (cpumask_empty(cpus_to_visit)) {
+-              topology_normalize_cpu_scale();
+-              schedule_work(&update_topology_flags_work);
+-              free_raw_capacity();
++              if (raw_capacity) {
++                      topology_normalize_cpu_scale();
++                      schedule_work(&update_topology_flags_work);
++                      free_raw_capacity();
++              }
+               pr_debug("cpu_capacity: parsing done\n");
+               schedule_work(&parsing_done_work);
+       }
+@@ -458,7 +457,7 @@ static int __init register_cpufreq_notif
+        * On ACPI-based systems skip registering cpufreq notifier as cpufreq
+        * information is not needed for cpu capacity initialization.
+        */
+-      if (!acpi_disabled || !raw_capacity)
++      if (!acpi_disabled)
+               return -EINVAL;
+       if (!alloc_cpumask_var(&cpus_to_visit, GFP_KERNEL))