Backport the following patches: cpufreq: change '.set_boost' to act on one policy cpufreq: CPPC: add SW BOOST support --- kernel.spec | 5 +- ...ange-.set_boost-to-act-on-one-policy.patch | 186 ++++++++++++++++++ ...63-cpufreq-CPPC-add-SW-BOOST-support.patch | 142 +++++++++++++ series.conf | 2 + 4 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 patches/0362-cpufreq-change-.set_boost-to-act-on-one-policy.patch create mode 100644 patches/0363-cpufreq-CPPC-add-SW-BOOST-support.patch
diff --git a/kernel.spec b/kernel.spec index 39fc740d35f6..afb398809fbb 100644 --- a/kernel.spec +++ b/kernel.spec @@ -32,7 +32,7 @@
Name: kernel Version: 4.19.90 -Release: %{hulkrelease}.0244 +Release: %{hulkrelease}.0245 Summary: Linux Kernel License: GPLv2 URL: http://www.kernel.org/ @@ -850,6 +850,9 @@ fi
%changelog
+* Thu Nov 16 2023 Yu Liao liaoyu15@huawei.com - 4.19.90-2311.3.0.0245 +- Backport cpu turbo patches + * Wed Nov 15 2023 Luo Shengwei luoshengwei@huawei.com - 4.19.90-2311.3.0.0244 - !2803 drivers/gmjstcm: fix a dev_err() call in spi tcm device probe - !2841 drm/qxl: fix UAF on handle creation diff --git a/patches/0362-cpufreq-change-.set_boost-to-act-on-one-policy.patch b/patches/0362-cpufreq-change-.set_boost-to-act-on-one-policy.patch new file mode 100644 index 000000000000..83a5195807bb --- /dev/null +++ b/patches/0362-cpufreq-change-.set_boost-to-act-on-one-policy.patch @@ -0,0 +1,186 @@ +From a93e5e087b753c9fe954e4a82ae1224ba56732d0 Mon Sep 17 00:00:00 2001 +From: Xiongfeng Wang wangxiongfeng2@huawei.com +Date: Sat, 30 May 2020 10:08:30 +0800 +Subject: [PATCH openEuler-1.0-LTS 1/2] cpufreq: change '.set_boost' to act on + one policy + +mainline inclusion +from mainline-v5.8-rc1 +commit cf6fada71543ceea0f6228ffdc0b85778f3f5a6e +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I88RXU +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... + +-------------------------------- + +Macro 'for_each_active_policy()' is defined internally. To avoid some +cpufreq driver needing this macro to iterate over all the policies in +'.set_boost' callback, we redefine '.set_boost' to act on only one +policy and pass the policy as an argument. + +'cpufreq_boost_trigger_state()' iterates over all the policies to set +boost for the system. + +This is preparation for adding SW BOOST support for CPPC. + +To protect Boost enable/disable by sysfs from CPU online/offline, +add 'cpu_hotplug_lock' before calling '.set_boost' for each CPU. + +Also move the lock from 'set_boost()' to 'store_cpb()' in +acpi_cpufreq. + +Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com +Suggested-by: Viresh Kumar viresh.kumar@linaro.org +Acked-by: Viresh Kumar viresh.kumar@linaro.org +[ rjw: Subject & changelog ] +Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com + +Conflicts: + drivers/cpufreq/cpufreq.c + +Signed-off-by: Yu Liao liaoyu15@huawei.com +--- + drivers/cpufreq/acpi-cpufreq.c | 14 ++++---- + drivers/cpufreq/cpufreq.c | 58 +++++++++++++++++++--------------- + include/linux/cpufreq.h | 2 +- + 3 files changed, 42 insertions(+), 32 deletions(-) + +diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c +index ce0a51849f66..189c7c9e2641 100644 +--- a/drivers/cpufreq/acpi-cpufreq.c ++++ b/drivers/cpufreq/acpi-cpufreq.c +@@ -147,12 +147,12 @@ static void boost_set_msr_each(void *p_en) + boost_set_msr(enable); + } + +-static int set_boost(int val) ++static int set_boost(struct cpufreq_policy *policy, int val) + { +- get_online_cpus(); +- on_each_cpu(boost_set_msr_each, (void *)(long)val, 1); +- put_online_cpus(); +- pr_debug("Core Boosting %sabled.\n", val ? "en" : "dis"); ++ on_each_cpu_mask(policy->cpus, boost_set_msr_each, ++ (void *)(long)val, 1); ++ pr_debug("CPU %*pbl: Core Boosting %sabled.\n", ++ cpumask_pr_args(policy->cpus), val ? "en" : "dis"); + + return 0; + } +@@ -183,7 +183,9 @@ static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf, + if (ret || val > 1) + return -EINVAL; + +- set_boost(val); ++ get_online_cpus(); ++ set_boost(policy, val); ++ put_online_cpus(); + + return count; + } +diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c +index 99ca9c50a88f..49ed22b45fb7 100644 +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -2347,34 +2347,32 @@ EXPORT_SYMBOL(cpufreq_update_policy); + /********************************************************************* + * BOOST * + *********************************************************************/ +-static int cpufreq_boost_set_sw(int state) ++static int cpufreq_boost_set_sw(struct cpufreq_policy *policy, int state) + { +- struct cpufreq_policy *policy; + int ret = -EINVAL; + +- for_each_active_policy(policy) { +- if (!policy->freq_table) +- continue; +- +- ret = cpufreq_frequency_table_cpuinfo(policy, +- policy->freq_table); +- if (ret) { +- pr_err("%s: Policy frequency update failed\n", +- __func__); +- break; +- } ++ if (!policy->freq_table) ++ return -ENXIO; + +- down_write(&policy->rwsem); +- policy->user_policy.max = policy->max; +- cpufreq_governor_limits(policy); +- up_write(&policy->rwsem); ++ ret = cpufreq_frequency_table_cpuinfo(policy, ++ policy->freq_table); ++ if (ret) { ++ pr_err("%s: Policy frequency update failed\n", ++ __func__); ++ return ret; + } + ++ down_write(&policy->rwsem); ++ policy->user_policy.max = policy->max; ++ cpufreq_governor_limits(policy); ++ up_write(&policy->rwsem); ++ + return ret; + } + + int cpufreq_boost_trigger_state(int state) + { ++ struct cpufreq_policy *policy; + unsigned long flags; + int ret = 0; + +@@ -2385,15 +2383,25 @@ int cpufreq_boost_trigger_state(int state) + cpufreq_driver->boost_enabled = state; + write_unlock_irqrestore(&cpufreq_driver_lock, flags); + +- ret = cpufreq_driver->set_boost(state); +- if (ret) { +- write_lock_irqsave(&cpufreq_driver_lock, flags); +- cpufreq_driver->boost_enabled = !state; +- write_unlock_irqrestore(&cpufreq_driver_lock, flags); +- +- pr_err("%s: Cannot %s BOOST\n", +- __func__, state ? "enable" : "disable"); ++ get_online_cpus(); ++ for_each_active_policy(policy) { ++ ret = cpufreq_driver->set_boost(policy, state); ++ if (ret) ++ goto err_reset_state; + } ++ put_online_cpus(); ++ ++ return 0; ++ ++err_reset_state: ++ put_online_cpus(); ++ ++ write_lock_irqsave(&cpufreq_driver_lock, flags); ++ cpufreq_driver->boost_enabled = !state; ++ write_unlock_irqrestore(&cpufreq_driver_lock, flags); ++ ++ pr_err("%s: Cannot %s BOOST\n", ++ __func__, state ? "enable" : "disable"); + + return ret; + } +diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h +index 3361663144a1..ff6b10552c86 100644 +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -334,7 +334,7 @@ struct cpufreq_driver { + + /* platform specific boost support code */ + bool boost_enabled; +- int (*set_boost)(int state); ++ int (*set_boost)(struct cpufreq_policy *policy, int state); + }; + + /* flags */ +-- +2.25.1 + diff --git a/patches/0363-cpufreq-CPPC-add-SW-BOOST-support.patch b/patches/0363-cpufreq-CPPC-add-SW-BOOST-support.patch new file mode 100644 index 000000000000..a8dfe4af2621 --- /dev/null +++ b/patches/0363-cpufreq-CPPC-add-SW-BOOST-support.patch @@ -0,0 +1,142 @@ +From 5cca93b9a9e4690a8491f6fde455ff0268f1e92a Mon Sep 17 00:00:00 2001 +From: Xiongfeng Wang wangxiongfeng2@huawei.com +Date: Sat, 30 May 2020 10:08:31 +0800 +Subject: [PATCH openEuler-1.0-LTS 2/2] cpufreq: CPPC: add SW BOOST support + +mainline inclusion +from mainline-v5.8-rc1 +commit 54e74df5d76dea824c7c0c9d1b97150bf9b33793 +category: feature +bugzilla: https://gitee.com/openeuler/kernel/issues/I88RXU +CVE: NA + +Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... + +-------------------------------- + +To add SW BOOST support for CPPC, we need to get the max frequency of +boost mode and non-boost mode. ACPI spec 6.2 section 8.4.7.1 describes +the following two CPC registers. + +"Highest performance is the absolute maximum performance an individual +processor may reach, assuming ideal conditions. This performance level +may not be sustainable for long durations, and may only be achievable if +other platform components are in a specific state; for example, it may +require other processors be in an idle state. + +Nominal Performance is the maximum sustained performance level of the +processor, assuming ideal operating conditions. In absence of an +external constraint (power, thermal, etc.) this is the performance level +the platform is expected to be able to maintain continuously. All +processors are expected to be able to sustain their nominal performance +state simultaneously." + +To add SW BOOST support for CPPC, we can use Highest Performance as the +max performance in boost mode and Nominal Performance as the max +performance in non-boost mode. If the Highest Performance is greater +than the Nominal Performance, we assume SW BOOST is supported. + +The current CPPC driver does not support SW BOOST and use 'Highest +Performance' as the max performance the CPU can achieve. 'Nominal +Performance' is used to convert 'performance' to 'frequency'. That +means, if firmware enable boost and provide a value for Highest +Performance which is greater than Nominal Performance, boost feature is +enabled by default. + +Because SW BOOST is disabled by default, so, after this patch, boost +feature is disabled by default even if boost is enabled by firmware. + +Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com +Suggested-by: Viresh Kumar viresh.kumar@linaro.org +Acked-by: Viresh Kumar viresh.kumar@linaro.org +[ rjw: Subject ] +Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com +Signed-off-by: Yu Liao liaoyu15@huawei.com +--- + drivers/cpufreq/cppc_cpufreq.c | 35 ++++++++++++++++++++++++++++++++-- + 1 file changed, 33 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c +index 0a245f1caa95..15cffca10f1a 100644 +--- a/drivers/cpufreq/cppc_cpufreq.c ++++ b/drivers/cpufreq/cppc_cpufreq.c +@@ -41,6 +41,7 @@ + * requested etc. + */ + static struct cppc_cpudata **all_cpu_data; ++static bool boost_supported; + + struct cppc_workaround_oem_info { + char oem_id[ACPI_OEM_ID_SIZE + 1]; +@@ -314,7 +315,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) + * Section 8.4.7.1.1.5 of ACPI 6.1 spec) + */ + policy->min = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_nonlinear_perf); +- policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf); ++ policy->max = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf); + + /* + * Set cpuinfo.min_freq to Lowest to make the full range of performance +@@ -322,7 +323,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) + * nonlinear perf + */ + policy->cpuinfo.min_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.lowest_perf); +- policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.highest_perf); ++ policy->cpuinfo.max_freq = cppc_cpufreq_perf_to_khz(cpu, cpu->perf_caps.nominal_perf); + + policy->transition_delay_us = cppc_cpufreq_get_transition_delay_us(cpu_num); + policy->shared_type = cpu->shared_type; +@@ -347,6 +348,13 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) + + cpu->cur_policy = policy; + ++ /* ++ * If 'highest_perf' is greater than 'nominal_perf', we assume CPU Boost ++ * is supported. ++ */ ++ if (cpu->perf_caps.highest_perf > cpu->perf_caps.nominal_perf) ++ boost_supported = true; ++ + /* Set policy->cur to max now. The governors will adjust later. */ + policy->cur = cppc_cpufreq_perf_to_khz(cpu, + cpu->perf_caps.highest_perf); +@@ -414,6 +422,28 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpunum) + return cppc_get_rate_from_fbctrs(cpu, fb_ctrs_t0, fb_ctrs_t1); + } + ++static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state) ++{ ++ struct cppc_cpudata *cpudata; ++ int ret; ++ ++ if (!boost_supported) { ++ pr_err("BOOST not supported by CPU or firmware\n"); ++ return -EINVAL; ++ } ++ ++ cpudata = all_cpu_data[policy->cpu]; ++ if (state) ++ policy->max = cppc_cpufreq_perf_to_khz(cpudata, ++ cpudata->perf_caps.highest_perf); ++ else ++ policy->max = cppc_cpufreq_perf_to_khz(cpudata, ++ cpudata->perf_caps.nominal_perf); ++ policy->cpuinfo.max_freq = policy->max; ++ ++ return 0; ++} ++ + static struct cpufreq_driver cppc_cpufreq_driver = { + .flags = CPUFREQ_CONST_LOOPS, + .verify = cppc_verify_policy, +@@ -421,6 +451,7 @@ static struct cpufreq_driver cppc_cpufreq_driver = { + .get = cppc_cpufreq_get_rate, + .init = cppc_cpufreq_cpu_init, + .stop_cpu = cppc_cpufreq_stop_cpu, ++ .set_boost = cppc_cpufreq_set_boost, + .name = "cppc_cpufreq", + }; + +-- +2.25.1 + diff --git a/series.conf b/series.conf index d78c29dea2e9..35aef9d23d6c 100644 --- a/series.conf +++ b/series.conf @@ -362,3 +362,5 @@ patches/0358-spi-hisi-sfc-v3xx-add-address-mode-check.patch patches/0359-spi-hisi-sfc-v3xx-fix-potential-irq-race-condition.patch patches/0360-spi-hisi-sfc-v3xx-drop-unnecessary-ACPI_PTR-and-rela.patch patches/0361-config-arm64-Build-HiSilicon-SPI-SFC-driver-as-modul.patch +patches/0362-cpufreq-change-.set_boost-to-act-on-one-policy.patch +patches/0363--cpufreq-CPPC-add-SW-BOOST-support.patch