aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott B2022-02-10 17:54:59 -0800
committerScott B2022-02-11 01:16:47 -0800
commit248c3c289b71536ece4f14f7bf753f14ce637696 (patch)
treee41d564bdfad415cd96f241d60164b4c7d10ddef
parent9b76b5b3d4d1ba39610587853b053e471e51137c (diff)
downloadaur-248c3c289b71536ece4f14f7bf753f14ce637696.tar.gz
patch: cpufreq CPPC perf freq adj
-rw-r--r--.SRCINFO2
-rw-r--r--PKGBUILD2
-rw-r--r--cpufreq-CPPC-Fix-performance-frequency-conversion.patch129
3 files changed, 133 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 859e978e68e0..98a9d050de5b 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -26,6 +26,7 @@ pkgbase = linux-xanmod-rog
source = Bluetooth-Read-codec-capabilities-only-if-supported.patch
source = Bluetooth-fix-deadlock-for-RFCOMM-sk-state-change.patch
source = Revert-XANMOD-fair-Remove-all-energy-efficiency-functions.patch
+ source = cpufreq-CPPC-Fix-performance-frequency-conversion.patch
source = udp-ipv6-optimisations-v2-net-next.patch
source = af_unix-Replace-unix_table_lock-with-per-hash-locks.patch
source = CONFIG_RCU_FAST_NO_HZ-removal-for-v5.17.patch
@@ -56,6 +57,7 @@ pkgbase = linux-xanmod-rog
sha256sums = dd01bd3f774c3a9af42b6d89f534f39c4a5f200db32cd6d4b72a29325645100e
sha256sums = a9647897e59b04cb883dcf649b3108e9397d5a6c672bc545ea0c6bb7bb30d5a9
sha256sums = 3bb1cf422c64b4eea324b71048d0bdee04b5f9132136c6a4774e5205e45c46f1
+ sha256sums = 5c6c7778bc2d873657a885272956e232138b8b4935c3a3d6b11ef1619d344b20
sha256sums = 56f8f93a38ed7236c2504c79645a33123ee7bdf3c0cbb97dfd90600df06be7dd
sha256sums = eac568d7f2b369a8a2b685fae236388c3516938000d4d6b2116b5874c4f93430
sha256sums = e74649fb883f2c8c3703c730e45119fca7126dc0599d6bc814de6dcf5a07e7cb
diff --git a/PKGBUILD b/PKGBUILD
index dbef60716f76..c821e026bb5b 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -118,6 +118,7 @@ source=("https://cdn.kernel.org/pub/linux/kernel/v${_branch}/linux-${_major}.tar
"Revert-XANMOD-fair-Remove-all-energy-efficiency-functions.patch"
# amd-pstate included in Xanmod
+ "cpufreq-CPPC-Fix-performance-frequency-conversion.patch"
# multigenerational lru included in Xanmod
# 5.17 TCP Optimizations included in Xanmod
# 5.17 TCP csum optimization included in Xanmod
@@ -180,6 +181,7 @@ sha256sums=('027d7e8988bb69ac12ee92406c3be1fe13f990b1ca2249e226225cd1573308bb'
'dd01bd3f774c3a9af42b6d89f534f39c4a5f200db32cd6d4b72a29325645100e'
'a9647897e59b04cb883dcf649b3108e9397d5a6c672bc545ea0c6bb7bb30d5a9'
'3bb1cf422c64b4eea324b71048d0bdee04b5f9132136c6a4774e5205e45c46f1'
+ '5c6c7778bc2d873657a885272956e232138b8b4935c3a3d6b11ef1619d344b20'
'56f8f93a38ed7236c2504c79645a33123ee7bdf3c0cbb97dfd90600df06be7dd'
'eac568d7f2b369a8a2b685fae236388c3516938000d4d6b2116b5874c4f93430'
'e74649fb883f2c8c3703c730e45119fca7126dc0599d6bc814de6dcf5a07e7cb'
diff --git a/cpufreq-CPPC-Fix-performance-frequency-conversion.patch b/cpufreq-CPPC-Fix-performance-frequency-conversion.patch
new file mode 100644
index 000000000000..c720750ffa97
--- /dev/null
+++ b/cpufreq-CPPC-Fix-performance-frequency-conversion.patch
@@ -0,0 +1,129 @@
+From 09ad43c40eaba6558e009d6ffd660b6feb624a7d Mon Sep 17 00:00:00 2001
+From: Pierre Gondois <Pierre.Gondois@arm.com>
+Date: Tue, 8 Feb 2022 09:01:09 +0100
+Subject: [PATCH] cpufreq: CPPC: Fix performance/frequency conversion
+
+CPUfreq governors request CPU frequencies using information
+on current CPU usage. The CPPC driver converts them to
+performance requests. Frequency targets are computed as:
+ target_freq = (util / cpu_capacity) * max_freq
+target_freq is then clamped between [policy->min, policy->max].
+
+The CPPC driver converts performance values to frequencies
+(and vice-versa) using cppc_cpufreq_perf_to_khz() and
+cppc_cpufreq_khz_to_perf(). These functions both use two different
+factors depending on the range of the input value. For
+cppc_cpufreq_khz_to_perf():
+- (NOMINAL_PERF / NOMINAL_FREQ) or
+- (LOWEST_PERF / LOWEST_FREQ)
+and for cppc_cpufreq_perf_to_khz():
+- (NOMINAL_FREQ / NOMINAL_PERF) or
+- ((NOMINAL_PERF - LOWEST_FREQ) / (NOMINAL_PERF - LOWEST_PERF))
+
+This means:
+1- the functions are not inverse for some values:
+ (perf_to_khz(khz_to_perf(x)) != x)
+2- cppc_cpufreq_perf_to_khz(LOWEST_PERF) can sometimes give
+ a different value from LOWEST_FREQ due to integer approximation
+3- it is implied that performance and frequency are proportional
+ (NOMINAL_FREQ / NOMINAL_PERF) == (LOWEST_PERF / LOWEST_FREQ)
+
+This patch changes the conversion functions to an affine function.
+This fixes the 3 points above.
+
+Suggested-by: Lukasz Luba <lukasz.luba@arm.com>
+Suggested-by: Morten Rasmussen <morten.rasmussen@arm.com>
+Signed-off-by: Pierre Gondois <Pierre.Gondois@arm.com>
+---
+ drivers/cpufreq/cppc_cpufreq.c | 43 +++++++++++++++++-----------------
+ 1 file changed, 21 insertions(+), 22 deletions(-)
+
+diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
+index db17196266e4..82d370ae6a4a 100644
+--- a/drivers/cpufreq/cppc_cpufreq.c
++++ b/drivers/cpufreq/cppc_cpufreq.c
+@@ -303,52 +303,48 @@ static u64 cppc_get_dmi_max_khz(void)
+
+ /*
+ * If CPPC lowest_freq and nominal_freq registers are exposed then we can
+- * use them to convert perf to freq and vice versa
+- *
+- * If the perf/freq point lies between Nominal and Lowest, we can treat
+- * (Low perf, Low freq) and (Nom Perf, Nom freq) as 2D co-ordinates of a line
+- * and extrapolate the rest
+- * For perf/freq > Nominal, we use the ratio perf:freq at Nominal for conversion
++ * use them to convert perf to freq and vice versa. The conversion is
++ * extrapolated as an affine function passing by the 2 points:
++ * - (Low perf, Low freq)
++ * - (Nominal perf, Nominal perf)
+ */
+ static unsigned int cppc_cpufreq_perf_to_khz(struct cppc_cpudata *cpu_data,
+ unsigned int perf)
+ {
+ struct cppc_perf_caps *caps = &cpu_data->perf_caps;
++ s64 retval, offset = 0;
+ static u64 max_khz;
+ u64 mul, div;
+
+ if (caps->lowest_freq && caps->nominal_freq) {
+- if (perf >= caps->nominal_perf) {
+- mul = caps->nominal_freq;
+- div = caps->nominal_perf;
+- } else {
+- mul = caps->nominal_freq - caps->lowest_freq;
+- div = caps->nominal_perf - caps->lowest_perf;
+- }
++ mul = caps->nominal_freq - caps->lowest_freq;
++ div = caps->nominal_perf - caps->lowest_perf;
++ offset = caps->nominal_freq - div64_u64(caps->nominal_perf * mul, div);
+ } else {
+ if (!max_khz)
+ max_khz = cppc_get_dmi_max_khz();
+ mul = max_khz;
+ div = caps->highest_perf;
+ }
+- return (u64)perf * mul / div;
++
++ retval = offset + div64_u64(perf * mul, div);
++ if (retval >= 0)
++ return retval;
++ return 0;
+ }
+
+ static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu_data,
+ unsigned int freq)
+ {
+ struct cppc_perf_caps *caps = &cpu_data->perf_caps;
++ s64 retval, offset = 0;
+ static u64 max_khz;
+ u64 mul, div;
+
+ if (caps->lowest_freq && caps->nominal_freq) {
+- if (freq >= caps->nominal_freq) {
+- mul = caps->nominal_perf;
+- div = caps->nominal_freq;
+- } else {
+- mul = caps->lowest_perf;
+- div = caps->lowest_freq;
+- }
++ mul = caps->nominal_perf - caps->lowest_perf;
++ div = caps->nominal_freq - caps->lowest_freq;
++ offset = caps->nominal_perf - div64_u64(caps->nominal_freq * mul, div);
+ } else {
+ if (!max_khz)
+ max_khz = cppc_get_dmi_max_khz();
+@@ -356,7 +352,10 @@ static unsigned int cppc_cpufreq_khz_to_perf(struct cppc_cpudata *cpu_data,
+ div = max_khz;
+ }
+
+- return (u64)freq * mul / div;
++ retval = offset + div64_u64(freq * mul, div);
++ if (retval >= 0)
++ return retval;
++ return 0;
+ }
+
+ static int cppc_cpufreq_set_target(struct cpufreq_policy *policy,
+--
+2.35.1
+