From: Greg Kroah-Hartman Date: Sun, 8 Sep 2024 14:29:20 +0000 (+0200) Subject: 6.6-stable patches X-Git-Tag: v4.19.322~57 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a29640c5759948067ca4a93bd66a7ca5a4b6661c;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: acpi-cppc-add-helper-to-get-the-highest-performance-value.patch cpufreq-amd-pstate-enable-amd-pstate-preferred-core-support.patch cpufreq-amd-pstate-fix-the-highest-frequency-issue-which-limits-performance.patch --- diff --git a/queue-6.6/acpi-cppc-add-helper-to-get-the-highest-performance-value.patch b/queue-6.6/acpi-cppc-add-helper-to-get-the-highest-performance-value.patch new file mode 100644 index 00000000000..92379ad55f8 --- /dev/null +++ b/queue-6.6/acpi-cppc-add-helper-to-get-the-highest-performance-value.patch @@ -0,0 +1,75 @@ +From 12753d71e8c5c3e716cedba23ddeed508da0bdc4 Mon Sep 17 00:00:00 2001 +From: Meng Li +Date: Fri, 19 Jan 2024 17:04:57 +0800 +Subject: ACPI: CPPC: Add helper to get the highest performance value + +From: Meng Li + +commit 12753d71e8c5c3e716cedba23ddeed508da0bdc4 upstream. + +Add support for getting the highest performance to the +generic CPPC driver. This enables downstream drivers +such as amd-pstate to discover and use these values. + +Refer to Chapter 8.4.6.1.1.1. Highest Performance of ACPI +Specification 6.5 for details on continuous performance control +of CPPC (linked below). + +Tested-by: Oleksandr Natalenko +Reviewed-by: Mario Limonciello +Reviewed-by: Wyes Karny +Reviewed-by: Perry Yuan +Acked-by: Huang Rui +Signed-off-by: Meng Li +Link: https://uefi.org/specs/ACPI/6.5/08_Processor_Configuration_and_Control.html?highlight=cppc#highest-performance +[ rjw: Subject and changelog edits ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/acpi/cppc_acpi.c | 13 +++++++++++++ + include/acpi/cppc_acpi.h | 5 +++++ + 2 files changed, 18 insertions(+) + +--- a/drivers/acpi/cppc_acpi.c ++++ b/drivers/acpi/cppc_acpi.c +@@ -1197,6 +1197,19 @@ int cppc_get_nominal_perf(int cpunum, u6 + } + + /** ++ * cppc_get_highest_perf - Get the highest performance register value. ++ * @cpunum: CPU from which to get highest performance. ++ * @highest_perf: Return address. ++ * ++ * Return: 0 for success, -EIO otherwise. ++ */ ++int cppc_get_highest_perf(int cpunum, u64 *highest_perf) ++{ ++ return cppc_get_perf(cpunum, HIGHEST_PERF, highest_perf); ++} ++EXPORT_SYMBOL_GPL(cppc_get_highest_perf); ++ ++/** + * cppc_get_epp_perf - Get the epp register value. + * @cpunum: CPU from which to get epp preference value. + * @epp_perf: Return address. +--- a/include/acpi/cppc_acpi.h ++++ b/include/acpi/cppc_acpi.h +@@ -139,6 +139,7 @@ struct cppc_cpudata { + #ifdef CONFIG_ACPI_CPPC_LIB + extern int cppc_get_desired_perf(int cpunum, u64 *desired_perf); + extern int cppc_get_nominal_perf(int cpunum, u64 *nominal_perf); ++extern int cppc_get_highest_perf(int cpunum, u64 *highest_perf); + extern int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs); + extern int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls); + extern int cppc_set_enable(int cpu, bool enable); +@@ -165,6 +166,10 @@ static inline int cppc_get_nominal_perf( + { + return -ENOTSUPP; + } ++static inline int cppc_get_highest_perf(int cpunum, u64 *highest_perf) ++{ ++ return -ENOTSUPP; ++} + static inline int cppc_get_perf_ctrs(int cpu, struct cppc_perf_fb_ctrs *perf_fb_ctrs) + { + return -ENOTSUPP; diff --git a/queue-6.6/cpufreq-amd-pstate-enable-amd-pstate-preferred-core-support.patch b/queue-6.6/cpufreq-amd-pstate-enable-amd-pstate-preferred-core-support.patch new file mode 100644 index 00000000000..64fa5ab8a25 --- /dev/null +++ b/queue-6.6/cpufreq-amd-pstate-enable-amd-pstate-preferred-core-support.patch @@ -0,0 +1,304 @@ +From f3a052391822b772b4e27f2594526cf1eb103cab Mon Sep 17 00:00:00 2001 +From: Meng Li +Date: Fri, 19 Jan 2024 17:04:58 +0800 +Subject: cpufreq: amd-pstate: Enable amd-pstate preferred core support + +From: Meng Li + +commit f3a052391822b772b4e27f2594526cf1eb103cab upstream. + +amd-pstate driver utilizes the functions and data structures +provided by the ITMT architecture to enable the scheduler to +favor scheduling on cores which can be get a higher frequency +with lower voltage. We call it amd-pstate preferrred core. + +Here sched_set_itmt_core_prio() is called to set priorities and +sched_set_itmt_support() is called to enable ITMT feature. +amd-pstate driver uses the highest performance value to indicate +the priority of CPU. The higher value has a higher priority. + +The initial core rankings are set up by amd-pstate when the +system boots. + +Add a variable hw_prefcore in cpudata structure. It will check +if the processor and power firmware support preferred core +feature. + +Add one new early parameter `disable` to allow user to disable +the preferred core. + +Only when hardware supports preferred core and user set `enabled` +in early parameter, amd pstate driver supports preferred core featue. + +Tested-by: Oleksandr Natalenko +Reviewed-by: Huang Rui +Reviewed-by: Wyes Karny +Reviewed-by: Mario Limonciello +Co-developed-by: Perry Yuan +Signed-off-by: Perry Yuan +Signed-off-by: Meng Li +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/amd-pstate.c | 131 ++++++++++++++++++++++++++++++++++++++++--- + include/linux/amd-pstate.h | 4 + + 2 files changed, 127 insertions(+), 8 deletions(-) + +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -49,6 +50,7 @@ + + #define AMD_PSTATE_TRANSITION_LATENCY 20000 + #define AMD_PSTATE_TRANSITION_DELAY 1000 ++#define AMD_PSTATE_PREFCORE_THRESHOLD 166 + + /* + * TODO: We need more time to fine tune processors with shared memory solution +@@ -64,6 +66,7 @@ static struct cpufreq_driver amd_pstate_ + static struct cpufreq_driver amd_pstate_epp_driver; + static int cppc_state = AMD_PSTATE_UNDEFINED; + static bool cppc_enabled; ++static bool amd_pstate_prefcore = true; + + /* + * AMD Energy Preference Performance (EPP) +@@ -320,13 +323,14 @@ static int pstate_init_perf(struct amd_c + if (ret) + return ret; + +- /* +- * TODO: Introduce AMD specific power feature. +- * +- * CPPC entry doesn't indicate the highest performance in some ASICs. ++ /* For platforms that do not support the preferred core feature, the ++ * highest_pef may be configured with 166 or 255, to avoid max frequency ++ * calculated wrongly. we take the AMD_CPPC_HIGHEST_PERF(cap1) value as ++ * the default max perf. + */ +- highest_perf = amd_get_highest_perf(); +- if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1)) ++ if (cpudata->hw_prefcore) ++ highest_perf = AMD_PSTATE_PREFCORE_THRESHOLD; ++ else + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); + + WRITE_ONCE(cpudata->highest_perf, highest_perf); +@@ -347,8 +351,9 @@ static int cppc_init_perf(struct amd_cpu + if (ret) + return ret; + +- highest_perf = amd_get_highest_perf(); +- if (highest_perf > cppc_perf.highest_perf) ++ if (cpudata->hw_prefcore) ++ highest_perf = AMD_PSTATE_PREFCORE_THRESHOLD; ++ else + highest_perf = cppc_perf.highest_perf; + + WRITE_ONCE(cpudata->highest_perf, highest_perf); +@@ -709,6 +714,80 @@ static void amd_perf_ctl_reset(unsigned + wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0); + } + ++/* ++ * Set amd-pstate preferred core enable can't be done directly from cpufreq callbacks ++ * due to locking, so queue the work for later. ++ */ ++static void amd_pstste_sched_prefcore_workfn(struct work_struct *work) ++{ ++ sched_set_itmt_support(); ++} ++static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn); ++ ++/* ++ * Get the highest performance register value. ++ * @cpu: CPU from which to get highest performance. ++ * @highest_perf: Return address. ++ * ++ * Return: 0 for success, -EIO otherwise. ++ */ ++static int amd_pstate_get_highest_perf(int cpu, u32 *highest_perf) ++{ ++ int ret; ++ ++ if (boot_cpu_has(X86_FEATURE_CPPC)) { ++ u64 cap1; ++ ++ ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1); ++ if (ret) ++ return ret; ++ WRITE_ONCE(*highest_perf, AMD_CPPC_HIGHEST_PERF(cap1)); ++ } else { ++ u64 cppc_highest_perf; ++ ++ ret = cppc_get_highest_perf(cpu, &cppc_highest_perf); ++ if (ret) ++ return ret; ++ WRITE_ONCE(*highest_perf, cppc_highest_perf); ++ } ++ ++ return (ret); ++} ++ ++#define CPPC_MAX_PERF U8_MAX ++ ++static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata) ++{ ++ int ret, prio; ++ u32 highest_perf; ++ ++ ret = amd_pstate_get_highest_perf(cpudata->cpu, &highest_perf); ++ if (ret) ++ return; ++ ++ cpudata->hw_prefcore = true; ++ /* check if CPPC preferred core feature is enabled*/ ++ if (highest_perf < CPPC_MAX_PERF) ++ prio = (int)highest_perf; ++ else { ++ pr_debug("AMD CPPC preferred core is unsupported!\n"); ++ cpudata->hw_prefcore = false; ++ return; ++ } ++ ++ if (!amd_pstate_prefcore) ++ return; ++ ++ /* ++ * The priorities can be set regardless of whether or not ++ * sched_set_itmt_support(true) has been called and it is valid to ++ * update them at any time after it has been called. ++ */ ++ sched_set_itmt_core_prio(prio, cpudata->cpu); ++ ++ schedule_work(&sched_prefcore_work); ++} ++ + static int amd_pstate_cpu_init(struct cpufreq_policy *policy) + { + int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret; +@@ -730,6 +809,8 @@ static int amd_pstate_cpu_init(struct cp + + cpudata->cpu = policy->cpu; + ++ amd_pstate_init_prefcore(cpudata); ++ + ret = amd_pstate_init_perf(cpudata); + if (ret) + goto free_cpudata1; +@@ -880,6 +961,17 @@ static ssize_t show_amd_pstate_highest_p + return sysfs_emit(buf, "%u\n", perf); + } + ++static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy, ++ char *buf) ++{ ++ bool hw_prefcore; ++ struct amd_cpudata *cpudata = policy->driver_data; ++ ++ hw_prefcore = READ_ONCE(cpudata->hw_prefcore); ++ ++ return sysfs_emit(buf, "%s\n", str_enabled_disabled(hw_prefcore)); ++} ++ + static ssize_t show_energy_performance_available_preferences( + struct cpufreq_policy *policy, char *buf) + { +@@ -1077,18 +1169,27 @@ static ssize_t status_store(struct devic + return ret < 0 ? ret : count; + } + ++static ssize_t prefcore_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore)); ++} ++ + cpufreq_freq_attr_ro(amd_pstate_max_freq); + cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq); + + cpufreq_freq_attr_ro(amd_pstate_highest_perf); ++cpufreq_freq_attr_ro(amd_pstate_hw_prefcore); + cpufreq_freq_attr_rw(energy_performance_preference); + cpufreq_freq_attr_ro(energy_performance_available_preferences); + static DEVICE_ATTR_RW(status); ++static DEVICE_ATTR_RO(prefcore); + + static struct freq_attr *amd_pstate_attr[] = { + &amd_pstate_max_freq, + &amd_pstate_lowest_nonlinear_freq, + &amd_pstate_highest_perf, ++ &amd_pstate_hw_prefcore, + NULL, + }; + +@@ -1096,6 +1197,7 @@ static struct freq_attr *amd_pstate_epp_ + &amd_pstate_max_freq, + &amd_pstate_lowest_nonlinear_freq, + &amd_pstate_highest_perf, ++ &amd_pstate_hw_prefcore, + &energy_performance_preference, + &energy_performance_available_preferences, + NULL, +@@ -1103,6 +1205,7 @@ static struct freq_attr *amd_pstate_epp_ + + static struct attribute *pstate_global_attributes[] = { + &dev_attr_status.attr, ++ &dev_attr_prefcore.attr, + NULL + }; + +@@ -1154,6 +1257,8 @@ static int amd_pstate_epp_cpu_init(struc + cpudata->cpu = policy->cpu; + cpudata->epp_policy = 0; + ++ amd_pstate_init_prefcore(cpudata); ++ + ret = amd_pstate_init_perf(cpudata); + if (ret) + goto free_cpudata1; +@@ -1577,7 +1682,17 @@ static int __init amd_pstate_param(char + + return amd_pstate_set_driver(mode_idx); + } ++ ++static int __init amd_prefcore_param(char *str) ++{ ++ if (!strcmp(str, "disable")) ++ amd_pstate_prefcore = false; ++ ++ return 0; ++} ++ + early_param("amd_pstate", amd_pstate_param); ++early_param("amd_prefcore", amd_prefcore_param); + + MODULE_AUTHOR("Huang Rui "); + MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver"); +--- a/include/linux/amd-pstate.h ++++ b/include/linux/amd-pstate.h +@@ -52,6 +52,9 @@ struct amd_aperf_mperf { + * @prev: Last Aperf/Mperf/tsc count value read from register + * @freq: current cpu frequency value + * @boost_supported: check whether the Processor or SBIOS supports boost mode ++ * @hw_prefcore: check whether HW supports preferred core featue. ++ * Only when hw_prefcore and early prefcore param are true, ++ * AMD P-State driver supports preferred core featue. + * @epp_policy: Last saved policy used to set energy-performance preference + * @epp_cached: Cached CPPC energy-performance preference value + * @policy: Cpufreq policy value +@@ -85,6 +88,7 @@ struct amd_cpudata { + + u64 freq; + bool boost_supported; ++ bool hw_prefcore; + + /* EPP feature related attributes*/ + s16 epp_policy; diff --git a/queue-6.6/cpufreq-amd-pstate-fix-the-highest-frequency-issue-which-limits-performance.patch b/queue-6.6/cpufreq-amd-pstate-fix-the-highest-frequency-issue-which-limits-performance.patch new file mode 100644 index 00000000000..40189163360 --- /dev/null +++ b/queue-6.6/cpufreq-amd-pstate-fix-the-highest-frequency-issue-which-limits-performance.patch @@ -0,0 +1,92 @@ +From bf202e654bfa57fb8cf9d93d4c6855890b70b9c4 Mon Sep 17 00:00:00 2001 +From: Perry Yuan +Date: Wed, 8 May 2024 13:47:03 +0800 +Subject: cpufreq: amd-pstate: fix the highest frequency issue which limits performance + +From: Perry Yuan + +commit bf202e654bfa57fb8cf9d93d4c6855890b70b9c4 upstream. + +To address the performance drop issue, an optimization has been +implemented. The incorrect highest performance value previously set by the +low-level power firmware for AMD CPUs with Family ID 0x19 and Model ID +ranging from 0x70 to 0x7F series has been identified as the cause. + +To resolve this, a check has been implemented to accurately determine the +CPU family and model ID. The correct highest performance value is now set +and the performance drop caused by the incorrect highest performance value +are eliminated. + +Before the fix, the highest frequency was set to 4200MHz, now it is set +to 4971MHz which is correct. + +CPU NODE SOCKET CORE L1d:L1i:L2:L3 ONLINE MAXMHZ MINMHZ MHZ + 0 0 0 0 0:0:0:0 yes 4971.0000 400.0000 400.0000 + 1 0 0 0 0:0:0:0 yes 4971.0000 400.0000 400.0000 + 2 0 0 1 1:1:1:0 yes 4971.0000 400.0000 4865.8140 + 3 0 0 1 1:1:1:0 yes 4971.0000 400.0000 400.0000 + +Fixes: f3a052391822 ("cpufreq: amd-pstate: Enable amd-pstate preferred core support") +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218759 +Signed-off-by: Perry Yuan +Co-developed-by: Mario Limonciello +Signed-off-by: Mario Limonciello +Tested-by: Gaha Bana +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/amd-pstate.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -50,7 +50,8 @@ + + #define AMD_PSTATE_TRANSITION_LATENCY 20000 + #define AMD_PSTATE_TRANSITION_DELAY 1000 +-#define AMD_PSTATE_PREFCORE_THRESHOLD 166 ++#define CPPC_HIGHEST_PERF_PERFORMANCE 196 ++#define CPPC_HIGHEST_PERF_DEFAULT 166 + + /* + * TODO: We need more time to fine tune processors with shared memory solution +@@ -313,6 +314,21 @@ static inline int amd_pstate_enable(bool + return static_call(amd_pstate_enable)(enable); + } + ++static u32 amd_pstate_highest_perf_set(struct amd_cpudata *cpudata) ++{ ++ struct cpuinfo_x86 *c = &cpu_data(0); ++ ++ /* ++ * For AMD CPUs with Family ID 19H and Model ID range 0x70 to 0x7f, ++ * the highest performance level is set to 196. ++ * https://bugzilla.kernel.org/show_bug.cgi?id=218759 ++ */ ++ if (c->x86 == 0x19 && (c->x86_model >= 0x70 && c->x86_model <= 0x7f)) ++ return CPPC_HIGHEST_PERF_PERFORMANCE; ++ ++ return CPPC_HIGHEST_PERF_DEFAULT; ++} ++ + static int pstate_init_perf(struct amd_cpudata *cpudata) + { + u64 cap1; +@@ -329,7 +345,7 @@ static int pstate_init_perf(struct amd_c + * the default max perf. + */ + if (cpudata->hw_prefcore) +- highest_perf = AMD_PSTATE_PREFCORE_THRESHOLD; ++ highest_perf = amd_pstate_highest_perf_set(cpudata); + else + highest_perf = AMD_CPPC_HIGHEST_PERF(cap1); + +@@ -352,7 +368,7 @@ static int cppc_init_perf(struct amd_cpu + return ret; + + if (cpudata->hw_prefcore) +- highest_perf = AMD_PSTATE_PREFCORE_THRESHOLD; ++ highest_perf = amd_pstate_highest_perf_set(cpudata); + else + highest_perf = cppc_perf.highest_perf; + diff --git a/queue-6.6/series b/queue-6.6/series index 39ba0941419..0a6bb06df94 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -200,3 +200,6 @@ riscv-use-write_once-when-setting-page-table-entries.patch mm-introduce-pudp-p4dp-pgdp_get-functions.patch riscv-mm-only-compile-pgtable.c-if-mmu.patch riscv-use-accessors-to-page-table-entries-instead-of-direct-dereference.patch +acpi-cppc-add-helper-to-get-the-highest-performance-value.patch +cpufreq-amd-pstate-enable-amd-pstate-preferred-core-support.patch +cpufreq-amd-pstate-fix-the-highest-frequency-issue-which-limits-performance.patch