release 6.12.9
This commit is contained in:
parent
3fb1083e44
commit
d372c88caf
2
debian/bin/genpatch-pfkernel
vendored
2
debian/bin/genpatch-pfkernel
vendored
@ -7,7 +7,7 @@ w=$(git rev-parse --path-format=absolute --show-toplevel) ; : "${w:?}" ; cd "$w"
|
|||||||
|
|
||||||
dst='debian/patches/pf-tmp'
|
dst='debian/patches/pf-tmp'
|
||||||
src='../linux-extras'
|
src='../linux-extras'
|
||||||
branches='amd-pstate amd-rapl cpuidle crypto fixes invlpgb kbuild pksm xfs zstd'
|
branches='amd-pstate amd-rapl btrfs cpuidle crypto fixes invlpgb kbuild pksm xfs zstd'
|
||||||
|
|
||||||
if [ -d "${dst}" ] ; then rm -rf "${dst}" ; fi
|
if [ -d "${dst}" ] ; then rm -rf "${dst}" ; fi
|
||||||
mkdir -p "${dst}"
|
mkdir -p "${dst}"
|
||||||
|
8
debian/changelog
vendored
8
debian/changelog
vendored
@ -1,3 +1,11 @@
|
|||||||
|
linux (6.12.9-1) sid; urgency=medium
|
||||||
|
|
||||||
|
* New upstream stable update:
|
||||||
|
https://www.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.12.9
|
||||||
|
* Drop "pf-amd-pstate" and "amd-rapl" patchsets.
|
||||||
|
|
||||||
|
-- Konstantin Demin <rockdrilla@gmail.com> Thu, 09 Jan 2025 23:12:22 +0300
|
||||||
|
|
||||||
linux (6.12.8-1) sid; urgency=medium
|
linux (6.12.8-1) sid; urgency=medium
|
||||||
|
|
||||||
* New upstream stable update:
|
* New upstream stable update:
|
||||||
|
1
debian/config/amd64/config.cloud
vendored
1
debian/config/amd64/config.cloud
vendored
@ -1406,6 +1406,7 @@ CONFIG_NVME_TARGET_FC=m
|
|||||||
## file: drivers/pci/Kconfig
|
## file: drivers/pci/Kconfig
|
||||||
##
|
##
|
||||||
CONFIG_XEN_PCIDEV_FRONTEND=m
|
CONFIG_XEN_PCIDEV_FRONTEND=m
|
||||||
|
# CONFIG_PCI_P2PDMA is not set
|
||||||
CONFIG_PCI_HYPERV=m
|
CONFIG_PCI_HYPERV=m
|
||||||
|
|
||||||
##
|
##
|
||||||
|
1
debian/config/amd64/config.mobile
vendored
1
debian/config/amd64/config.mobile
vendored
@ -4933,6 +4933,7 @@ CONFIG_PARPORT_1284=y
|
|||||||
##
|
##
|
||||||
## file: drivers/pci/Kconfig
|
## file: drivers/pci/Kconfig
|
||||||
##
|
##
|
||||||
|
CONFIG_PCI_P2PDMA=y
|
||||||
# CONFIG_PCI_DYNAMIC_OF_NODES is not set
|
# CONFIG_PCI_DYNAMIC_OF_NODES is not set
|
||||||
|
|
||||||
##
|
##
|
||||||
|
1
debian/config/amd64/config.vm
vendored
1
debian/config/amd64/config.vm
vendored
@ -2377,6 +2377,7 @@ CONFIG_NVME_TARGET_FC=m
|
|||||||
## file: drivers/pci/Kconfig
|
## file: drivers/pci/Kconfig
|
||||||
##
|
##
|
||||||
CONFIG_XEN_PCIDEV_FRONTEND=m
|
CONFIG_XEN_PCIDEV_FRONTEND=m
|
||||||
|
# CONFIG_PCI_P2PDMA is not set
|
||||||
CONFIG_PCI_HYPERV=m
|
CONFIG_PCI_HYPERV=m
|
||||||
|
|
||||||
##
|
##
|
||||||
|
1
debian/config/config
vendored
1
debian/config/config
vendored
@ -1133,7 +1133,6 @@ CONFIG_PCI_PF_STUB=m
|
|||||||
CONFIG_PCI_IOV=y
|
CONFIG_PCI_IOV=y
|
||||||
CONFIG_PCI_PRI=y
|
CONFIG_PCI_PRI=y
|
||||||
CONFIG_PCI_PASID=y
|
CONFIG_PCI_PASID=y
|
||||||
# CONFIG_PCI_P2PDMA is not set
|
|
||||||
## choice: PCI Express hierarchy optimization setting
|
## choice: PCI Express hierarchy optimization setting
|
||||||
# CONFIG_PCIE_BUS_TUNE_OFF is not set
|
# CONFIG_PCIE_BUS_TUNE_OFF is not set
|
||||||
CONFIG_PCIE_BUS_DEFAULT=y
|
CONFIG_PCIE_BUS_DEFAULT=y
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
From f077f4265c59f5d417aa40eaf82bb632c891b221 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Date: Fri, 9 Aug 2024 14:09:05 +0800
|
|
||||||
Subject: cpufreq: amd-pstate: add quirk for Ryzen 3000 series processor
|
|
||||||
|
|
||||||
The Ryzen 3000 series processors have been observed lacking the
|
|
||||||
nominal_freq and lowest_freq parameters in their ACPI tables. This
|
|
||||||
absence causes issues with loading the amd-pstate driver on these
|
|
||||||
systems. Introduces a fix to resolve the dependency issue
|
|
||||||
by adding a quirk specifically for the Ryzen 3000 series.
|
|
||||||
|
|
||||||
Reported-by: David Wang <00107082@163.com>
|
|
||||||
Signed-off-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 30 ++++++++++++++++++++++++++++++
|
|
||||||
1 file changed, 30 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -136,6 +136,11 @@ static struct quirk_entry quirk_amd_7k62
|
|
||||||
.lowest_freq = 550,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct quirk_entry quirk_amd_mts = {
|
|
||||||
+ .nominal_freq = 3600,
|
|
||||||
+ .lowest_freq = 550,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
@@ -152,6 +157,21 @@ static int __init dmi_matched_7k62_bios_
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int __init dmi_matched_mts_bios_bug(const struct dmi_system_id *dmi)
|
|
||||||
+{
|
|
||||||
+ /**
|
|
||||||
+ * match the broken bios for ryzen 3000 series processor support CPPC V2
|
|
||||||
+ * broken BIOS lack of nominal_freq and lowest_freq capabilities
|
|
||||||
+ * definition in ACPI tables
|
|
||||||
+ */
|
|
||||||
+ if (cpu_feature_enabled(X86_FEATURE_ZEN2)) {
|
|
||||||
+ quirks = dmi->driver_data;
|
|
||||||
+ pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident);
|
|
||||||
+ return 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = {
|
|
||||||
{
|
|
||||||
.callback = dmi_matched_7k62_bios_bug,
|
|
||||||
@@ -162,6 +182,16 @@ static const struct dmi_system_id amd_ps
|
|
||||||
},
|
|
||||||
.driver_data = &quirk_amd_7k62,
|
|
||||||
},
|
|
||||||
+ {
|
|
||||||
+ .callback = dmi_matched_mts_bios_bug,
|
|
||||||
+ .ident = "AMD Ryzen 3000",
|
|
||||||
+ .matches = {
|
|
||||||
+ DMI_MATCH(DMI_PRODUCT_NAME, "B450M MORTAR MAX (MS-7B89)"),
|
|
||||||
+ DMI_MATCH(DMI_BIOS_RELEASE, "06/10/2020"),
|
|
||||||
+ DMI_MATCH(DMI_BIOS_VERSION, "5.14"),
|
|
||||||
+ },
|
|
||||||
+ .driver_data = &quirk_amd_mts,
|
|
||||||
+ },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(dmi, amd_pstate_quirks_table);
|
|
@ -1,24 +0,0 @@
|
|||||||
From da2702cb43c82219d4624135d85e2fc8768aeb09 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Sep 2024 11:23:51 -0500
|
|
||||||
Subject: cpufreq/amd-pstate: Fix non kerneldoc comment
|
|
||||||
|
|
||||||
The comment for amd_cppc_supported() isn't meant to be kernel doc.
|
|
||||||
|
|
||||||
Fixes: cb817ec6673b7 ("cpufreq: amd-pstate: show CPPC debug message if CPPC is not supported")
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1782,7 +1782,7 @@ static int __init amd_pstate_set_driver(
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/**
|
|
||||||
+/*
|
|
||||||
* CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F.
|
|
||||||
* show the debug message that helps to check if the CPU has CPPC support for loading issue.
|
|
||||||
*/
|
|
@ -1,108 +0,0 @@
|
|||||||
From a7b86a6057ccc8f5b5ab4d08e753b2a034fa7d28 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Tue, 17 Sep 2024 09:14:35 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Rename MSR and shared memory specific functions
|
|
||||||
|
|
||||||
Existing function names "cppc_*" and "pstate_*" for shared memory and
|
|
||||||
MSR based systems are not intuitive enough, replace them with "shmem_*" and
|
|
||||||
"msr_*" respectively.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 24 ++++++++++++------------
|
|
||||||
1 file changed, 12 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -263,7 +263,7 @@ static int amd_pstate_get_energy_pref_in
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
+static void msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
u32 des_perf, u32 max_perf, bool fast_switch)
|
|
||||||
{
|
|
||||||
if (fast_switch)
|
|
||||||
@@ -273,7 +273,7 @@ static void pstate_update_perf(struct am
|
|
||||||
READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
}
|
|
||||||
|
|
||||||
-DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf);
|
|
||||||
+DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);
|
|
||||||
|
|
||||||
static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
u32 min_perf, u32 des_perf,
|
|
||||||
@@ -336,7 +336,7 @@ static int amd_pstate_set_energy_pref_in
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static inline int pstate_enable(bool enable)
|
|
||||||
+static inline int msr_enable(bool enable)
|
|
||||||
{
|
|
||||||
int ret, cpu;
|
|
||||||
unsigned long logical_proc_id_mask = 0;
|
|
||||||
@@ -362,7 +362,7 @@ static inline int pstate_enable(bool ena
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int cppc_enable(bool enable)
|
|
||||||
+static int shmem_enable(bool enable)
|
|
||||||
{
|
|
||||||
int cpu, ret = 0;
|
|
||||||
struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
@@ -389,14 +389,14 @@ static int cppc_enable(bool enable)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-DEFINE_STATIC_CALL(amd_pstate_enable, pstate_enable);
|
|
||||||
+DEFINE_STATIC_CALL(amd_pstate_enable, msr_enable);
|
|
||||||
|
|
||||||
static inline int amd_pstate_enable(bool enable)
|
|
||||||
{
|
|
||||||
return static_call(amd_pstate_enable)(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int pstate_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
+static int msr_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
u64 cap1;
|
|
||||||
|
|
||||||
@@ -415,7 +415,7 @@ static int pstate_init_perf(struct amd_c
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int cppc_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
+static int shmem_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
struct cppc_perf_caps cppc_perf;
|
|
||||||
|
|
||||||
@@ -450,14 +450,14 @@ static int cppc_init_perf(struct amd_cpu
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-DEFINE_STATIC_CALL(amd_pstate_init_perf, pstate_init_perf);
|
|
||||||
+DEFINE_STATIC_CALL(amd_pstate_init_perf, msr_init_perf);
|
|
||||||
|
|
||||||
static inline int amd_pstate_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
return static_call(amd_pstate_init_perf)(cpudata);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void cppc_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
+static void shmem_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
u32 min_perf, u32 des_perf,
|
|
||||||
u32 max_perf, bool fast_switch)
|
|
||||||
{
|
|
||||||
@@ -1905,9 +1905,9 @@ static int __init amd_pstate_init(void)
|
|
||||||
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
|
|
||||||
} else {
|
|
||||||
pr_debug("AMD CPPC shared memory based functionality is supported\n");
|
|
||||||
- static_call_update(amd_pstate_enable, cppc_enable);
|
|
||||||
- static_call_update(amd_pstate_init_perf, cppc_init_perf);
|
|
||||||
- static_call_update(amd_pstate_update_perf, cppc_update_perf);
|
|
||||||
+ static_call_update(amd_pstate_enable, shmem_enable);
|
|
||||||
+ static_call_update(amd_pstate_init_perf, shmem_init_perf);
|
|
||||||
+ static_call_update(amd_pstate_update_perf, shmem_update_perf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amd_pstate_prefcore) {
|
|
@ -1,49 +0,0 @@
|
|||||||
From 4e784acad1b275ddcb105b053922ab2179ab3f86 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Sat, 12 Oct 2024 12:45:18 -0500
|
|
||||||
Subject: cpufreq/amd-pstate: Use amd_pstate_update_min_max_limit() for EPP
|
|
||||||
limits
|
|
||||||
|
|
||||||
When the EPP updates are set the maximum capable frequency for the
|
|
||||||
CPU is used to set the upper limit instead of that of the policy.
|
|
||||||
|
|
||||||
Adjust amd_pstate_epp_update_limit() to reuse policy calculation code
|
|
||||||
from amd_pstate_update_min_max_limit().
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 19 +++----------------
|
|
||||||
1 file changed, 3 insertions(+), 16 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1515,26 +1515,13 @@ static void amd_pstate_epp_cpu_exit(stru
|
|
||||||
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
- u32 max_perf, min_perf, min_limit_perf, max_limit_perf;
|
|
||||||
+ u32 max_perf, min_perf;
|
|
||||||
u64 value;
|
|
||||||
s16 epp;
|
|
||||||
|
|
||||||
- if (cpudata->boost_supported && !policy->boost_enabled)
|
|
||||||
- max_perf = READ_ONCE(cpudata->nominal_perf);
|
|
||||||
- else
|
|
||||||
- max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
+ max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
min_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
- max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq);
|
|
||||||
- min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq);
|
|
||||||
-
|
|
||||||
- if (min_limit_perf < min_perf)
|
|
||||||
- min_limit_perf = min_perf;
|
|
||||||
-
|
|
||||||
- if (max_limit_perf < min_limit_perf)
|
|
||||||
- max_limit_perf = min_limit_perf;
|
|
||||||
-
|
|
||||||
- WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf);
|
|
||||||
- WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf);
|
|
||||||
+ amd_pstate_update_min_max_limit(policy);
|
|
||||||
|
|
||||||
max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf,
|
|
||||||
cpudata->max_limit_perf);
|
|
@ -1,29 +0,0 @@
|
|||||||
From ed39a400d49baf070571bb1da475297a8495aa67 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Sat, 12 Oct 2024 12:45:19 -0500
|
|
||||||
Subject: cpufreq/amd-pstate: Drop needless EPP initialization
|
|
||||||
|
|
||||||
The EPP value doesn't need to be cached to the CPPC request in
|
|
||||||
amd_pstate_epp_update_limit() because it's passed as an argument
|
|
||||||
at the end to amd_pstate_set_epp() and stored at that time.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 6 ------
|
|
||||||
1 file changed, 6 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1558,12 +1558,6 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
epp = 0;
|
|
||||||
|
|
||||||
- /* Set initial EPP value */
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
- value &= ~GENMASK_ULL(31, 24);
|
|
||||||
- value |= (u64)epp << 24;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
return amd_pstate_set_epp(cpudata, epp);
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
From 2a012fdcef91db6e380000b8042f90544ea49fd7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 05:39:28 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Remove the redundant verify() function
|
|
||||||
|
|
||||||
Merge the two verify() callback functions and rename the
|
|
||||||
cpufreq_policy_data argument for better readability.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 15 ++++-----------
|
|
||||||
1 file changed, 4 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -557,10 +557,10 @@ cpufreq_policy_put:
|
|
||||||
cpufreq_cpu_put(policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int amd_pstate_verify(struct cpufreq_policy_data *policy)
|
|
||||||
+static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
|
|
||||||
{
|
|
||||||
- cpufreq_verify_within_cpu_limits(policy);
|
|
||||||
-
|
|
||||||
+ cpufreq_verify_within_cpu_limits(policy_data);
|
|
||||||
+ pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1668,13 +1668,6 @@ static int amd_pstate_epp_cpu_offline(st
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int amd_pstate_epp_verify_policy(struct cpufreq_policy_data *policy)
|
|
||||||
-{
|
|
||||||
- cpufreq_verify_within_cpu_limits(policy);
|
|
||||||
- pr_debug("policy_max =%d, policy_min=%d\n", policy->max, policy->min);
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
@@ -1730,7 +1723,7 @@ static struct cpufreq_driver amd_pstate_
|
|
||||||
|
|
||||||
static struct cpufreq_driver amd_pstate_epp_driver = {
|
|
||||||
.flags = CPUFREQ_CONST_LOOPS,
|
|
||||||
- .verify = amd_pstate_epp_verify_policy,
|
|
||||||
+ .verify = amd_pstate_verify,
|
|
||||||
.setpolicy = amd_pstate_epp_set_policy,
|
|
||||||
.init = amd_pstate_epp_cpu_init,
|
|
||||||
.exit = amd_pstate_epp_cpu_exit,
|
|
@ -1,74 +0,0 @@
|
|||||||
From ba9f0c8ca71a1c44e35dd8d3221abda0bd4e465a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 05:39:30 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq
|
|
||||||
|
|
||||||
According to the AMD architectural programmer's manual volume 2 [1], in
|
|
||||||
section "17.6.4.1 CPPC_CAPABILITY_1" lowest_nonlinear_perf is described
|
|
||||||
as "Reports the most energy efficient performance level (in terms of
|
|
||||||
performance per watt). Above this threshold, lower performance levels
|
|
||||||
generally result in increased energy efficiency. Reducing performance
|
|
||||||
below this threshold does not result in total energy savings for a given
|
|
||||||
computation, although it reduces instantaneous power consumption". So
|
|
||||||
lowest_nonlinear_perf is the most power efficient performance level, and
|
|
||||||
going below that would lead to a worse performance/watt.
|
|
||||||
|
|
||||||
Also, setting the minimum frequency to lowest_nonlinear_freq (instead of
|
|
||||||
lowest_freq) allows the CPU to idle at a higher frequency which leads
|
|
||||||
to more time being spent in a deeper idle state (as trivial idle tasks
|
|
||||||
are completed sooner). This has shown a power benefit in some systems,
|
|
||||||
in other systems, power consumption has increased but so has the
|
|
||||||
throughput/watt.
|
|
||||||
|
|
||||||
Modify the initial policy_data->min set by cpufreq-core to
|
|
||||||
lowest_nonlinear_freq, in the ->verify() callback. Also set the
|
|
||||||
cpudata->req[0] to FREQ_QOS_MIN_DEFAULT_VALUE (i.e. 0), so that it also
|
|
||||||
gets overriden by the check in verify function.
|
|
||||||
|
|
||||||
Link: https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf [1]
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 21 ++++++++++++++++++++-
|
|
||||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -559,8 +559,27 @@ cpufreq_policy_put:
|
|
||||||
|
|
||||||
static int amd_pstate_verify(struct cpufreq_policy_data *policy_data)
|
|
||||||
{
|
|
||||||
+ /*
|
|
||||||
+ * Initialize lower frequency limit (i.e.policy->min) with
|
|
||||||
+ * lowest_nonlinear_frequency which is the most energy efficient
|
|
||||||
+ * frequency. Override the initial value set by cpufreq core and
|
|
||||||
+ * amd-pstate qos_requests.
|
|
||||||
+ */
|
|
||||||
+ if (policy_data->min == FREQ_QOS_MIN_DEFAULT_VALUE) {
|
|
||||||
+ struct cpufreq_policy *policy = cpufreq_cpu_get(policy_data->cpu);
|
|
||||||
+ struct amd_cpudata *cpudata;
|
|
||||||
+
|
|
||||||
+ if (!policy)
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
+ cpudata = policy->driver_data;
|
|
||||||
+ policy_data->min = cpudata->lowest_nonlinear_freq;
|
|
||||||
+ cpufreq_cpu_put(policy);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
cpufreq_verify_within_cpu_limits(policy_data);
|
|
||||||
pr_debug("policy_max =%d, policy_min=%d\n", policy_data->max, policy_data->min);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1009,7 +1028,7 @@ static int amd_pstate_cpu_init(struct cp
|
|
||||||
policy->fast_switch_possible = true;
|
|
||||||
|
|
||||||
ret = freq_qos_add_request(&policy->constraints, &cpudata->req[0],
|
|
||||||
- FREQ_QOS_MIN, policy->cpuinfo.min_freq);
|
|
||||||
+ FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(dev, "Failed to add min-freq constraint (%d)\n", ret);
|
|
||||||
goto free_cpudata1;
|
|
@ -1,44 +0,0 @@
|
|||||||
From e50aedf7fcd345c6f2e22a942deae007d71582df Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 10:05:27 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Call amd_pstate_register() in amd_pstate_init()
|
|
||||||
|
|
||||||
Replace a similar chunk of code in amd_pstate_init() with
|
|
||||||
amd_pstate_register() call.
|
|
||||||
|
|
||||||
Suggested-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 12 ++----------
|
|
||||||
1 file changed, 2 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1909,17 +1909,10 @@ static int __init amd_pstate_init(void)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- /* enable amd pstate feature */
|
|
||||||
- ret = amd_pstate_enable(true);
|
|
||||||
- if (ret) {
|
|
||||||
- pr_err("failed to enable driver mode(%d)\n", cppc_state);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = cpufreq_register_driver(current_pstate_driver);
|
|
||||||
+ ret = amd_pstate_register_driver(cppc_state);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("failed to register with return %d\n", ret);
|
|
||||||
- goto disable_driver;
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_root = bus_get_dev_root(&cpu_subsys);
|
|
||||||
@@ -1936,7 +1929,6 @@ static int __init amd_pstate_init(void)
|
|
||||||
|
|
||||||
global_attr_free:
|
|
||||||
cpufreq_unregister_driver(current_pstate_driver);
|
|
||||||
-disable_driver:
|
|
||||||
amd_pstate_enable(false);
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
From 658af2bf561ee3883369b2caca4d688983f943de Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 10:05:29 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Call amd_pstate_set_driver() in
|
|
||||||
amd_pstate_register_driver()
|
|
||||||
|
|
||||||
Replace a similar chunk of code in amd_pstate_register_driver() with
|
|
||||||
amd_pstate_set_driver() call.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 47 +++++++++++++++++-------------------
|
|
||||||
1 file changed, 22 insertions(+), 25 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1221,16 +1221,32 @@ static void amd_pstate_driver_cleanup(vo
|
|
||||||
current_pstate_driver = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int amd_pstate_set_driver(int mode_idx)
|
|
||||||
+{
|
|
||||||
+ if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
|
|
||||||
+ cppc_state = mode_idx;
|
|
||||||
+ if (cppc_state == AMD_PSTATE_DISABLE)
|
|
||||||
+ pr_info("driver is explicitly disabled\n");
|
|
||||||
+
|
|
||||||
+ if (cppc_state == AMD_PSTATE_ACTIVE)
|
|
||||||
+ current_pstate_driver = &amd_pstate_epp_driver;
|
|
||||||
+
|
|
||||||
+ if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
|
|
||||||
+ current_pstate_driver = &amd_pstate_driver;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return -EINVAL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int amd_pstate_register_driver(int mode)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- if (mode == AMD_PSTATE_PASSIVE || mode == AMD_PSTATE_GUIDED)
|
|
||||||
- current_pstate_driver = &amd_pstate_driver;
|
|
||||||
- else if (mode == AMD_PSTATE_ACTIVE)
|
|
||||||
- current_pstate_driver = &amd_pstate_epp_driver;
|
|
||||||
- else
|
|
||||||
- return -EINVAL;
|
|
||||||
+ ret = amd_pstate_set_driver(mode);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
cppc_state = mode;
|
|
||||||
|
|
||||||
@@ -1756,25 +1772,6 @@ static struct cpufreq_driver amd_pstate_
|
|
||||||
.attr = amd_pstate_epp_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static int __init amd_pstate_set_driver(int mode_idx)
|
|
||||||
-{
|
|
||||||
- if (mode_idx >= AMD_PSTATE_DISABLE && mode_idx < AMD_PSTATE_MAX) {
|
|
||||||
- cppc_state = mode_idx;
|
|
||||||
- if (cppc_state == AMD_PSTATE_DISABLE)
|
|
||||||
- pr_info("driver is explicitly disabled\n");
|
|
||||||
-
|
|
||||||
- if (cppc_state == AMD_PSTATE_ACTIVE)
|
|
||||||
- current_pstate_driver = &amd_pstate_epp_driver;
|
|
||||||
-
|
|
||||||
- if (cppc_state == AMD_PSTATE_PASSIVE || cppc_state == AMD_PSTATE_GUIDED)
|
|
||||||
- current_pstate_driver = &amd_pstate_driver;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return -EINVAL;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* CPPC function is not supported for family ID 17H with model_ID ranging from 0x10 to 0x2F.
|
|
||||||
* show the debug message that helps to check if the CPU has CPPC support for loading issue.
|
|
@ -1,41 +0,0 @@
|
|||||||
From 0f2929e03651c101f1a6fa8ccf40167eb48c1789 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 10:05:31 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Remove the switch case in amd_pstate_init()
|
|
||||||
|
|
||||||
Replace the switch case with a more readable if condition.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 16 +++++-----------
|
|
||||||
1 file changed, 5 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1873,21 +1873,15 @@ static int __init amd_pstate_init(void)
|
|
||||||
cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
- switch (cppc_state) {
|
|
||||||
- case AMD_PSTATE_DISABLE:
|
|
||||||
+ if (cppc_state == AMD_PSTATE_DISABLE) {
|
|
||||||
pr_info("driver load is disabled, boot with specific mode to enable this\n");
|
|
||||||
return -ENODEV;
|
|
||||||
- case AMD_PSTATE_PASSIVE:
|
|
||||||
- case AMD_PSTATE_ACTIVE:
|
|
||||||
- case AMD_PSTATE_GUIDED:
|
|
||||||
- ret = amd_pstate_set_driver(cppc_state);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ ret = amd_pstate_set_driver(cppc_state);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
/* capability check */
|
|
||||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
pr_debug("AMD CPPC MSR based functionality is supported\n");
|
|
@ -1,43 +0,0 @@
|
|||||||
From bec664db265db933a107bac290601eb89acb938b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 10:05:33 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Remove the redundant amd_pstate_set_driver() call
|
|
||||||
|
|
||||||
amd_pstate_set_driver() is called twice, once in amd_pstate_init() and once
|
|
||||||
as part of amd_pstate_register_driver(). Move around code and eliminate
|
|
||||||
the redundancy.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 12 ++++--------
|
|
||||||
1 file changed, 4 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1878,9 +1878,11 @@ static int __init amd_pstate_init(void)
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = amd_pstate_set_driver(cppc_state);
|
|
||||||
- if (ret)
|
|
||||||
+ ret = amd_pstate_register_driver(cppc_state);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_err("failed to register with return %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/* capability check */
|
|
||||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
@@ -1900,12 +1902,6 @@ static int __init amd_pstate_init(void)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = amd_pstate_register_driver(cppc_state);
|
|
||||||
- if (ret) {
|
|
||||||
- pr_err("failed to register with return %d\n", ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
dev_root = bus_get_dev_root(&cpu_subsys);
|
|
||||||
if (dev_root) {
|
|
||||||
ret = sysfs_create_group(&dev_root->kobj, &amd_pstate_global_attr_group);
|
|
@ -1,33 +0,0 @@
|
|||||||
From 82d4b19d01912cd9c2cfb3c638a43cc2b04ffc63 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 17 Oct 2024 12:34:39 -0500
|
|
||||||
Subject: cpufreq/amd-pstate-ut: Add fix for min freq unit test
|
|
||||||
|
|
||||||
commit 642aff3964b0f ("cpufreq/amd-pstate: Set the initial min_freq to
|
|
||||||
lowest_nonlinear_freq") changed the iniital minimum frequency to lowest
|
|
||||||
nonlinear frequency, but the unit tests weren't updated and now fail.
|
|
||||||
|
|
||||||
Update them to match this same change.
|
|
||||||
|
|
||||||
Fixes: 642aff3964b0f ("cpufreq/amd-pstate: Set the initial min_freq to lowest_nonlinear_freq")
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate-ut.c | 6 +++---
|
|
||||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate-ut.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate-ut.c
|
|
||||||
@@ -227,10 +227,10 @@ static void amd_pstate_ut_check_freq(u32
|
|
||||||
goto skip_test;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (cpudata->min_freq != policy->min) {
|
|
||||||
+ if (cpudata->lowest_nonlinear_freq != policy->min) {
|
|
||||||
amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
|
|
||||||
- pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n",
|
|
||||||
- __func__, cpu, cpudata->min_freq, policy->min);
|
|
||||||
+ pr_err("%s cpu%d cpudata_lowest_nonlinear_freq=%d policy_min=%d, they should be equal!\n",
|
|
||||||
+ __func__, cpu, cpudata->lowest_nonlinear_freq, policy->min);
|
|
||||||
goto skip_test;
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
|||||||
From b1bc26a3ecd5afc4d6106332910fbdc3f6718acd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Swapnil Sapkal <swapnil.sapkal@amd.com>
|
|
||||||
Date: Mon, 21 Oct 2024 15:48:36 +0530
|
|
||||||
Subject: amd-pstate: Switch to amd-pstate by default on some Server platforms
|
|
||||||
|
|
||||||
Currently the default cpufreq driver for all the AMD EPYC servers is
|
|
||||||
acpi-cpufreq. Going forward, switch to amd-pstate as the default
|
|
||||||
driver on the AMD EPYC server platforms with CPU family 0x1A or
|
|
||||||
higher. The default mode will be active mode.
|
|
||||||
|
|
||||||
Testing shows that amd-pstate with active mode and performance
|
|
||||||
governor provides comparable or better performance per-watt against
|
|
||||||
acpi-cpufreq + performance governor.
|
|
||||||
|
|
||||||
Likewise, amd-pstate with active mode and powersave governor with the
|
|
||||||
energy_performance_preference=power (EPP=255) provides comparable or
|
|
||||||
better performance per-watt against acpi-cpufreq + schedutil governor
|
|
||||||
for a wide range of workloads.
|
|
||||||
|
|
||||||
Users can still revert to using acpi-cpufreq driver on these platforms
|
|
||||||
with the "amd_pstate=disable" kernel commandline parameter.
|
|
||||||
|
|
||||||
Signed-off-by: Swapnil Sapkal <swapnil.sapkal@amd.com>
|
|
||||||
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1862,10 +1862,10 @@ static int __init amd_pstate_init(void)
|
|
||||||
if (cppc_state == AMD_PSTATE_UNDEFINED) {
|
|
||||||
/* Disable on the following configs by default:
|
|
||||||
* 1. Undefined platforms
|
|
||||||
- * 2. Server platforms
|
|
||||||
+ * 2. Server platforms with CPUs older than Family 0x1A.
|
|
||||||
*/
|
|
||||||
if (amd_pstate_acpi_pm_profile_undefined() ||
|
|
||||||
- amd_pstate_acpi_pm_profile_server()) {
|
|
||||||
+ (amd_pstate_acpi_pm_profile_server() && boot_cpu_data.x86 < 0x1A)) {
|
|
||||||
pr_info("driver load is disabled, boot with specific mode to enable this\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
From ca32f306d11e95ca133a2f90249bb4555c2742c3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 23 Oct 2024 10:21:06 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Rename functions that enable CPPC
|
|
||||||
|
|
||||||
Explicitly rename functions that enable CPPC as *_cppc_*.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 26 +++++++++++++-------------
|
|
||||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -336,7 +336,7 @@ static int amd_pstate_set_energy_pref_in
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static inline int msr_enable(bool enable)
|
|
||||||
+static inline int msr_cppc_enable(bool enable)
|
|
||||||
{
|
|
||||||
int ret, cpu;
|
|
||||||
unsigned long logical_proc_id_mask = 0;
|
|
||||||
@@ -362,7 +362,7 @@ static inline int msr_enable(bool enable
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int shmem_enable(bool enable)
|
|
||||||
+static int shmem_cppc_enable(bool enable)
|
|
||||||
{
|
|
||||||
int cpu, ret = 0;
|
|
||||||
struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
@@ -389,11 +389,11 @@ static int shmem_enable(bool enable)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-DEFINE_STATIC_CALL(amd_pstate_enable, msr_enable);
|
|
||||||
+DEFINE_STATIC_CALL(amd_pstate_cppc_enable, msr_cppc_enable);
|
|
||||||
|
|
||||||
-static inline int amd_pstate_enable(bool enable)
|
|
||||||
+static inline int amd_pstate_cppc_enable(bool enable)
|
|
||||||
{
|
|
||||||
- return static_call(amd_pstate_enable)(enable);
|
|
||||||
+ return static_call(amd_pstate_cppc_enable)(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int msr_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
@@ -1072,7 +1072,7 @@ static int amd_pstate_cpu_resume(struct
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- ret = amd_pstate_enable(true);
|
|
||||||
+ ret = amd_pstate_cppc_enable(true);
|
|
||||||
if (ret)
|
|
||||||
pr_err("failed to enable amd-pstate during resume, return %d\n", ret);
|
|
||||||
|
|
||||||
@@ -1083,7 +1083,7 @@ static int amd_pstate_cpu_suspend(struct
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- ret = amd_pstate_enable(false);
|
|
||||||
+ ret = amd_pstate_cppc_enable(false);
|
|
||||||
if (ret)
|
|
||||||
pr_err("failed to disable amd-pstate during suspend, return %d\n", ret);
|
|
||||||
|
|
||||||
@@ -1216,7 +1216,7 @@ static ssize_t show_energy_performance_p
|
|
||||||
|
|
||||||
static void amd_pstate_driver_cleanup(void)
|
|
||||||
{
|
|
||||||
- amd_pstate_enable(false);
|
|
||||||
+ amd_pstate_cppc_enable(false);
|
|
||||||
cppc_state = AMD_PSTATE_DISABLE;
|
|
||||||
current_pstate_driver = NULL;
|
|
||||||
}
|
|
||||||
@@ -1250,7 +1250,7 @@ static int amd_pstate_register_driver(in
|
|
||||||
|
|
||||||
cppc_state = mode;
|
|
||||||
|
|
||||||
- ret = amd_pstate_enable(true);
|
|
||||||
+ ret = amd_pstate_cppc_enable(true);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n",
|
|
||||||
ret);
|
|
||||||
@@ -1629,7 +1629,7 @@ static void amd_pstate_epp_reenable(stru
|
|
||||||
u64 value, max_perf;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- ret = amd_pstate_enable(true);
|
|
||||||
+ ret = amd_pstate_cppc_enable(true);
|
|
||||||
if (ret)
|
|
||||||
pr_err("failed to enable amd pstate during resume, return %d\n", ret);
|
|
||||||
|
|
||||||
@@ -1716,7 +1716,7 @@ static int amd_pstate_epp_suspend(struct
|
|
||||||
cpudata->suspended = true;
|
|
||||||
|
|
||||||
/* disable CPPC in lowlevel firmware */
|
|
||||||
- ret = amd_pstate_enable(false);
|
|
||||||
+ ret = amd_pstate_cppc_enable(false);
|
|
||||||
if (ret)
|
|
||||||
pr_err("failed to suspend, return %d\n", ret);
|
|
||||||
|
|
||||||
@@ -1891,7 +1891,7 @@ static int __init amd_pstate_init(void)
|
|
||||||
current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
|
|
||||||
} else {
|
|
||||||
pr_debug("AMD CPPC shared memory based functionality is supported\n");
|
|
||||||
- static_call_update(amd_pstate_enable, shmem_enable);
|
|
||||||
+ static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable);
|
|
||||||
static_call_update(amd_pstate_init_perf, shmem_init_perf);
|
|
||||||
static_call_update(amd_pstate_update_perf, shmem_update_perf);
|
|
||||||
}
|
|
||||||
@@ -1916,7 +1916,7 @@ static int __init amd_pstate_init(void)
|
|
||||||
|
|
||||||
global_attr_free:
|
|
||||||
cpufreq_unregister_driver(current_pstate_driver);
|
|
||||||
- amd_pstate_enable(false);
|
|
||||||
+ amd_pstate_cppc_enable(false);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
device_initcall(amd_pstate_init);
|
|
@ -1,30 +0,0 @@
|
|||||||
From de31d4a11e894a73ed7ef2388fb27f0bb4036de3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 23 Oct 2024 10:21:08 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Do not attempt to clear MSR_AMD_CPPC_ENABLE
|
|
||||||
|
|
||||||
MSR_AMD_CPPC_ENABLE is a write once register, i.e. attempting to clear
|
|
||||||
it is futile, it will not take effect. Hence, return if disable (0)
|
|
||||||
argument is passed to the msr_cppc_enable()
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 6 ++++++
|
|
||||||
1 file changed, 6 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -341,6 +341,12 @@ static inline int msr_cppc_enable(bool e
|
|
||||||
int ret, cpu;
|
|
||||||
unsigned long logical_proc_id_mask = 0;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * MSR_AMD_CPPC_ENABLE is write-once, once set it cannot be cleared.
|
|
||||||
+ */
|
|
||||||
+ if (!enable)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
if (enable == cppc_enabled)
|
|
||||||
return 0;
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
|||||||
From c5eadae39ccdf6bada95c834147e285e445b12ad Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 23 Oct 2024 10:21:10 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Call cppc_set_epp_perf in the reenable function
|
|
||||||
|
|
||||||
The EPP value being set in perf_ctrls.energy_perf is not being propagated
|
|
||||||
to the shared memory, fix that.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 6 ++++--
|
|
||||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1646,8 +1646,9 @@ static void amd_pstate_epp_reenable(stru
|
|
||||||
wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
} else {
|
|
||||||
perf_ctrls.max_perf = max_perf;
|
|
||||||
- perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached);
|
|
||||||
cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
+ perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached);
|
|
||||||
+ cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1688,8 +1689,9 @@ static void amd_pstate_epp_offline(struc
|
|
||||||
} else {
|
|
||||||
perf_ctrls.desired_perf = 0;
|
|
||||||
perf_ctrls.max_perf = min_perf;
|
|
||||||
- perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE);
|
|
||||||
cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
+ perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE);
|
|
||||||
+ cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
}
|
|
||||||
mutex_unlock(&amd_pstate_limits_lock);
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
From 275a7a8c95ac5d0c0ff586acd882d751478f6a00 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 23 Oct 2024 10:21:12 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Align offline flow of shared memory and MSR based
|
|
||||||
systems
|
|
||||||
|
|
||||||
Set min_perf to lowest_perf for shared memory systems, similar to the MSR
|
|
||||||
based systems.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1688,6 +1688,7 @@ static void amd_pstate_epp_offline(struc
|
|
||||||
wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
} else {
|
|
||||||
perf_ctrls.desired_perf = 0;
|
|
||||||
+ perf_ctrls.min_perf = min_perf;
|
|
||||||
perf_ctrls.max_perf = min_perf;
|
|
||||||
cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE);
|
|
@ -1,60 +0,0 @@
|
|||||||
From 173172a4604a050ccb5a6745acd9fa90d01257a7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Fri, 25 Oct 2024 12:14:55 -0500
|
|
||||||
Subject: x86/cpufeatures: Rename X86_FEATURE_FAST_CPPC to have AMD prefix
|
|
||||||
|
|
||||||
This feature is an AMD unique feature of some processors, so put
|
|
||||||
AMD into the name.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/include/asm/cpufeatures.h | 2 +-
|
|
||||||
arch/x86/kernel/cpu/scattered.c | 2 +-
|
|
||||||
drivers/cpufreq/amd-pstate.c | 2 +-
|
|
||||||
tools/arch/x86/include/asm/cpufeatures.h | 2 +-
|
|
||||||
4 files changed, 4 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/include/asm/cpufeatures.h
|
|
||||||
+++ b/arch/x86/include/asm/cpufeatures.h
|
|
||||||
@@ -473,7 +473,7 @@
|
|
||||||
#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* BHI_DIS_S HW control available */
|
|
||||||
#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* BHI_DIS_S HW control enabled */
|
|
||||||
#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
|
||||||
-#define X86_FEATURE_FAST_CPPC (21*32 + 5) /* AMD Fast CPPC */
|
|
||||||
+#define X86_FEATURE_AMD_FAST_CPPC (21*32 + 5) /* Fast CPPC */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BUG word(s)
|
|
||||||
--- a/arch/x86/kernel/cpu/scattered.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/scattered.c
|
|
||||||
@@ -45,7 +45,7 @@ static const struct cpuid_bit cpuid_bits
|
|
||||||
{ X86_FEATURE_HW_PSTATE, CPUID_EDX, 7, 0x80000007, 0 },
|
|
||||||
{ X86_FEATURE_CPB, CPUID_EDX, 9, 0x80000007, 0 },
|
|
||||||
{ X86_FEATURE_PROC_FEEDBACK, CPUID_EDX, 11, 0x80000007, 0 },
|
|
||||||
- { X86_FEATURE_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 },
|
|
||||||
+ { X86_FEATURE_AMD_FAST_CPPC, CPUID_EDX, 15, 0x80000007, 0 },
|
|
||||||
{ X86_FEATURE_MBA, CPUID_EBX, 6, 0x80000008, 0 },
|
|
||||||
{ X86_FEATURE_SMBA, CPUID_EBX, 2, 0x80000020, 0 },
|
|
||||||
{ X86_FEATURE_BMEC, CPUID_EBX, 3, 0x80000020, 0 },
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -880,7 +880,7 @@ static u32 amd_pstate_get_transition_del
|
|
||||||
|
|
||||||
transition_delay_ns = cppc_get_transition_latency(cpu);
|
|
||||||
if (transition_delay_ns == CPUFREQ_ETERNAL) {
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_FAST_CPPC))
|
|
||||||
+ if (cpu_feature_enabled(X86_FEATURE_AMD_FAST_CPPC))
|
|
||||||
return AMD_PSTATE_FAST_CPPC_TRANSITION_DELAY;
|
|
||||||
else
|
|
||||||
return AMD_PSTATE_TRANSITION_DELAY;
|
|
||||||
--- a/tools/arch/x86/include/asm/cpufeatures.h
|
|
||||||
+++ b/tools/arch/x86/include/asm/cpufeatures.h
|
|
||||||
@@ -472,7 +472,7 @@
|
|
||||||
#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* BHI_DIS_S HW control available */
|
|
||||||
#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* BHI_DIS_S HW control enabled */
|
|
||||||
#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
|
||||||
-#define X86_FEATURE_FAST_CPPC (21*32 + 5) /* AMD Fast CPPC */
|
|
||||||
+#define X86_FEATURE_AMD_FAST_CPPC (21*32 + 5) /* AMD Fast CPPC */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BUG word(s)
|
|
@ -1,43 +0,0 @@
|
|||||||
From 34ef29430b9a217ef0811f218b8f86c631d6c574 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Date: Fri, 25 Oct 2024 12:14:56 -0500
|
|
||||||
Subject: x86/cpufeatures: Add feature bits for AMD heterogeneous processor
|
|
||||||
|
|
||||||
CPUID leaf 0x80000026 advertises core types with different efficiency
|
|
||||||
rankings.
|
|
||||||
|
|
||||||
Bit 30 indicates the heterogeneous core topology feature, if the bit
|
|
||||||
set, it means not all instances at the current hierarchical level have
|
|
||||||
the same core topology.
|
|
||||||
|
|
||||||
This is described in the AMD64 Architecture Programmers Manual Volume
|
|
||||||
2 and 3, doc ID #25493 and #25494.
|
|
||||||
|
|
||||||
Signed-off-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/include/asm/cpufeatures.h | 1 +
|
|
||||||
arch/x86/kernel/cpu/scattered.c | 1 +
|
|
||||||
2 files changed, 2 insertions(+)
|
|
||||||
|
|
||||||
--- a/arch/x86/include/asm/cpufeatures.h
|
|
||||||
+++ b/arch/x86/include/asm/cpufeatures.h
|
|
||||||
@@ -474,6 +474,7 @@
|
|
||||||
#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* BHI_DIS_S HW control enabled */
|
|
||||||
#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* Clear branch history at vmexit using SW loop */
|
|
||||||
#define X86_FEATURE_AMD_FAST_CPPC (21*32 + 5) /* Fast CPPC */
|
|
||||||
+#define X86_FEATURE_AMD_HETEROGENEOUS_CORES (21*32 + 6) /* Heterogeneous Core Topology */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* BUG word(s)
|
|
||||||
--- a/arch/x86/kernel/cpu/scattered.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/scattered.c
|
|
||||||
@@ -52,6 +52,7 @@ static const struct cpuid_bit cpuid_bits
|
|
||||||
{ X86_FEATURE_PERFMON_V2, CPUID_EAX, 0, 0x80000022, 0 },
|
|
||||||
{ X86_FEATURE_AMD_LBR_V2, CPUID_EAX, 1, 0x80000022, 0 },
|
|
||||||
{ X86_FEATURE_AMD_LBR_PMC_FREEZE, CPUID_EAX, 2, 0x80000022, 0 },
|
|
||||||
+ { X86_FEATURE_AMD_HETEROGENEOUS_CORES, CPUID_EAX, 30, 0x80000026, 0 },
|
|
||||||
{ 0, 0, 0, 0, 0 }
|
|
||||||
};
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
|||||||
From 5bd4c7b75f5588eb81bee35179569e27a4e164e4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Date: Fri, 25 Oct 2024 12:14:57 -0500
|
|
||||||
Subject: x86/cpu: Enable SD_ASYM_PACKING for PKG Domain on AMD Processors
|
|
||||||
|
|
||||||
Enable the SD_ASYM_PACKING domain flag for the PKG domain on AMD
|
|
||||||
heterogeneous processors.
|
|
||||||
This flag is beneficial for processors with one or more CCDs and
|
|
||||||
relies on x86_sched_itmt_flags().
|
|
||||||
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Signed-off-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/kernel/smpboot.c | 5 +++--
|
|
||||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/kernel/smpboot.c
|
|
||||||
+++ b/arch/x86/kernel/smpboot.c
|
|
||||||
@@ -497,8 +497,9 @@ static int x86_cluster_flags(void)
|
|
||||||
|
|
||||||
static int x86_die_flags(void)
|
|
||||||
{
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
|
|
||||||
- return x86_sched_itmt_flags();
|
|
||||||
+ if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU) ||
|
|
||||||
+ cpu_feature_enabled(X86_FEATURE_AMD_HETEROGENEOUS_CORES))
|
|
||||||
+ return x86_sched_itmt_flags();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,187 +0,0 @@
|
|||||||
From c30f11be765d5a5a68e975fbe720a4bdb6900388 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
|
|
||||||
Date: Fri, 25 Oct 2024 12:14:58 -0500
|
|
||||||
Subject: x86/cpu: Add CPU type to struct cpuinfo_topology
|
|
||||||
|
|
||||||
Sometimes it is required to take actions based on if a CPU is a performance
|
|
||||||
or efficiency core. As an example, intel_pstate driver uses the Intel
|
|
||||||
core-type to determine CPU scaling. Also, some CPU vulnerabilities only
|
|
||||||
affect a specific CPU type, like RFDS only affects Intel Atom. Hybrid
|
|
||||||
systems that have variants P+E, P-only(Core) and E-only(Atom), it is not
|
|
||||||
straightforward to identify which variant is affected by a type specific
|
|
||||||
vulnerability.
|
|
||||||
|
|
||||||
Such processors do have CPUID field that can uniquely identify them. Like,
|
|
||||||
P+E, P-only and E-only enumerates CPUID.1A.CORE_TYPE identification, while
|
|
||||||
P+E additionally enumerates CPUID.7.HYBRID. Based on this information, it
|
|
||||||
is possible for boot CPU to identify if a system has mixed CPU types.
|
|
||||||
|
|
||||||
Add a new field hw_cpu_type to struct cpuinfo_topology that stores the
|
|
||||||
hardware specific CPU type. This saves the overhead of IPIs to get the CPU
|
|
||||||
type of a different CPU. CPU type is populated early in the boot process,
|
|
||||||
before vulnerabilities are enumerated.
|
|
||||||
|
|
||||||
Acked-by: Dave Hansen <dave.hansen@linux.intel.com>
|
|
||||||
Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
|
|
||||||
Co-developed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/include/asm/intel-family.h | 6 +++++
|
|
||||||
arch/x86/include/asm/processor.h | 18 ++++++++++++++
|
|
||||||
arch/x86/include/asm/topology.h | 9 +++++++
|
|
||||||
arch/x86/kernel/cpu/debugfs.c | 1 +
|
|
||||||
arch/x86/kernel/cpu/topology_amd.c | 3 +++
|
|
||||||
arch/x86/kernel/cpu/topology_common.c | 34 +++++++++++++++++++++++++++
|
|
||||||
6 files changed, 71 insertions(+)
|
|
||||||
|
|
||||||
--- a/arch/x86/include/asm/intel-family.h
|
|
||||||
+++ b/arch/x86/include/asm/intel-family.h
|
|
||||||
@@ -183,4 +183,10 @@
|
|
||||||
/* Family 19 */
|
|
||||||
#define INTEL_PANTHERCOVE_X IFM(19, 0x01) /* Diamond Rapids */
|
|
||||||
|
|
||||||
+/* CPU core types */
|
|
||||||
+enum intel_cpu_type {
|
|
||||||
+ INTEL_CPU_TYPE_ATOM = 0x20,
|
|
||||||
+ INTEL_CPU_TYPE_CORE = 0x40,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
#endif /* _ASM_X86_INTEL_FAMILY_H */
|
|
||||||
--- a/arch/x86/include/asm/processor.h
|
|
||||||
+++ b/arch/x86/include/asm/processor.h
|
|
||||||
@@ -105,6 +105,24 @@ struct cpuinfo_topology {
|
|
||||||
// Cache level topology IDs
|
|
||||||
u32 llc_id;
|
|
||||||
u32 l2c_id;
|
|
||||||
+
|
|
||||||
+ // Hardware defined CPU-type
|
|
||||||
+ union {
|
|
||||||
+ u32 cpu_type;
|
|
||||||
+ struct {
|
|
||||||
+ // CPUID.1A.EAX[23-0]
|
|
||||||
+ u32 intel_native_model_id :24;
|
|
||||||
+ // CPUID.1A.EAX[31-24]
|
|
||||||
+ u32 intel_type :8;
|
|
||||||
+ };
|
|
||||||
+ struct {
|
|
||||||
+ // CPUID 0x80000026.EBX
|
|
||||||
+ u32 amd_num_processors :16,
|
|
||||||
+ amd_power_eff_ranking :8,
|
|
||||||
+ amd_native_model_id :4,
|
|
||||||
+ amd_type :4;
|
|
||||||
+ };
|
|
||||||
+ };
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cpuinfo_x86 {
|
|
||||||
--- a/arch/x86/include/asm/topology.h
|
|
||||||
+++ b/arch/x86/include/asm/topology.h
|
|
||||||
@@ -114,6 +114,12 @@ enum x86_topology_domains {
|
|
||||||
TOPO_MAX_DOMAIN,
|
|
||||||
};
|
|
||||||
|
|
||||||
+enum x86_topology_cpu_type {
|
|
||||||
+ TOPO_CPU_TYPE_PERFORMANCE,
|
|
||||||
+ TOPO_CPU_TYPE_EFFICIENCY,
|
|
||||||
+ TOPO_CPU_TYPE_UNKNOWN,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
struct x86_topology_system {
|
|
||||||
unsigned int dom_shifts[TOPO_MAX_DOMAIN];
|
|
||||||
unsigned int dom_size[TOPO_MAX_DOMAIN];
|
|
||||||
@@ -149,6 +155,9 @@ extern unsigned int __max_threads_per_co
|
|
||||||
extern unsigned int __num_threads_per_package;
|
|
||||||
extern unsigned int __num_cores_per_package;
|
|
||||||
|
|
||||||
+const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c);
|
|
||||||
+enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c);
|
|
||||||
+
|
|
||||||
static inline unsigned int topology_max_packages(void)
|
|
||||||
{
|
|
||||||
return __max_logical_packages;
|
|
||||||
--- a/arch/x86/kernel/cpu/debugfs.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/debugfs.c
|
|
||||||
@@ -22,6 +22,7 @@ static int cpu_debug_show(struct seq_fil
|
|
||||||
seq_printf(m, "die_id: %u\n", c->topo.die_id);
|
|
||||||
seq_printf(m, "cu_id: %u\n", c->topo.cu_id);
|
|
||||||
seq_printf(m, "core_id: %u\n", c->topo.core_id);
|
|
||||||
+ seq_printf(m, "cpu_type: %s\n", get_topology_cpu_type_name(c));
|
|
||||||
seq_printf(m, "logical_pkg_id: %u\n", c->topo.logical_pkg_id);
|
|
||||||
seq_printf(m, "logical_die_id: %u\n", c->topo.logical_die_id);
|
|
||||||
seq_printf(m, "llc_id: %u\n", c->topo.llc_id);
|
|
||||||
--- a/arch/x86/kernel/cpu/topology_amd.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/topology_amd.c
|
|
||||||
@@ -182,6 +182,9 @@ static void parse_topology_amd(struct to
|
|
||||||
if (cpu_feature_enabled(X86_FEATURE_TOPOEXT))
|
|
||||||
has_topoext = cpu_parse_topology_ext(tscan);
|
|
||||||
|
|
||||||
+ if (cpu_feature_enabled(X86_FEATURE_AMD_HETEROGENEOUS_CORES))
|
|
||||||
+ tscan->c->topo.cpu_type = cpuid_ebx(0x80000026);
|
|
||||||
+
|
|
||||||
if (!has_topoext && !parse_8000_0008(tscan))
|
|
||||||
return;
|
|
||||||
|
|
||||||
--- a/arch/x86/kernel/cpu/topology_common.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/topology_common.c
|
|
||||||
@@ -3,6 +3,7 @@
|
|
||||||
|
|
||||||
#include <xen/xen.h>
|
|
||||||
|
|
||||||
+#include <asm/intel-family.h>
|
|
||||||
#include <asm/apic.h>
|
|
||||||
#include <asm/processor.h>
|
|
||||||
#include <asm/smp.h>
|
|
||||||
@@ -27,6 +28,36 @@ void topology_set_dom(struct topo_scan *
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c)
|
|
||||||
+{
|
|
||||||
+ if (c->x86_vendor == X86_VENDOR_INTEL) {
|
|
||||||
+ switch (c->topo.intel_type) {
|
|
||||||
+ case INTEL_CPU_TYPE_ATOM: return TOPO_CPU_TYPE_EFFICIENCY;
|
|
||||||
+ case INTEL_CPU_TYPE_CORE: return TOPO_CPU_TYPE_PERFORMANCE;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ if (c->x86_vendor == X86_VENDOR_AMD) {
|
|
||||||
+ switch (c->topo.amd_type) {
|
|
||||||
+ case 0: return TOPO_CPU_TYPE_PERFORMANCE;
|
|
||||||
+ case 1: return TOPO_CPU_TYPE_EFFICIENCY;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return TOPO_CPU_TYPE_UNKNOWN;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c)
|
|
||||||
+{
|
|
||||||
+ switch (get_topology_cpu_type(c)) {
|
|
||||||
+ case TOPO_CPU_TYPE_PERFORMANCE:
|
|
||||||
+ return "performance";
|
|
||||||
+ case TOPO_CPU_TYPE_EFFICIENCY:
|
|
||||||
+ return "efficiency";
|
|
||||||
+ default:
|
|
||||||
+ return "unknown";
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static unsigned int __maybe_unused parse_num_cores_legacy(struct cpuinfo_x86 *c)
|
|
||||||
{
|
|
||||||
struct {
|
|
||||||
@@ -87,6 +118,7 @@ static void parse_topology(struct topo_s
|
|
||||||
.cu_id = 0xff,
|
|
||||||
.llc_id = BAD_APICID,
|
|
||||||
.l2c_id = BAD_APICID,
|
|
||||||
+ .cpu_type = TOPO_CPU_TYPE_UNKNOWN,
|
|
||||||
};
|
|
||||||
struct cpuinfo_x86 *c = tscan->c;
|
|
||||||
struct {
|
|
||||||
@@ -132,6 +164,8 @@ static void parse_topology(struct topo_s
|
|
||||||
case X86_VENDOR_INTEL:
|
|
||||||
if (!IS_ENABLED(CONFIG_CPU_SUP_INTEL) || !cpu_parse_topology_ext(tscan))
|
|
||||||
parse_legacy(tscan);
|
|
||||||
+ if (c->cpuid_level >= 0x1a)
|
|
||||||
+ c->topo.cpu_type = cpuid_eax(0x1a);
|
|
||||||
break;
|
|
||||||
case X86_VENDOR_HYGON:
|
|
||||||
if (IS_ENABLED(CONFIG_CPU_SUP_HYGON))
|
|
@ -1,71 +0,0 @@
|
|||||||
From ab9618cbe5e3d55b09b59f5e18e890be80ca1076 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Fri, 25 Oct 2024 12:14:59 -0500
|
|
||||||
Subject: x86/amd: Use heterogeneous core topology for identifying boost
|
|
||||||
numerator
|
|
||||||
|
|
||||||
AMD heterogeneous designs include two types of cores:
|
|
||||||
* Performance
|
|
||||||
* Efficiency
|
|
||||||
|
|
||||||
Each core type has different highest performance values configured by the
|
|
||||||
platform. Drivers such as `amd_pstate` need to identify the type of
|
|
||||||
core to correctly set an appropriate boost numerator to calculate the
|
|
||||||
maximum frequency.
|
|
||||||
|
|
||||||
X86_FEATURE_AMD_HETEROGENEOUS_CORES is used to identify whether the SoC
|
|
||||||
supports heterogeneous core type by reading CPUID leaf Fn_0x80000026.
|
|
||||||
|
|
||||||
On performance cores the scaling factor of 196 is used. On efficiency
|
|
||||||
cores the scaling factor is the value reported as the highest perf.
|
|
||||||
Efficiency cores have the same preferred core rankings.
|
|
||||||
|
|
||||||
Tested-by: Eric Naim <dnaim@cachyos.org>
|
|
||||||
Tested-by: Peter Jung <ptr1337@cachyos.org>
|
|
||||||
Suggested-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/kernel/acpi/cppc.c | 23 +++++++++++++++++++++++
|
|
||||||
1 file changed, 23 insertions(+)
|
|
||||||
|
|
||||||
--- a/arch/x86/kernel/acpi/cppc.c
|
|
||||||
+++ b/arch/x86/kernel/acpi/cppc.c
|
|
||||||
@@ -239,8 +239,10 @@ EXPORT_SYMBOL_GPL(amd_detect_prefcore);
|
|
||||||
*/
|
|
||||||
int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator)
|
|
||||||
{
|
|
||||||
+ enum x86_topology_cpu_type core_type = get_topology_cpu_type(&cpu_data(cpu));
|
|
||||||
bool prefcore;
|
|
||||||
int ret;
|
|
||||||
+ u32 tmp;
|
|
||||||
|
|
||||||
ret = amd_detect_prefcore(&prefcore);
|
|
||||||
if (ret)
|
|
||||||
@@ -266,6 +268,27 @@ int amd_get_boost_ratio_numerator(unsign
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /* detect if running on heterogeneous design */
|
|
||||||
+ if (cpu_feature_enabled(X86_FEATURE_AMD_HETEROGENEOUS_CORES)) {
|
|
||||||
+ switch (core_type) {
|
|
||||||
+ case TOPO_CPU_TYPE_UNKNOWN:
|
|
||||||
+ pr_warn("Undefined core type found for cpu %d\n", cpu);
|
|
||||||
+ break;
|
|
||||||
+ case TOPO_CPU_TYPE_PERFORMANCE:
|
|
||||||
+ /* use the max scale for performance cores */
|
|
||||||
+ *numerator = CPPC_HIGHEST_PERF_PERFORMANCE;
|
|
||||||
+ return 0;
|
|
||||||
+ case TOPO_CPU_TYPE_EFFICIENCY:
|
|
||||||
+ /* use the highest perf value for efficiency cores */
|
|
||||||
+ ret = amd_get_highest_perf(cpu, &tmp);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+ *numerator = tmp;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
*numerator = CPPC_HIGHEST_PERF_PREFCORE;
|
|
||||||
|
|
||||||
return 0;
|
|
@ -1,38 +0,0 @@
|
|||||||
From f1a423d6cfc0888638642bea1b8ed5c64770888c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Mon, 28 Oct 2024 09:55:41 -0500
|
|
||||||
Subject: cpufreq/amd-pstate: Push adjust_perf vfunc init into cpu_init
|
|
||||||
|
|
||||||
As the driver can be changed in and out of different modes it's possible
|
|
||||||
that adjust_perf is assigned when it shouldn't be.
|
|
||||||
|
|
||||||
This could happen if an MSR design is started up in passive mode and then
|
|
||||||
switches to active mode.
|
|
||||||
|
|
||||||
To solve this explicitly clear `adjust_perf` in amd_pstate_epp_cpu_init().
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 4 ++--
|
|
||||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1534,6 +1534,8 @@ static int amd_pstate_epp_cpu_init(struc
|
|
||||||
WRITE_ONCE(cpudata->cppc_cap1_cached, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ current_pstate_driver->adjust_perf = NULL;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
free_cpudata1:
|
|
||||||
@@ -1896,8 +1898,6 @@ static int __init amd_pstate_init(void)
|
|
||||||
/* capability check */
|
|
||||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
pr_debug("AMD CPPC MSR based functionality is supported\n");
|
|
||||||
- if (cppc_state != AMD_PSTATE_ACTIVE)
|
|
||||||
- current_pstate_driver->adjust_perf = amd_pstate_adjust_perf;
|
|
||||||
} else {
|
|
||||||
pr_debug("AMD CPPC shared memory based functionality is supported\n");
|
|
||||||
static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable);
|
|
@ -1,47 +0,0 @@
|
|||||||
From 242ffb086a15c8aec549096a6ad96d186b670fa9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Mon, 28 Oct 2024 09:55:42 -0500
|
|
||||||
Subject: cpufreq/amd-pstate: Move registration after static function call
|
|
||||||
update
|
|
||||||
|
|
||||||
On shared memory designs the static functions need to work before
|
|
||||||
registration is done or the system can hang at bootup.
|
|
||||||
|
|
||||||
Move the registration later in amd_pstate_init() to solve this.
|
|
||||||
|
|
||||||
Fixes: e238968a2087 ("cpufreq/amd-pstate: Remove the redundant amd_pstate_set_driver() call")
|
|
||||||
Reported-by: Klara Modin <klarasmodin@gmail.com>
|
|
||||||
Closes: https://lore.kernel.org/linux-pm/cf9c146d-bacf-444e-92e2-15ebf513af96@gmail.com/#t
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 12 ++++++------
|
|
||||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1889,12 +1889,6 @@ static int __init amd_pstate_init(void)
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = amd_pstate_register_driver(cppc_state);
|
|
||||||
- if (ret) {
|
|
||||||
- pr_err("failed to register with return %d\n", ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* capability check */
|
|
||||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
pr_debug("AMD CPPC MSR based functionality is supported\n");
|
|
||||||
@@ -1905,6 +1899,12 @@ static int __init amd_pstate_init(void)
|
|
||||||
static_call_update(amd_pstate_update_perf, shmem_update_perf);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ ret = amd_pstate_register_driver(cppc_state);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_err("failed to register with return %d\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (amd_pstate_prefcore) {
|
|
||||||
ret = amd_detect_prefcore(&amd_pstate_prefcore);
|
|
||||||
if (ret)
|
|
@ -1,152 +0,0 @@
|
|||||||
From f6e6b4ebc5ef3ad05b291928d31f597210a2eb6e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 4 Dec 2024 14:48:38 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Convert the amd_pstate_get/set_epp() to static
|
|
||||||
calls
|
|
||||||
|
|
||||||
MSR and shared memory based systems have different mechanisms to get and
|
|
||||||
set the epp value. Split those mechanisms into different functions and
|
|
||||||
assign them appropriately to the static calls at boot time. This eliminates
|
|
||||||
the need for the "if(cpu_feature_enabled(X86_FEATURE_CPPC))" checks at
|
|
||||||
runtime.
|
|
||||||
|
|
||||||
Also, propagate the error code from rdmsrl_on_cpu() and cppc_get_epp_perf()
|
|
||||||
to *_get_epp()'s caller, instead of returning -EIO unconditionally.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 92 +++++++++++++++++++++++-------------
|
|
||||||
1 file changed, 60 insertions(+), 32 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -210,26 +210,40 @@ static inline int get_mode_idx_from_str(
|
|
||||||
static DEFINE_MUTEX(amd_pstate_limits_lock);
|
|
||||||
static DEFINE_MUTEX(amd_pstate_driver_lock);
|
|
||||||
|
|
||||||
-static s16 amd_pstate_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|
||||||
+static s16 msr_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|
||||||
{
|
|
||||||
u64 epp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
- if (!cppc_req_cached) {
|
|
||||||
- epp = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
|
||||||
- &cppc_req_cached);
|
|
||||||
- if (epp)
|
|
||||||
- return epp;
|
|
||||||
- }
|
|
||||||
- epp = (cppc_req_cached >> 24) & 0xFF;
|
|
||||||
- } else {
|
|
||||||
- ret = cppc_get_epp_perf(cpudata->cpu, &epp);
|
|
||||||
+ if (!cppc_req_cached) {
|
|
||||||
+ ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &cppc_req_cached);
|
|
||||||
if (ret < 0) {
|
|
||||||
pr_debug("Could not retrieve energy perf value (%d)\n", ret);
|
|
||||||
- return -EIO;
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ epp = (cppc_req_cached >> 24) & 0xFF;
|
|
||||||
+
|
|
||||||
+ return (s16)epp;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+DEFINE_STATIC_CALL(amd_pstate_get_epp, msr_get_epp);
|
|
||||||
+
|
|
||||||
+static inline s16 amd_pstate_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|
||||||
+{
|
|
||||||
+ return static_call(amd_pstate_get_epp)(cpudata, cppc_req_cached);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static s16 shmem_get_epp(struct amd_cpudata *cpudata, u64 dummy)
|
|
||||||
+{
|
|
||||||
+ u64 epp;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = cppc_get_epp_perf(cpudata->cpu, &epp);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ pr_debug("Could not retrieve energy perf value (%d)\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return (s16)(epp & 0xff);
|
|
||||||
}
|
|
||||||
@@ -283,33 +297,45 @@ static inline void amd_pstate_update_per
|
|
||||||
max_perf, fast_switch);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
+static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
- struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
- u64 value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
+ u64 value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
|
|
||||||
- value &= ~GENMASK_ULL(31, 24);
|
|
||||||
- value |= (u64)epp << 24;
|
|
||||||
- WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
-
|
|
||||||
- ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
- if (!ret)
|
|
||||||
- cpudata->epp_cached = epp;
|
|
||||||
- } else {
|
|
||||||
- amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
- cpudata->max_limit_perf, false);
|
|
||||||
+ value &= ~GENMASK_ULL(31, 24);
|
|
||||||
+ value |= (u64)epp << 24;
|
|
||||||
+ WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
- perf_ctrls.energy_perf = epp;
|
|
||||||
- ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
- if (ret) {
|
|
||||||
- pr_debug("failed to set energy perf value (%d)\n", ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
+ ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
+ if (!ret)
|
|
||||||
cpudata->epp_cached = epp;
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+DEFINE_STATIC_CALL(amd_pstate_set_epp, msr_set_epp);
|
|
||||||
+
|
|
||||||
+static inline int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
+{
|
|
||||||
+ return static_call(amd_pstate_set_epp)(cpudata, epp);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int shmem_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+ struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
+
|
|
||||||
+ amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
+ cpudata->max_limit_perf, false);
|
|
||||||
+
|
|
||||||
+ perf_ctrls.energy_perf = epp;
|
|
||||||
+ ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_debug("failed to set energy perf value (%d)\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
+ cpudata->epp_cached = epp;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1897,6 +1923,8 @@ static int __init amd_pstate_init(void)
|
|
||||||
static_call_update(amd_pstate_cppc_enable, shmem_cppc_enable);
|
|
||||||
static_call_update(amd_pstate_init_perf, shmem_init_perf);
|
|
||||||
static_call_update(amd_pstate_update_perf, shmem_update_perf);
|
|
||||||
+ static_call_update(amd_pstate_get_epp, shmem_get_epp);
|
|
||||||
+ static_call_update(amd_pstate_set_epp, shmem_set_epp);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = amd_pstate_register_driver(cppc_state);
|
|
@ -1,38 +0,0 @@
|
|||||||
From e73d7f9cb6d8f0e79860788371c88f88057ae34b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 4 Dec 2024 14:48:39 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Move the invocation of amd_pstate_update_perf()
|
|
||||||
|
|
||||||
amd_pstate_update_perf() should not be a part of shmem_set_epp() function,
|
|
||||||
so move it to the amd_pstate_epp_update_limit() function, where it is needed.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 7 ++++---
|
|
||||||
1 file changed, 4 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -326,9 +326,6 @@ static int shmem_set_epp(struct amd_cpud
|
|
||||||
int ret;
|
|
||||||
struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
|
|
||||||
- amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
- cpudata->max_limit_perf, false);
|
|
||||||
-
|
|
||||||
perf_ctrls.energy_perf = epp;
|
|
||||||
ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
if (ret) {
|
|
||||||
@@ -1628,6 +1625,10 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
epp = 0;
|
|
||||||
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
+
|
|
||||||
+ amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
+ cpudata->max_limit_perf, false);
|
|
||||||
+
|
|
||||||
return amd_pstate_set_epp(cpudata, epp);
|
|
||||||
}
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
|||||||
From 021028e977fcd835ed92a4543f7977a8aa0c1dd6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 4 Dec 2024 14:48:40 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Refactor amd_pstate_epp_reenable() and
|
|
||||||
amd_pstate_epp_offline()
|
|
||||||
|
|
||||||
Replace similar code chunks with amd_pstate_update_perf() and
|
|
||||||
amd_pstate_set_epp() function calls.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 38 +++++++-----------------------------
|
|
||||||
1 file changed, 7 insertions(+), 31 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1660,25 +1660,17 @@ static int amd_pstate_epp_set_policy(str
|
|
||||||
|
|
||||||
static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
- struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
- u64 value, max_perf;
|
|
||||||
+ u64 max_perf;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = amd_pstate_cppc_enable(true);
|
|
||||||
if (ret)
|
|
||||||
pr_err("failed to enable amd pstate during resume, return %d\n", ret);
|
|
||||||
|
|
||||||
- value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
- wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
- } else {
|
|
||||||
- perf_ctrls.max_perf = max_perf;
|
|
||||||
- cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
- perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(cpudata->epp_cached);
|
|
||||||
- cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
- }
|
|
||||||
+ amd_pstate_update_perf(cpudata, 0, 0, max_perf, false);
|
|
||||||
+ amd_pstate_set_epp(cpudata, cpudata->epp_cached);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy)
|
|
||||||
@@ -1698,31 +1690,15 @@ static int amd_pstate_epp_cpu_online(str
|
|
||||||
static void amd_pstate_epp_offline(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
- struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
int min_perf;
|
|
||||||
- u64 value;
|
|
||||||
|
|
||||||
min_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
- value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
|
|
||||||
mutex_lock(&amd_pstate_limits_lock);
|
|
||||||
- if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
- cpudata->epp_policy = CPUFREQ_POLICY_UNKNOWN;
|
|
||||||
|
|
||||||
- /* Set max perf same as min perf */
|
|
||||||
- value &= ~AMD_CPPC_MAX_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_MAX_PERF(min_perf);
|
|
||||||
- value &= ~AMD_CPPC_MIN_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_MIN_PERF(min_perf);
|
|
||||||
- wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
- } else {
|
|
||||||
- perf_ctrls.desired_perf = 0;
|
|
||||||
- perf_ctrls.min_perf = min_perf;
|
|
||||||
- perf_ctrls.max_perf = min_perf;
|
|
||||||
- cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
- perf_ctrls.energy_perf = AMD_CPPC_ENERGY_PERF_PREF(HWP_EPP_BALANCE_POWERSAVE);
|
|
||||||
- cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
- }
|
|
||||||
+ amd_pstate_update_perf(cpudata, min_perf, 0, min_perf, false);
|
|
||||||
+ amd_pstate_set_epp(cpudata, AMD_CPPC_EPP_BALANCE_POWERSAVE);
|
|
||||||
+
|
|
||||||
mutex_unlock(&amd_pstate_limits_lock);
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
|||||||
From f94f6415c70f76d885dd542e8631f826f427941e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 4 Dec 2024 14:48:41 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Remove the cppc_state check in offline/online
|
|
||||||
functions
|
|
||||||
|
|
||||||
Only amd_pstate_epp driver (i.e. cppc_state = ACTIVE) enters the
|
|
||||||
amd_pstate_epp_offline() and amd_pstate_epp_cpu_online() functions,
|
|
||||||
so remove the unnecessary if condition checking if cppc_state is
|
|
||||||
equal to AMD_PSTATE_ACTIVE.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 9 +++------
|
|
||||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1679,10 +1679,8 @@ static int amd_pstate_epp_cpu_online(str
|
|
||||||
|
|
||||||
pr_debug("AMD CPU Core %d going online\n", cpudata->cpu);
|
|
||||||
|
|
||||||
- if (cppc_state == AMD_PSTATE_ACTIVE) {
|
|
||||||
- amd_pstate_epp_reenable(cpudata);
|
|
||||||
- cpudata->suspended = false;
|
|
||||||
- }
|
|
||||||
+ amd_pstate_epp_reenable(cpudata);
|
|
||||||
+ cpudata->suspended = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1711,8 +1709,7 @@ static int amd_pstate_epp_cpu_offline(st
|
|
||||||
if (cpudata->suspended)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
- if (cppc_state == AMD_PSTATE_ACTIVE)
|
|
||||||
- amd_pstate_epp_offline(policy);
|
|
||||||
+ amd_pstate_epp_offline(policy);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
From 5aea3e8c4255cb04876e3af714d58ed329376b7f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Wed, 4 Dec 2024 14:48:42 +0000
|
|
||||||
Subject: cpufreq/amd-pstate: Merge amd_pstate_epp_cpu_offline() and
|
|
||||||
amd_pstate_epp_offline()
|
|
||||||
|
|
||||||
amd_pstate_epp_offline() is only called from within
|
|
||||||
amd_pstate_epp_cpu_offline() and doesn't make much sense to have it at all.
|
|
||||||
Hence, remove it.
|
|
||||||
|
|
||||||
Also remove the unncessary debug print in the offline path while at it.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 17 ++++-------------
|
|
||||||
1 file changed, 4 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1685,11 +1685,14 @@ static int amd_pstate_epp_cpu_online(str
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void amd_pstate_epp_offline(struct cpufreq_policy *policy)
|
|
||||||
+static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
int min_perf;
|
|
||||||
|
|
||||||
+ if (cpudata->suspended)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
min_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
|
|
||||||
mutex_lock(&amd_pstate_limits_lock);
|
|
||||||
@@ -1698,18 +1701,6 @@ static void amd_pstate_epp_offline(struc
|
|
||||||
amd_pstate_set_epp(cpudata, AMD_CPPC_EPP_BALANCE_POWERSAVE);
|
|
||||||
|
|
||||||
mutex_unlock(&amd_pstate_limits_lock);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int amd_pstate_epp_cpu_offline(struct cpufreq_policy *policy)
|
|
||||||
-{
|
|
||||||
- struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
-
|
|
||||||
- pr_debug("AMD CPU Core %d going offline\n", cpudata->cpu);
|
|
||||||
-
|
|
||||||
- if (cpudata->suspended)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- amd_pstate_epp_offline(policy);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,132 +0,0 @@
|
|||||||
From ea6b500eb38124a59e83254435340e0390117c54 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:33 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Add trace event for EPP perf updates
|
|
||||||
|
|
||||||
In "active" mode the most important thing for debugging whether
|
|
||||||
an issue is hardware or software based is to look at what was the
|
|
||||||
last thing written to the CPPC request MSR or shared memory region.
|
|
||||||
|
|
||||||
The 'amd_pstate_epp_perf' trace event shows the values being written
|
|
||||||
for all CPUs.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Perry Yuan <perry.yuan@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate-trace.h | 45 ++++++++++++++++++++++++++++++
|
|
||||||
drivers/cpufreq/amd-pstate.c | 28 +++++++++++++++++++
|
|
||||||
2 files changed, 73 insertions(+)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate-trace.h
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate-trace.h
|
|
||||||
@@ -88,6 +88,51 @@ TRACE_EVENT(amd_pstate_perf,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
+TRACE_EVENT(amd_pstate_epp_perf,
|
|
||||||
+
|
|
||||||
+ TP_PROTO(unsigned int cpu_id,
|
|
||||||
+ unsigned int highest_perf,
|
|
||||||
+ unsigned int epp,
|
|
||||||
+ unsigned int min_perf,
|
|
||||||
+ unsigned int max_perf,
|
|
||||||
+ bool boost
|
|
||||||
+ ),
|
|
||||||
+
|
|
||||||
+ TP_ARGS(cpu_id,
|
|
||||||
+ highest_perf,
|
|
||||||
+ epp,
|
|
||||||
+ min_perf,
|
|
||||||
+ max_perf,
|
|
||||||
+ boost),
|
|
||||||
+
|
|
||||||
+ TP_STRUCT__entry(
|
|
||||||
+ __field(unsigned int, cpu_id)
|
|
||||||
+ __field(unsigned int, highest_perf)
|
|
||||||
+ __field(unsigned int, epp)
|
|
||||||
+ __field(unsigned int, min_perf)
|
|
||||||
+ __field(unsigned int, max_perf)
|
|
||||||
+ __field(bool, boost)
|
|
||||||
+ ),
|
|
||||||
+
|
|
||||||
+ TP_fast_assign(
|
|
||||||
+ __entry->cpu_id = cpu_id;
|
|
||||||
+ __entry->highest_perf = highest_perf;
|
|
||||||
+ __entry->epp = epp;
|
|
||||||
+ __entry->min_perf = min_perf;
|
|
||||||
+ __entry->max_perf = max_perf;
|
|
||||||
+ __entry->boost = boost;
|
|
||||||
+ ),
|
|
||||||
+
|
|
||||||
+ TP_printk("cpu%u: [%u<->%u]/%u, epp=%u, boost=%u",
|
|
||||||
+ (unsigned int)__entry->cpu_id,
|
|
||||||
+ (unsigned int)__entry->min_perf,
|
|
||||||
+ (unsigned int)__entry->max_perf,
|
|
||||||
+ (unsigned int)__entry->highest_perf,
|
|
||||||
+ (unsigned int)__entry->epp,
|
|
||||||
+ (bool)__entry->boost
|
|
||||||
+ )
|
|
||||||
+);
|
|
||||||
+
|
|
||||||
#endif /* _AMD_PSTATE_TRACE_H */
|
|
||||||
|
|
||||||
/* This part must be outside protection */
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -354,6 +354,14 @@ static int amd_pstate_set_energy_pref_in
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
+ trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
|
|
||||||
+ epp,
|
|
||||||
+ AMD_CPPC_MIN_PERF(cpudata->cppc_req_cached),
|
|
||||||
+ AMD_CPPC_MAX_PERF(cpudata->cppc_req_cached),
|
|
||||||
+ cpudata->boost_state);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
ret = amd_pstate_set_epp(cpudata, epp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
@@ -1626,6 +1634,13 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
+ if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
+ trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf, epp,
|
|
||||||
+ cpudata->min_limit_perf,
|
|
||||||
+ cpudata->max_limit_perf,
|
|
||||||
+ cpudata->boost_state);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
cpudata->max_limit_perf, false);
|
|
||||||
|
|
||||||
@@ -1669,6 +1684,13 @@ static void amd_pstate_epp_reenable(stru
|
|
||||||
|
|
||||||
max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
|
|
||||||
+ if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
+ trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
|
|
||||||
+ cpudata->epp_cached,
|
|
||||||
+ AMD_CPPC_MIN_PERF(cpudata->cppc_req_cached),
|
|
||||||
+ max_perf, cpudata->boost_state);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
amd_pstate_update_perf(cpudata, 0, 0, max_perf, false);
|
|
||||||
amd_pstate_set_epp(cpudata, cpudata->epp_cached);
|
|
||||||
}
|
|
||||||
@@ -1697,6 +1719,12 @@ static int amd_pstate_epp_cpu_offline(st
|
|
||||||
|
|
||||||
mutex_lock(&amd_pstate_limits_lock);
|
|
||||||
|
|
||||||
+ if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
+ trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
|
|
||||||
+ AMD_CPPC_EPP_BALANCE_POWERSAVE,
|
|
||||||
+ min_perf, min_perf, cpudata->boost_state);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
amd_pstate_update_perf(cpudata, min_perf, 0, min_perf, false);
|
|
||||||
amd_pstate_set_epp(cpudata, AMD_CPPC_EPP_BALANCE_POWERSAVE);
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
|||||||
From 57fdcf14dcd80808fc46edea6d31bb2a699c0fd1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:34 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: convert mutex use to guard()
|
|
||||||
|
|
||||||
Using scoped guard declaration will unlock mutexes automatically.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 32 ++++++++++++--------------------
|
|
||||||
1 file changed, 12 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -782,12 +782,12 @@ static int amd_pstate_set_boost(struct c
|
|
||||||
pr_err("Boost mode is not supported by this processor or SBIOS\n");
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
- mutex_lock(&amd_pstate_driver_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_driver_lock);
|
|
||||||
+
|
|
||||||
ret = amd_pstate_cpu_boost_update(policy, state);
|
|
||||||
WRITE_ONCE(cpudata->boost_state, !ret ? state : false);
|
|
||||||
policy->boost_enabled = !ret ? state : false;
|
|
||||||
refresh_frequency_limits(policy);
|
|
||||||
- mutex_unlock(&amd_pstate_driver_lock);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -878,7 +878,8 @@ static void amd_pstate_update_limits(uns
|
|
||||||
if (!amd_pstate_prefcore)
|
|
||||||
return;
|
|
||||||
|
|
||||||
- mutex_lock(&amd_pstate_driver_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_driver_lock);
|
|
||||||
+
|
|
||||||
ret = amd_get_highest_perf(cpu, &cur_high);
|
|
||||||
if (ret)
|
|
||||||
goto free_cpufreq_put;
|
|
||||||
@@ -898,7 +899,6 @@ free_cpufreq_put:
|
|
||||||
if (!highest_perf_changed)
|
|
||||||
cpufreq_update_policy(cpu);
|
|
||||||
|
|
||||||
- mutex_unlock(&amd_pstate_driver_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1231,11 +1231,11 @@ static ssize_t store_energy_performance_
|
|
||||||
if (ret < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- mutex_lock(&amd_pstate_limits_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_limits_lock);
|
|
||||||
+
|
|
||||||
ret = amd_pstate_set_energy_pref_index(cpudata, ret);
|
|
||||||
- mutex_unlock(&amd_pstate_limits_lock);
|
|
||||||
|
|
||||||
- return ret ?: count;
|
|
||||||
+ return ret ? ret : count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t show_energy_performance_preference(
|
|
||||||
@@ -1399,13 +1399,10 @@ EXPORT_SYMBOL_GPL(amd_pstate_update_stat
|
|
||||||
static ssize_t status_show(struct device *dev,
|
|
||||||
struct device_attribute *attr, char *buf)
|
|
||||||
{
|
|
||||||
- ssize_t ret;
|
|
||||||
|
|
||||||
- mutex_lock(&amd_pstate_driver_lock);
|
|
||||||
- ret = amd_pstate_show_status(buf);
|
|
||||||
- mutex_unlock(&amd_pstate_driver_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_driver_lock);
|
|
||||||
|
|
||||||
- return ret;
|
|
||||||
+ return amd_pstate_show_status(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t status_store(struct device *a, struct device_attribute *b,
|
|
||||||
@@ -1414,9 +1411,8 @@ static ssize_t status_store(struct devic
|
|
||||||
char *p = memchr(buf, '\n', count);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- mutex_lock(&amd_pstate_driver_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_driver_lock);
|
|
||||||
ret = amd_pstate_update_status(buf, p ? p - buf : count);
|
|
||||||
- mutex_unlock(&amd_pstate_driver_lock);
|
|
||||||
|
|
||||||
return ret < 0 ? ret : count;
|
|
||||||
}
|
|
||||||
@@ -1717,7 +1713,7 @@ static int amd_pstate_epp_cpu_offline(st
|
|
||||||
|
|
||||||
min_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
|
|
||||||
- mutex_lock(&amd_pstate_limits_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_limits_lock);
|
|
||||||
|
|
||||||
if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
|
|
||||||
@@ -1728,8 +1724,6 @@ static int amd_pstate_epp_cpu_offline(st
|
|
||||||
amd_pstate_update_perf(cpudata, min_perf, 0, min_perf, false);
|
|
||||||
amd_pstate_set_epp(cpudata, AMD_CPPC_EPP_BALANCE_POWERSAVE);
|
|
||||||
|
|
||||||
- mutex_unlock(&amd_pstate_limits_lock);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1758,13 +1752,11 @@ static int amd_pstate_epp_resume(struct
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
|
|
||||||
if (cpudata->suspended) {
|
|
||||||
- mutex_lock(&amd_pstate_limits_lock);
|
|
||||||
+ guard(mutex)(&amd_pstate_limits_lock);
|
|
||||||
|
|
||||||
/* enable amd pstate from suspend state*/
|
|
||||||
amd_pstate_epp_reenable(cpudata);
|
|
||||||
|
|
||||||
- mutex_unlock(&amd_pstate_limits_lock);
|
|
||||||
-
|
|
||||||
cpudata->suspended = false;
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
|||||||
From 06c52df851256238253ec286682cafbd5bb832d8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:35 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Drop cached epp_policy variable
|
|
||||||
|
|
||||||
epp_policy is not used by any of the current code and there
|
|
||||||
is no need to cache it.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 3 ---
|
|
||||||
drivers/cpufreq/amd-pstate.h | 2 --
|
|
||||||
2 files changed, 5 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1506,7 +1506,6 @@ static int amd_pstate_epp_cpu_init(struc
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
cpudata->cpu = policy->cpu;
|
|
||||||
- cpudata->epp_policy = 0;
|
|
||||||
|
|
||||||
ret = amd_pstate_init_perf(cpudata);
|
|
||||||
if (ret)
|
|
||||||
@@ -1613,8 +1612,6 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
value &= ~AMD_CPPC_DES_PERF(~0L);
|
|
||||||
value |= AMD_CPPC_DES_PERF(0);
|
|
||||||
|
|
||||||
- cpudata->epp_policy = cpudata->policy;
|
|
||||||
-
|
|
||||||
/* Get BIOS pre-defined epp value */
|
|
||||||
epp = amd_pstate_get_epp(cpudata, value);
|
|
||||||
if (epp < 0) {
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.h
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.h
|
|
||||||
@@ -57,7 +57,6 @@ struct amd_aperf_mperf {
|
|
||||||
* @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
|
|
||||||
* @cppc_cap1_cached Cached MSR_AMD_CPPC_CAP1 register value
|
|
||||||
@@ -94,7 +93,6 @@ struct amd_cpudata {
|
|
||||||
bool hw_prefcore;
|
|
||||||
|
|
||||||
/* EPP feature related attributes*/
|
|
||||||
- s16 epp_policy;
|
|
||||||
s16 epp_cached;
|
|
||||||
u32 policy;
|
|
||||||
u64 cppc_cap1_cached;
|
|
@ -1,117 +0,0 @@
|
|||||||
From da3e84f3dd424c1b7fa6d86484ddcccac391e49c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:36 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Use FIELD_PREP and FIELD_GET macros
|
|
||||||
|
|
||||||
The FIELD_PREP and FIELD_GET macros improve readability and help
|
|
||||||
to avoid shifting bugs.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 45 ++++++++++++++++--------------------
|
|
||||||
1 file changed, 20 insertions(+), 25 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -22,6 +22,7 @@
|
|
||||||
|
|
||||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
||||||
|
|
||||||
+#include <linux/bitfield.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
@@ -88,6 +89,11 @@ static bool cppc_enabled;
|
|
||||||
static bool amd_pstate_prefcore = true;
|
|
||||||
static struct quirk_entry *quirks;
|
|
||||||
|
|
||||||
+#define AMD_PSTATE_MAX_PERF_MASK GENMASK(7, 0)
|
|
||||||
+#define AMD_PSTATE_MIN_PERF_MASK GENMASK(15, 8)
|
|
||||||
+#define AMD_PSTATE_DES_PERF_MASK GENMASK(23, 16)
|
|
||||||
+#define AMD_PSTATE_EPP_PERF_MASK GENMASK(31, 24)
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* AMD Energy Preference Performance (EPP)
|
|
||||||
* The EPP is used in the CCLK DPM controller to drive
|
|
||||||
@@ -212,7 +218,6 @@ static DEFINE_MUTEX(amd_pstate_driver_lo
|
|
||||||
|
|
||||||
static s16 msr_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|
||||||
{
|
|
||||||
- u64 epp;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!cppc_req_cached) {
|
|
||||||
@@ -222,9 +227,8 @@ static s16 msr_get_epp(struct amd_cpudat
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- epp = (cppc_req_cached >> 24) & 0xFF;
|
|
||||||
|
|
||||||
- return (s16)epp;
|
|
||||||
+ return FIELD_GET(AMD_PSTATE_EPP_PERF_MASK, cppc_req_cached);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_STATIC_CALL(amd_pstate_get_epp, msr_get_epp);
|
|
||||||
@@ -299,12 +303,11 @@ static inline void amd_pstate_update_per
|
|
||||||
|
|
||||||
static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
{
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
u64 value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
- value &= ~GENMASK_ULL(31, 24);
|
|
||||||
- value |= (u64)epp << 24;
|
|
||||||
+ value &= ~AMD_PSTATE_EPP_PERF_MASK;
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, epp);
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
@@ -563,18 +566,15 @@ static void amd_pstate_update(struct amd
|
|
||||||
des_perf = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- value &= ~AMD_CPPC_MIN_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_MIN_PERF(min_perf);
|
|
||||||
-
|
|
||||||
- value &= ~AMD_CPPC_DES_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_DES_PERF(des_perf);
|
|
||||||
-
|
|
||||||
/* limit the max perf when core performance boost feature is disabled */
|
|
||||||
if (!cpudata->boost_supported)
|
|
||||||
max_perf = min_t(unsigned long, nominal_perf, max_perf);
|
|
||||||
|
|
||||||
- value &= ~AMD_CPPC_MAX_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_MAX_PERF(max_perf);
|
|
||||||
+ value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
+ AMD_PSTATE_DES_PERF_MASK);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, des_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf);
|
|
||||||
|
|
||||||
if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
|
|
||||||
trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
|
|
||||||
@@ -1601,16 +1601,11 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
min_perf = min(cpudata->nominal_perf, max_perf);
|
|
||||||
|
|
||||||
- /* Initial min/max values for CPPC Performance Controls Register */
|
|
||||||
- value &= ~AMD_CPPC_MIN_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_MIN_PERF(min_perf);
|
|
||||||
-
|
|
||||||
- value &= ~AMD_CPPC_MAX_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_MAX_PERF(max_perf);
|
|
||||||
-
|
|
||||||
- /* CPPC EPP feature require to set zero to the desire perf bit */
|
|
||||||
- value &= ~AMD_CPPC_DES_PERF(~0L);
|
|
||||||
- value |= AMD_CPPC_DES_PERF(0);
|
|
||||||
+ value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
+ AMD_PSTATE_DES_PERF_MASK);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, 0);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf);
|
|
||||||
|
|
||||||
/* Get BIOS pre-defined epp value */
|
|
||||||
epp = amd_pstate_get_epp(cpudata, value);
|
|
@ -1,103 +0,0 @@
|
|||||||
From b1e3f18eb18f9febe9f4e32a1ef55cf60c97892a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:37 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Store the boost numerator as highest perf again
|
|
||||||
|
|
||||||
commit ad4caad58d91d ("cpufreq: amd-pstate: Merge
|
|
||||||
amd_pstate_highest_perf_set() into amd_get_boost_ratio_numerator()")
|
|
||||||
changed the semantics for highest perf and commit 18d9b52271213
|
|
||||||
("cpufreq/amd-pstate: Use nominal perf for limits when boost is disabled")
|
|
||||||
worked around those semantic changes.
|
|
||||||
|
|
||||||
This however is a confusing result and furthermore makes it awkward to
|
|
||||||
change frequency limits and boost due to the scaling differences. Restore
|
|
||||||
the boost numerator to highest perf again.
|
|
||||||
|
|
||||||
Suggested-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Fixes: ad4caad58d91 ("cpufreq: amd-pstate: Merge amd_pstate_highest_perf_set() into amd_get_boost_ratio_numerator()")
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
Documentation/admin-guide/pm/amd-pstate.rst | 4 +---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 25 ++++++++++++---------
|
|
||||||
2 files changed, 16 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
--- a/Documentation/admin-guide/pm/amd-pstate.rst
|
|
||||||
+++ b/Documentation/admin-guide/pm/amd-pstate.rst
|
|
||||||
@@ -251,9 +251,7 @@ performance supported in `AMD CPPC Perfo
|
|
||||||
In some ASICs, the highest CPPC performance is not the one in the ``_CPC``
|
|
||||||
table, so we need to expose it to sysfs. If boost is not active, but
|
|
||||||
still supported, this maximum frequency will be larger than the one in
|
|
||||||
-``cpuinfo``. On systems that support preferred core, the driver will have
|
|
||||||
-different values for some cores than others and this will reflect the values
|
|
||||||
-advertised by the platform at bootup.
|
|
||||||
+``cpuinfo``.
|
|
||||||
This attribute is read-only.
|
|
||||||
|
|
||||||
``amd_pstate_lowest_nonlinear_freq``
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -438,15 +438,19 @@ static inline int amd_pstate_cppc_enable
|
|
||||||
|
|
||||||
static int msr_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
- u64 cap1;
|
|
||||||
+ u64 cap1, numerator;
|
|
||||||
|
|
||||||
int ret = rdmsrl_safe_on_cpu(cpudata->cpu, MSR_AMD_CPPC_CAP1,
|
|
||||||
&cap1);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- WRITE_ONCE(cpudata->highest_perf, AMD_CPPC_HIGHEST_PERF(cap1));
|
|
||||||
- WRITE_ONCE(cpudata->max_limit_perf, AMD_CPPC_HIGHEST_PERF(cap1));
|
|
||||||
+ ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ WRITE_ONCE(cpudata->highest_perf, numerator);
|
|
||||||
+ WRITE_ONCE(cpudata->max_limit_perf, numerator);
|
|
||||||
WRITE_ONCE(cpudata->nominal_perf, AMD_CPPC_NOMINAL_PERF(cap1));
|
|
||||||
WRITE_ONCE(cpudata->lowest_nonlinear_perf, AMD_CPPC_LOWNONLIN_PERF(cap1));
|
|
||||||
WRITE_ONCE(cpudata->lowest_perf, AMD_CPPC_LOWEST_PERF(cap1));
|
|
||||||
@@ -458,13 +462,18 @@ static int msr_init_perf(struct amd_cpud
|
|
||||||
static int shmem_init_perf(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
struct cppc_perf_caps cppc_perf;
|
|
||||||
+ u64 numerator;
|
|
||||||
|
|
||||||
int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- WRITE_ONCE(cpudata->highest_perf, cppc_perf.highest_perf);
|
|
||||||
- WRITE_ONCE(cpudata->max_limit_perf, cppc_perf.highest_perf);
|
|
||||||
+ ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ WRITE_ONCE(cpudata->highest_perf, numerator);
|
|
||||||
+ WRITE_ONCE(cpudata->max_limit_perf, numerator);
|
|
||||||
WRITE_ONCE(cpudata->nominal_perf, cppc_perf.nominal_perf);
|
|
||||||
WRITE_ONCE(cpudata->lowest_nonlinear_perf,
|
|
||||||
cppc_perf.lowest_nonlinear_perf);
|
|
||||||
@@ -950,7 +959,6 @@ static int amd_pstate_init_freq(struct a
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
u32 min_freq, max_freq;
|
|
||||||
- u64 numerator;
|
|
||||||
u32 nominal_perf, nominal_freq;
|
|
||||||
u32 lowest_nonlinear_perf, lowest_nonlinear_freq;
|
|
||||||
u32 boost_ratio, lowest_nonlinear_ratio;
|
|
||||||
@@ -972,10 +980,7 @@ static int amd_pstate_init_freq(struct a
|
|
||||||
|
|
||||||
nominal_perf = READ_ONCE(cpudata->nominal_perf);
|
|
||||||
|
|
||||||
- ret = amd_get_boost_ratio_numerator(cpudata->cpu, &numerator);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
- boost_ratio = div_u64(numerator << SCHED_CAPACITY_SHIFT, nominal_perf);
|
|
||||||
+ boost_ratio = div_u64(cpudata->highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
|
|
||||||
max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
|
|
||||||
|
|
||||||
lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
|
|
@ -1,45 +0,0 @@
|
|||||||
From fab64249be63c384484cf82f4e08724577ad3b84 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:38 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Use boost numerator for upper bound of
|
|
||||||
frequencies
|
|
||||||
|
|
||||||
commit 18d9b5227121 ("cpufreq/amd-pstate: Use nominal perf for limits
|
|
||||||
when boost is disabled") introduced different semantics for min/max limits
|
|
||||||
based upon whether the user turned off boost from sysfs.
|
|
||||||
|
|
||||||
This however is not necessary when the highest perf value is the boost
|
|
||||||
numerator.
|
|
||||||
|
|
||||||
Suggested-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Fixes: 18d9b5227121 ("cpufreq/amd-pstate: Use nominal perf for limits when boost is disabled")
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 13 +++++--------
|
|
||||||
1 file changed, 5 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -631,16 +631,13 @@ static int amd_pstate_verify(struct cpuf
|
|
||||||
|
|
||||||
static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
- u32 max_limit_perf, min_limit_perf, lowest_perf, max_perf;
|
|
||||||
+ u32 max_limit_perf, min_limit_perf, lowest_perf, max_perf, max_freq;
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
|
|
||||||
- if (cpudata->boost_supported && !policy->boost_enabled)
|
|
||||||
- max_perf = READ_ONCE(cpudata->nominal_perf);
|
|
||||||
- else
|
|
||||||
- max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
-
|
|
||||||
- max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq);
|
|
||||||
- min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq);
|
|
||||||
+ max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
+ max_freq = READ_ONCE(cpudata->max_freq);
|
|
||||||
+ max_limit_perf = div_u64(policy->max * max_perf, max_freq);
|
|
||||||
+ min_limit_perf = div_u64(policy->min * max_perf, max_freq);
|
|
||||||
|
|
||||||
lowest_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
if (min_limit_perf < lowest_perf)
|
|
@ -1,36 +0,0 @@
|
|||||||
From a9b210306e861b7c2d3b8532c85e8cd54c3b322a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:39 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Only update the cached value in msr_set_epp() on
|
|
||||||
success
|
|
||||||
|
|
||||||
If writing the MSR MSR_AMD_CPPC_REQ fails then the cached value in the
|
|
||||||
amd_cpudata structure should not be updated.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 10 +++++++---
|
|
||||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -308,11 +308,15 @@ static int msr_set_epp(struct amd_cpudat
|
|
||||||
|
|
||||||
value &= ~AMD_PSTATE_EPP_PERF_MASK;
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, epp);
|
|
||||||
- WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
- if (!ret)
|
|
||||||
- cpudata->epp_cached = epp;
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_err("failed to set energy perf value (%d)\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ cpudata->epp_cached = epp;
|
|
||||||
+ WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,134 +0,0 @@
|
|||||||
From 27a3d0642a3d26ba54e8a21575e6d2cb0ada55b3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:40 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: store all values in cpudata struct in khz
|
|
||||||
|
|
||||||
Storing values in the cpudata structure in different units leads
|
|
||||||
to confusion and hardcoded conversions elsewhere. After ratios are
|
|
||||||
calculated store everything in khz for any future use. Adjust all
|
|
||||||
relevant consumers for this change as well.
|
|
||||||
|
|
||||||
Suggested-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate-ut.c | 12 +++++-------
|
|
||||||
drivers/cpufreq/amd-pstate.c | 30 +++++++++++++++---------------
|
|
||||||
2 files changed, 20 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate-ut.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate-ut.c
|
|
||||||
@@ -207,7 +207,6 @@ static void amd_pstate_ut_check_freq(u32
|
|
||||||
int cpu = 0;
|
|
||||||
struct cpufreq_policy *policy = NULL;
|
|
||||||
struct amd_cpudata *cpudata = NULL;
|
|
||||||
- u32 nominal_freq_khz;
|
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
|
||||||
policy = cpufreq_cpu_get(cpu);
|
|
||||||
@@ -215,14 +214,13 @@ static void amd_pstate_ut_check_freq(u32
|
|
||||||
break;
|
|
||||||
cpudata = policy->driver_data;
|
|
||||||
|
|
||||||
- nominal_freq_khz = cpudata->nominal_freq*1000;
|
|
||||||
- if (!((cpudata->max_freq >= nominal_freq_khz) &&
|
|
||||||
- (nominal_freq_khz > cpudata->lowest_nonlinear_freq) &&
|
|
||||||
+ if (!((cpudata->max_freq >= cpudata->nominal_freq) &&
|
|
||||||
+ (cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) &&
|
|
||||||
(cpudata->lowest_nonlinear_freq > cpudata->min_freq) &&
|
|
||||||
(cpudata->min_freq > 0))) {
|
|
||||||
amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
|
|
||||||
pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n",
|
|
||||||
- __func__, cpu, cpudata->max_freq, nominal_freq_khz,
|
|
||||||
+ __func__, cpu, cpudata->max_freq, cpudata->nominal_freq,
|
|
||||||
cpudata->lowest_nonlinear_freq, cpudata->min_freq);
|
|
||||||
goto skip_test;
|
|
||||||
}
|
|
||||||
@@ -236,13 +234,13 @@ static void amd_pstate_ut_check_freq(u32
|
|
||||||
|
|
||||||
if (cpudata->boost_supported) {
|
|
||||||
if ((policy->max == cpudata->max_freq) ||
|
|
||||||
- (policy->max == nominal_freq_khz))
|
|
||||||
+ (policy->max == cpudata->nominal_freq))
|
|
||||||
amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS;
|
|
||||||
else {
|
|
||||||
amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
|
|
||||||
pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n",
|
|
||||||
__func__, cpu, policy->max, cpudata->max_freq,
|
|
||||||
- nominal_freq_khz);
|
|
||||||
+ cpudata->nominal_freq);
|
|
||||||
goto skip_test;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -769,8 +769,8 @@ static int amd_pstate_cpu_boost_update(s
|
|
||||||
|
|
||||||
if (on)
|
|
||||||
policy->cpuinfo.max_freq = max_freq;
|
|
||||||
- else if (policy->cpuinfo.max_freq > nominal_freq * 1000)
|
|
||||||
- policy->cpuinfo.max_freq = nominal_freq * 1000;
|
|
||||||
+ else if (policy->cpuinfo.max_freq > nominal_freq)
|
|
||||||
+ policy->cpuinfo.max_freq = nominal_freq;
|
|
||||||
|
|
||||||
policy->max = policy->cpuinfo.max_freq;
|
|
||||||
|
|
||||||
@@ -970,29 +970,29 @@ static int amd_pstate_init_freq(struct a
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (quirks && quirks->lowest_freq)
|
|
||||||
- min_freq = quirks->lowest_freq * 1000;
|
|
||||||
+ min_freq = quirks->lowest_freq;
|
|
||||||
else
|
|
||||||
- min_freq = cppc_perf.lowest_freq * 1000;
|
|
||||||
+ min_freq = cppc_perf.lowest_freq;
|
|
||||||
|
|
||||||
if (quirks && quirks->nominal_freq)
|
|
||||||
- nominal_freq = quirks->nominal_freq ;
|
|
||||||
+ nominal_freq = quirks->nominal_freq;
|
|
||||||
else
|
|
||||||
nominal_freq = cppc_perf.nominal_freq;
|
|
||||||
|
|
||||||
nominal_perf = READ_ONCE(cpudata->nominal_perf);
|
|
||||||
|
|
||||||
boost_ratio = div_u64(cpudata->highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
|
|
||||||
- max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
|
|
||||||
+ max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT);
|
|
||||||
|
|
||||||
lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
|
|
||||||
lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
|
|
||||||
nominal_perf);
|
|
||||||
- lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
|
|
||||||
+ lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT);
|
|
||||||
|
|
||||||
- WRITE_ONCE(cpudata->min_freq, min_freq);
|
|
||||||
- WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq);
|
|
||||||
- WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
|
|
||||||
- WRITE_ONCE(cpudata->max_freq, max_freq);
|
|
||||||
+ WRITE_ONCE(cpudata->min_freq, min_freq * 1000);
|
|
||||||
+ WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq * 1000);
|
|
||||||
+ WRITE_ONCE(cpudata->nominal_freq, nominal_freq * 1000);
|
|
||||||
+ WRITE_ONCE(cpudata->max_freq, max_freq * 1000);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Below values need to be initialized correctly, otherwise driver will fail to load
|
|
||||||
@@ -1000,15 +1000,15 @@ static int amd_pstate_init_freq(struct a
|
|
||||||
* lowest_nonlinear_freq is a value between [min_freq, nominal_freq]
|
|
||||||
* Check _CPC in ACPI table objects if any values are incorrect
|
|
||||||
*/
|
|
||||||
- if (min_freq <= 0 || max_freq <= 0 || nominal_freq <= 0 || min_freq > max_freq) {
|
|
||||||
+ if (min_freq <= 0 || max_freq <= 0 || cpudata->nominal_freq <= 0 || min_freq > max_freq) {
|
|
||||||
pr_err("min_freq(%d) or max_freq(%d) or nominal_freq(%d) value is incorrect\n",
|
|
||||||
- min_freq, max_freq, nominal_freq * 1000);
|
|
||||||
+ min_freq, max_freq, cpudata->nominal_freq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (lowest_nonlinear_freq <= min_freq || lowest_nonlinear_freq > nominal_freq * 1000) {
|
|
||||||
+ if (lowest_nonlinear_freq <= min_freq || lowest_nonlinear_freq > cpudata->nominal_freq) {
|
|
||||||
pr_err("lowest_nonlinear_freq(%d) value is out of range [min_freq(%d), nominal_freq(%d)]\n",
|
|
||||||
- lowest_nonlinear_freq, min_freq, nominal_freq * 1000);
|
|
||||||
+ lowest_nonlinear_freq, min_freq, cpudata->nominal_freq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
@ -1,69 +0,0 @@
|
|||||||
From b2a0f625fa30dc907daf1b07bf94b15872da096b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:41 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Change amd_pstate_update_perf() to return an int
|
|
||||||
|
|
||||||
As msr_update_perf() calls an MSR it's possible that it fails. Pass
|
|
||||||
this return code up to the caller.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 22 ++++++++++++----------
|
|
||||||
1 file changed, 12 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -281,24 +281,26 @@ static int amd_pstate_get_energy_pref_in
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
+static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
u32 des_perf, u32 max_perf, bool fast_switch)
|
|
||||||
{
|
|
||||||
- if (fast_switch)
|
|
||||||
+ if (fast_switch) {
|
|
||||||
wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
- else
|
|
||||||
- wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
|
||||||
- READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
|
||||||
+ READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);
|
|
||||||
|
|
||||||
-static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
+static inline int amd_pstate_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
u32 min_perf, u32 des_perf,
|
|
||||||
u32 max_perf, bool fast_switch)
|
|
||||||
{
|
|
||||||
- static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
|
|
||||||
- max_perf, fast_switch);
|
|
||||||
+ return static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
|
|
||||||
+ max_perf, fast_switch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
@@ -510,7 +512,7 @@ static inline int amd_pstate_init_perf(s
|
|
||||||
return static_call(amd_pstate_init_perf)(cpudata);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void shmem_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
+static int shmem_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
u32 min_perf, u32 des_perf,
|
|
||||||
u32 max_perf, bool fast_switch)
|
|
||||||
{
|
|
||||||
@@ -520,7 +522,7 @@ static void shmem_update_perf(struct amd
|
|
||||||
perf_ctrls.min_perf = min_perf;
|
|
||||||
perf_ctrls.desired_perf = des_perf;
|
|
||||||
|
|
||||||
- cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
+ return cppc_set_perf(cpudata->cpu, &perf_ctrls);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
|
|
@ -1,85 +0,0 @@
|
|||||||
From 8399d57cda79a662800a4cd01bd7db951355f451 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:42 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Move limit updating code
|
|
||||||
|
|
||||||
The limit updating code in amd_pstate_epp_update_limit() should not
|
|
||||||
only apply to EPP updates. Move it to amd_pstate_update_min_max_limit()
|
|
||||||
so other callers can benefit as well.
|
|
||||||
|
|
||||||
With this move it's not necessary to have clamp_t calls anymore because
|
|
||||||
the verify callback is called when setting limits.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 28 +++++-----------------------
|
|
||||||
1 file changed, 5 insertions(+), 23 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -567,10 +567,6 @@ static void amd_pstate_update(struct amd
|
|
||||||
u32 nominal_perf = READ_ONCE(cpudata->nominal_perf);
|
|
||||||
u64 value = prev;
|
|
||||||
|
|
||||||
- min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf,
|
|
||||||
- cpudata->max_limit_perf);
|
|
||||||
- max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf,
|
|
||||||
- cpudata->max_limit_perf);
|
|
||||||
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
|
|
||||||
|
|
||||||
max_freq = READ_ONCE(cpudata->max_limit_freq);
|
|
||||||
@@ -637,7 +633,7 @@ static int amd_pstate_verify(struct cpuf
|
|
||||||
|
|
||||||
static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
- u32 max_limit_perf, min_limit_perf, lowest_perf, max_perf, max_freq;
|
|
||||||
+ u32 max_limit_perf, min_limit_perf, max_perf, max_freq;
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
|
|
||||||
max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
@@ -645,12 +641,8 @@ static int amd_pstate_update_min_max_lim
|
|
||||||
max_limit_perf = div_u64(policy->max * max_perf, max_freq);
|
|
||||||
min_limit_perf = div_u64(policy->min * max_perf, max_freq);
|
|
||||||
|
|
||||||
- lowest_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
- if (min_limit_perf < lowest_perf)
|
|
||||||
- min_limit_perf = lowest_perf;
|
|
||||||
-
|
|
||||||
- if (max_limit_perf < min_limit_perf)
|
|
||||||
- max_limit_perf = min_limit_perf;
|
|
||||||
+ if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
+ min_limit_perf = min(cpudata->nominal_perf, max_limit_perf);
|
|
||||||
|
|
||||||
WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf);
|
|
||||||
WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf);
|
|
||||||
@@ -1592,28 +1584,18 @@ static void amd_pstate_epp_cpu_exit(stru
|
|
||||||
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
- u32 max_perf, min_perf;
|
|
||||||
u64 value;
|
|
||||||
s16 epp;
|
|
||||||
|
|
||||||
- max_perf = READ_ONCE(cpudata->highest_perf);
|
|
||||||
- min_perf = READ_ONCE(cpudata->lowest_perf);
|
|
||||||
amd_pstate_update_min_max_limit(policy);
|
|
||||||
|
|
||||||
- max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf,
|
|
||||||
- cpudata->max_limit_perf);
|
|
||||||
- min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf,
|
|
||||||
- cpudata->max_limit_perf);
|
|
||||||
value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
|
|
||||||
- if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
- min_perf = min(cpudata->nominal_perf, max_perf);
|
|
||||||
-
|
|
||||||
value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
AMD_PSTATE_DES_PERF_MASK);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, cpudata->max_limit_perf);
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, 0);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, cpudata->min_limit_perf);
|
|
||||||
|
|
||||||
/* Get BIOS pre-defined epp value */
|
|
||||||
epp = amd_pstate_get_epp(cpudata, value);
|
|
@ -1,233 +0,0 @@
|
|||||||
From fe7f993593ee1891acc875dfb1e091cf17a43f7a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:43 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Cache EPP value and use that everywhere
|
|
||||||
|
|
||||||
Cache the value in cpudata->epp_cached, and use that for all callers.
|
|
||||||
As all callers use cached value merge amd_pstate_get_energy_pref_index()
|
|
||||||
into show_energy_performance_preference().
|
|
||||||
|
|
||||||
Check if the EPP value is changed before writing it to MSR or
|
|
||||||
shared memory region.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 107 +++++++++++++++--------------------
|
|
||||||
1 file changed, 45 insertions(+), 62 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -216,29 +216,28 @@ static inline int get_mode_idx_from_str(
|
|
||||||
static DEFINE_MUTEX(amd_pstate_limits_lock);
|
|
||||||
static DEFINE_MUTEX(amd_pstate_driver_lock);
|
|
||||||
|
|
||||||
-static s16 msr_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|
||||||
+static s16 msr_get_epp(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
+ u64 value;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- if (!cppc_req_cached) {
|
|
||||||
- ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &cppc_req_cached);
|
|
||||||
- if (ret < 0) {
|
|
||||||
- pr_debug("Could not retrieve energy perf value (%d)\n", ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
+ ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ pr_debug("Could not retrieve energy perf value (%d)\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return FIELD_GET(AMD_PSTATE_EPP_PERF_MASK, cppc_req_cached);
|
|
||||||
+ return FIELD_GET(AMD_PSTATE_EPP_PERF_MASK, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_STATIC_CALL(amd_pstate_get_epp, msr_get_epp);
|
|
||||||
|
|
||||||
-static inline s16 amd_pstate_get_epp(struct amd_cpudata *cpudata, u64 cppc_req_cached)
|
|
||||||
+static inline s16 amd_pstate_get_epp(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
- return static_call(amd_pstate_get_epp)(cpudata, cppc_req_cached);
|
|
||||||
+ return static_call(amd_pstate_get_epp)(cpudata);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static s16 shmem_get_epp(struct amd_cpudata *cpudata, u64 dummy)
|
|
||||||
+static s16 shmem_get_epp(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
u64 epp;
|
|
||||||
int ret;
|
|
||||||
@@ -252,35 +251,6 @@ static s16 shmem_get_epp(struct amd_cpud
|
|
||||||
return (s16)(epp & 0xff);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int amd_pstate_get_energy_pref_index(struct amd_cpudata *cpudata)
|
|
||||||
-{
|
|
||||||
- s16 epp;
|
|
||||||
- int index = -EINVAL;
|
|
||||||
-
|
|
||||||
- epp = amd_pstate_get_epp(cpudata, 0);
|
|
||||||
- if (epp < 0)
|
|
||||||
- return epp;
|
|
||||||
-
|
|
||||||
- switch (epp) {
|
|
||||||
- case AMD_CPPC_EPP_PERFORMANCE:
|
|
||||||
- index = EPP_INDEX_PERFORMANCE;
|
|
||||||
- break;
|
|
||||||
- case AMD_CPPC_EPP_BALANCE_PERFORMANCE:
|
|
||||||
- index = EPP_INDEX_BALANCE_PERFORMANCE;
|
|
||||||
- break;
|
|
||||||
- case AMD_CPPC_EPP_BALANCE_POWERSAVE:
|
|
||||||
- index = EPP_INDEX_BALANCE_POWERSAVE;
|
|
||||||
- break;
|
|
||||||
- case AMD_CPPC_EPP_POWERSAVE:
|
|
||||||
- index = EPP_INDEX_POWERSAVE;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return index;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
u32 des_perf, u32 max_perf, bool fast_switch)
|
|
||||||
{
|
|
||||||
@@ -305,19 +275,23 @@ static inline int amd_pstate_update_perf
|
|
||||||
|
|
||||||
static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
{
|
|
||||||
- u64 value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
+ u64 value, prev;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
+ value = prev = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
value &= ~AMD_PSTATE_EPP_PERF_MASK;
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, epp);
|
|
||||||
|
|
||||||
+ if (value == prev)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("failed to set energy perf value (%d)\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- cpudata->epp_cached = epp;
|
|
||||||
+ WRITE_ONCE(cpudata->epp_cached, epp);
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
@@ -335,13 +309,16 @@ static int shmem_set_epp(struct amd_cpud
|
|
||||||
int ret;
|
|
||||||
struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
|
|
||||||
+ if (epp == cpudata->epp_cached)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
perf_ctrls.energy_perf = epp;
|
|
||||||
ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
|
|
||||||
if (ret) {
|
|
||||||
pr_debug("failed to set energy perf value (%d)\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
- cpudata->epp_cached = epp;
|
|
||||||
+ WRITE_ONCE(cpudata->epp_cached, epp);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1244,9 +1221,22 @@ static ssize_t show_energy_performance_p
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
int preference;
|
|
||||||
|
|
||||||
- preference = amd_pstate_get_energy_pref_index(cpudata);
|
|
||||||
- if (preference < 0)
|
|
||||||
- return preference;
|
|
||||||
+ switch (cpudata->epp_cached) {
|
|
||||||
+ case AMD_CPPC_EPP_PERFORMANCE:
|
|
||||||
+ preference = EPP_INDEX_PERFORMANCE;
|
|
||||||
+ break;
|
|
||||||
+ case AMD_CPPC_EPP_BALANCE_PERFORMANCE:
|
|
||||||
+ preference = EPP_INDEX_BALANCE_PERFORMANCE;
|
|
||||||
+ break;
|
|
||||||
+ case AMD_CPPC_EPP_BALANCE_POWERSAVE:
|
|
||||||
+ preference = EPP_INDEX_BALANCE_POWERSAVE;
|
|
||||||
+ break;
|
|
||||||
+ case AMD_CPPC_EPP_POWERSAVE:
|
|
||||||
+ preference = EPP_INDEX_POWERSAVE;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
|
|
||||||
}
|
|
||||||
@@ -1531,7 +1521,7 @@ static int amd_pstate_epp_cpu_init(struc
|
|
||||||
|
|
||||||
policy->driver_data = cpudata;
|
|
||||||
|
|
||||||
- cpudata->epp_cached = cpudata->epp_default = amd_pstate_get_epp(cpudata, 0);
|
|
||||||
+ cpudata->epp_cached = cpudata->epp_default = amd_pstate_get_epp(cpudata);
|
|
||||||
|
|
||||||
policy->min = policy->cpuinfo.min_freq;
|
|
||||||
policy->max = policy->cpuinfo.max_freq;
|
|
||||||
@@ -1585,35 +1575,26 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
u64 value;
|
|
||||||
- s16 epp;
|
|
||||||
|
|
||||||
amd_pstate_update_min_max_limit(policy);
|
|
||||||
|
|
||||||
value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
|
|
||||||
value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
- AMD_PSTATE_DES_PERF_MASK);
|
|
||||||
+ AMD_PSTATE_DES_PERF_MASK | AMD_PSTATE_EPP_PERF_MASK);
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, cpudata->max_limit_perf);
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, 0);
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, cpudata->min_limit_perf);
|
|
||||||
|
|
||||||
- /* Get BIOS pre-defined epp value */
|
|
||||||
- epp = amd_pstate_get_epp(cpudata, value);
|
|
||||||
- if (epp < 0) {
|
|
||||||
- /**
|
|
||||||
- * This return value can only be negative for shared_memory
|
|
||||||
- * systems where EPP register read/write not supported.
|
|
||||||
- */
|
|
||||||
- return epp;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
- epp = 0;
|
|
||||||
+ WRITE_ONCE(cpudata->epp_cached, 0);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, cpudata->epp_cached);
|
|
||||||
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
- trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf, epp,
|
|
||||||
+ trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
|
|
||||||
+ cpudata->epp_cached,
|
|
||||||
cpudata->min_limit_perf,
|
|
||||||
cpudata->max_limit_perf,
|
|
||||||
cpudata->boost_state);
|
|
||||||
@@ -1622,7 +1603,7 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
cpudata->max_limit_perf, false);
|
|
||||||
|
|
||||||
- return amd_pstate_set_epp(cpudata, epp);
|
|
||||||
+ return amd_pstate_set_epp(cpudata, READ_ONCE(cpudata->epp_cached));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
|
|
||||||
@@ -1638,6 +1619,8 @@ static int amd_pstate_epp_set_policy(str
|
|
||||||
|
|
||||||
cpudata->policy = policy->policy;
|
|
||||||
|
|
||||||
+ guard(mutex)(&amd_pstate_limits_lock);
|
|
||||||
+
|
|
||||||
ret = amd_pstate_epp_update_limit(policy);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
@ -1,182 +0,0 @@
|
|||||||
From 98f0f9202cd0fc549f5beaaaf8750658d8ee2140 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:44 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Always write EPP value when updating perf
|
|
||||||
|
|
||||||
For MSR systems the EPP value is in the same register as perf targets
|
|
||||||
and so divding them into two separate MSR writes is wasteful.
|
|
||||||
|
|
||||||
In msr_update_perf(), update both EPP and perf values in one write to
|
|
||||||
MSR_AMD_CPPC_REQ, and cache them if successful.
|
|
||||||
|
|
||||||
To accomplish this plumb the EPP value into the update_perf call and modify
|
|
||||||
all its callers to check the return value.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 71 ++++++++++++++++++++++--------------
|
|
||||||
1 file changed, 43 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -252,25 +252,36 @@ static s16 shmem_get_epp(struct amd_cpud
|
|
||||||
}
|
|
||||||
|
|
||||||
static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
- u32 des_perf, u32 max_perf, bool fast_switch)
|
|
||||||
+ u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
|
|
||||||
{
|
|
||||||
+ u64 value;
|
|
||||||
+
|
|
||||||
+ value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
if (fast_switch) {
|
|
||||||
wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
return 0;
|
|
||||||
+ } else {
|
|
||||||
+ int ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
|
||||||
+ READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
|
||||||
- READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
+ WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
+ WRITE_ONCE(cpudata->epp_cached, epp);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_STATIC_CALL(amd_pstate_update_perf, msr_update_perf);
|
|
||||||
|
|
||||||
static inline int amd_pstate_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
u32 min_perf, u32 des_perf,
|
|
||||||
- u32 max_perf, bool fast_switch)
|
|
||||||
+ u32 max_perf, u32 epp,
|
|
||||||
+ bool fast_switch)
|
|
||||||
{
|
|
||||||
return static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
|
|
||||||
- max_perf, fast_switch);
|
|
||||||
+ max_perf, epp, fast_switch);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int msr_set_epp(struct amd_cpudata *cpudata, u32 epp)
|
|
||||||
@@ -489,12 +500,19 @@ static inline int amd_pstate_init_perf(s
|
|
||||||
return static_call(amd_pstate_init_perf)(cpudata);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int shmem_update_perf(struct amd_cpudata *cpudata,
|
|
||||||
- u32 min_perf, u32 des_perf,
|
|
||||||
- u32 max_perf, bool fast_switch)
|
|
||||||
+static int shmem_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
+ u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
|
|
||||||
{
|
|
||||||
struct cppc_perf_ctrls perf_ctrls;
|
|
||||||
|
|
||||||
+ if (cppc_state == AMD_PSTATE_ACTIVE) {
|
|
||||||
+ int ret = shmem_set_epp(cpudata, epp);
|
|
||||||
+
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+ WRITE_ONCE(cpudata->epp_cached, epp);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
perf_ctrls.max_perf = max_perf;
|
|
||||||
perf_ctrls.min_perf = min_perf;
|
|
||||||
perf_ctrls.desired_perf = des_perf;
|
|
||||||
@@ -575,10 +593,10 @@ static void amd_pstate_update(struct amd
|
|
||||||
|
|
||||||
WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
|
|
||||||
- amd_pstate_update_perf(cpudata, min_perf, des_perf,
|
|
||||||
- max_perf, fast_switch);
|
|
||||||
+ amd_pstate_update_perf(cpudata, min_perf, des_perf, max_perf, 0, fast_switch);
|
|
||||||
|
|
||||||
cpufreq_policy_put:
|
|
||||||
+
|
|
||||||
cpufreq_cpu_put(policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1575,6 +1593,7 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
u64 value;
|
|
||||||
+ u32 epp;
|
|
||||||
|
|
||||||
amd_pstate_update_min_max_limit(policy);
|
|
||||||
|
|
||||||
@@ -1587,23 +1606,19 @@ static int amd_pstate_epp_update_limit(s
|
|
||||||
value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, cpudata->min_limit_perf);
|
|
||||||
|
|
||||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
- WRITE_ONCE(cpudata->epp_cached, 0);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, cpudata->epp_cached);
|
|
||||||
-
|
|
||||||
- WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
+ epp = 0;
|
|
||||||
+ else
|
|
||||||
+ epp = READ_ONCE(cpudata->epp_cached);
|
|
||||||
|
|
||||||
if (trace_amd_pstate_epp_perf_enabled()) {
|
|
||||||
- trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf,
|
|
||||||
- cpudata->epp_cached,
|
|
||||||
+ trace_amd_pstate_epp_perf(cpudata->cpu, cpudata->highest_perf, epp,
|
|
||||||
cpudata->min_limit_perf,
|
|
||||||
cpudata->max_limit_perf,
|
|
||||||
cpudata->boost_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
- amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
- cpudata->max_limit_perf, false);
|
|
||||||
-
|
|
||||||
- return amd_pstate_set_epp(cpudata, READ_ONCE(cpudata->epp_cached));
|
|
||||||
+ return amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
|
|
||||||
+ cpudata->max_limit_perf, epp, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amd_pstate_epp_set_policy(struct cpufreq_policy *policy)
|
|
||||||
@@ -1634,7 +1649,7 @@ static int amd_pstate_epp_set_policy(str
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
|
|
||||||
+static int amd_pstate_epp_reenable(struct amd_cpudata *cpudata)
|
|
||||||
{
|
|
||||||
u64 max_perf;
|
|
||||||
int ret;
|
|
||||||
@@ -1652,17 +1667,19 @@ static void amd_pstate_epp_reenable(stru
|
|
||||||
max_perf, cpudata->boost_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
- amd_pstate_update_perf(cpudata, 0, 0, max_perf, false);
|
|
||||||
- amd_pstate_set_epp(cpudata, cpudata->epp_cached);
|
|
||||||
+ return amd_pstate_update_perf(cpudata, 0, 0, max_perf, cpudata->epp_cached, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amd_pstate_epp_cpu_online(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
+ int ret;
|
|
||||||
|
|
||||||
pr_debug("AMD CPU Core %d going online\n", cpudata->cpu);
|
|
||||||
|
|
||||||
- amd_pstate_epp_reenable(cpudata);
|
|
||||||
+ ret = amd_pstate_epp_reenable(cpudata);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
cpudata->suspended = false;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -1686,10 +1703,8 @@ static int amd_pstate_epp_cpu_offline(st
|
|
||||||
min_perf, min_perf, cpudata->boost_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
- amd_pstate_update_perf(cpudata, min_perf, 0, min_perf, false);
|
|
||||||
- amd_pstate_set_epp(cpudata, AMD_CPPC_EPP_BALANCE_POWERSAVE);
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
+ return amd_pstate_update_perf(cpudata, min_perf, 0, min_perf,
|
|
||||||
+ AMD_CPPC_EPP_BALANCE_POWERSAVE, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int amd_pstate_epp_suspend(struct cpufreq_policy *policy)
|
|
@ -1,158 +0,0 @@
|
|||||||
From acf3f432287638044e472501a1d5969abee15043 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:45 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Check if CPPC request has changed before writing
|
|
||||||
to the MSR or shared memory
|
|
||||||
|
|
||||||
Move the common MSR field formatting code to msr_update_perf() from
|
|
||||||
its callers.
|
|
||||||
|
|
||||||
Ensure that the MSR write is necessary before flushing a write out.
|
|
||||||
Also drop the comparison from the passive flow tracing.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate-trace.h | 7 +----
|
|
||||||
drivers/cpufreq/amd-pstate.c | 47 +++++++++++-------------------
|
|
||||||
2 files changed, 18 insertions(+), 36 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate-trace.h
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate-trace.h
|
|
||||||
@@ -32,7 +32,6 @@ TRACE_EVENT(amd_pstate_perf,
|
|
||||||
u64 aperf,
|
|
||||||
u64 tsc,
|
|
||||||
unsigned int cpu_id,
|
|
||||||
- bool changed,
|
|
||||||
bool fast_switch
|
|
||||||
),
|
|
||||||
|
|
||||||
@@ -44,7 +43,6 @@ TRACE_EVENT(amd_pstate_perf,
|
|
||||||
aperf,
|
|
||||||
tsc,
|
|
||||||
cpu_id,
|
|
||||||
- changed,
|
|
||||||
fast_switch
|
|
||||||
),
|
|
||||||
|
|
||||||
@@ -57,7 +55,6 @@ TRACE_EVENT(amd_pstate_perf,
|
|
||||||
__field(unsigned long long, aperf)
|
|
||||||
__field(unsigned long long, tsc)
|
|
||||||
__field(unsigned int, cpu_id)
|
|
||||||
- __field(bool, changed)
|
|
||||||
__field(bool, fast_switch)
|
|
||||||
),
|
|
||||||
|
|
||||||
@@ -70,11 +67,10 @@ TRACE_EVENT(amd_pstate_perf,
|
|
||||||
__entry->aperf = aperf;
|
|
||||||
__entry->tsc = tsc;
|
|
||||||
__entry->cpu_id = cpu_id;
|
|
||||||
- __entry->changed = changed;
|
|
||||||
__entry->fast_switch = fast_switch;
|
|
||||||
),
|
|
||||||
|
|
||||||
- TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u changed=%s fast_switch=%s",
|
|
||||||
+ TP_printk("amd_min_perf=%lu amd_des_perf=%lu amd_max_perf=%lu freq=%llu mperf=%llu aperf=%llu tsc=%llu cpu_id=%u fast_switch=%s",
|
|
||||||
(unsigned long)__entry->min_perf,
|
|
||||||
(unsigned long)__entry->target_perf,
|
|
||||||
(unsigned long)__entry->capacity,
|
|
||||||
@@ -83,7 +79,6 @@ TRACE_EVENT(amd_pstate_perf,
|
|
||||||
(unsigned long long)__entry->aperf,
|
|
||||||
(unsigned long long)__entry->tsc,
|
|
||||||
(unsigned int)__entry->cpu_id,
|
|
||||||
- (__entry->changed) ? "true" : "false",
|
|
||||||
(__entry->fast_switch) ? "true" : "false"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -254,15 +254,26 @@ static s16 shmem_get_epp(struct amd_cpud
|
|
||||||
static int msr_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
|
|
||||||
u32 des_perf, u32 max_perf, u32 epp, bool fast_switch)
|
|
||||||
{
|
|
||||||
- u64 value;
|
|
||||||
+ u64 value, prev;
|
|
||||||
+
|
|
||||||
+ value = prev = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
+
|
|
||||||
+ value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
+ AMD_PSTATE_DES_PERF_MASK | AMD_PSTATE_EPP_PERF_MASK);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, des_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf);
|
|
||||||
+ value |= FIELD_PREP(AMD_PSTATE_EPP_PERF_MASK, epp);
|
|
||||||
+
|
|
||||||
+ if (value == prev)
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
- value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
if (fast_switch) {
|
|
||||||
- wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
+ wrmsrl(MSR_AMD_CPPC_REQ, value);
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
- int ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
|
|
||||||
- READ_ONCE(cpudata->cppc_req_cached));
|
|
||||||
+ int ret = wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, value);
|
|
||||||
+
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -558,9 +569,7 @@ static void amd_pstate_update(struct amd
|
|
||||||
{
|
|
||||||
unsigned long max_freq;
|
|
||||||
struct cpufreq_policy *policy = cpufreq_cpu_get(cpudata->cpu);
|
|
||||||
- u64 prev = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
u32 nominal_perf = READ_ONCE(cpudata->nominal_perf);
|
|
||||||
- u64 value = prev;
|
|
||||||
|
|
||||||
des_perf = clamp_t(unsigned long, des_perf, min_perf, max_perf);
|
|
||||||
|
|
||||||
@@ -576,27 +585,14 @@ static void amd_pstate_update(struct amd
|
|
||||||
if (!cpudata->boost_supported)
|
|
||||||
max_perf = min_t(unsigned long, nominal_perf, max_perf);
|
|
||||||
|
|
||||||
- value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
- AMD_PSTATE_DES_PERF_MASK);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, max_perf);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, des_perf);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, min_perf);
|
|
||||||
-
|
|
||||||
if (trace_amd_pstate_perf_enabled() && amd_pstate_sample(cpudata)) {
|
|
||||||
trace_amd_pstate_perf(min_perf, des_perf, max_perf, cpudata->freq,
|
|
||||||
cpudata->cur.mperf, cpudata->cur.aperf, cpudata->cur.tsc,
|
|
||||||
- cpudata->cpu, (value != prev), fast_switch);
|
|
||||||
+ cpudata->cpu, fast_switch);
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (value == prev)
|
|
||||||
- goto cpufreq_policy_put;
|
|
||||||
-
|
|
||||||
- WRITE_ONCE(cpudata->cppc_req_cached, value);
|
|
||||||
-
|
|
||||||
amd_pstate_update_perf(cpudata, min_perf, des_perf, max_perf, 0, fast_switch);
|
|
||||||
|
|
||||||
-cpufreq_policy_put:
|
|
||||||
-
|
|
||||||
cpufreq_cpu_put(policy);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1592,19 +1588,10 @@ static void amd_pstate_epp_cpu_exit(stru
|
|
||||||
static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy)
|
|
||||||
{
|
|
||||||
struct amd_cpudata *cpudata = policy->driver_data;
|
|
||||||
- u64 value;
|
|
||||||
u32 epp;
|
|
||||||
|
|
||||||
amd_pstate_update_min_max_limit(policy);
|
|
||||||
|
|
||||||
- value = READ_ONCE(cpudata->cppc_req_cached);
|
|
||||||
-
|
|
||||||
- value &= ~(AMD_PSTATE_MAX_PERF_MASK | AMD_PSTATE_MIN_PERF_MASK |
|
|
||||||
- AMD_PSTATE_DES_PERF_MASK | AMD_PSTATE_EPP_PERF_MASK);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_MAX_PERF_MASK, cpudata->max_limit_perf);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_DES_PERF_MASK, 0);
|
|
||||||
- value |= FIELD_PREP(AMD_PSTATE_MIN_PERF_MASK, cpudata->min_limit_perf);
|
|
||||||
-
|
|
||||||
if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
|
|
||||||
epp = 0;
|
|
||||||
else
|
|
@ -1,42 +0,0 @@
|
|||||||
From 55bcae033b08b1b926f927616cca17242cfcfe59 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:46 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Drop ret variable from
|
|
||||||
amd_pstate_set_energy_pref_index()
|
|
||||||
|
|
||||||
The ret variable is not necessary.
|
|
||||||
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 10 +++-------
|
|
||||||
1 file changed, 3 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -348,13 +348,11 @@ static int shmem_set_epp(struct amd_cpud
|
|
||||||
static int amd_pstate_set_energy_pref_index(struct amd_cpudata *cpudata,
|
|
||||||
int pref_index)
|
|
||||||
{
|
|
||||||
- int epp = -EINVAL;
|
|
||||||
- int ret;
|
|
||||||
+ int epp;
|
|
||||||
|
|
||||||
if (!pref_index)
|
|
||||||
epp = cpudata->epp_default;
|
|
||||||
-
|
|
||||||
- if (epp == -EINVAL)
|
|
||||||
+ else
|
|
||||||
epp = epp_values[pref_index];
|
|
||||||
|
|
||||||
if (epp > 0 && cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) {
|
|
||||||
@@ -370,9 +368,7 @@ static int amd_pstate_set_energy_pref_in
|
|
||||||
cpudata->boost_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
- ret = amd_pstate_set_epp(cpudata, epp);
|
|
||||||
-
|
|
||||||
- return ret;
|
|
||||||
+ return amd_pstate_set_epp(cpudata, epp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int msr_cppc_enable(bool enable)
|
|
@ -1,58 +0,0 @@
|
|||||||
From f1edcca6a96f087f5862a14012fafd4eb9738601 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
Date: Thu, 5 Dec 2024 16:28:47 -0600
|
|
||||||
Subject: cpufreq/amd-pstate: Set different default EPP policy for Epyc and
|
|
||||||
Ryzen
|
|
||||||
|
|
||||||
For Ryzen systems the EPP policy set by the BIOS is generally configured
|
|
||||||
to performance as this is the default register value for the CPPC request
|
|
||||||
MSR.
|
|
||||||
|
|
||||||
If a user doesn't use additional software to configure EPP then the system
|
|
||||||
will default biased towards performance and consume extra battery. Instead
|
|
||||||
configure the default to "balanced_performance" for this case.
|
|
||||||
|
|
||||||
Suggested-by: Artem S. Tashkinov <aros@gmx.com>
|
|
||||||
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219526
|
|
||||||
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
|
|
||||||
---
|
|
||||||
drivers/cpufreq/amd-pstate.c | 12 ++++++++----
|
|
||||||
1 file changed, 8 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
--- a/drivers/cpufreq/amd-pstate.c
|
|
||||||
+++ b/drivers/cpufreq/amd-pstate.c
|
|
||||||
@@ -1531,8 +1531,6 @@ static int amd_pstate_epp_cpu_init(struc
|
|
||||||
|
|
||||||
policy->driver_data = cpudata;
|
|
||||||
|
|
||||||
- cpudata->epp_cached = cpudata->epp_default = amd_pstate_get_epp(cpudata);
|
|
||||||
-
|
|
||||||
policy->min = policy->cpuinfo.min_freq;
|
|
||||||
policy->max = policy->cpuinfo.max_freq;
|
|
||||||
|
|
||||||
@@ -1543,10 +1541,13 @@ static int amd_pstate_epp_cpu_init(struc
|
|
||||||
* the default cpufreq governor is neither powersave nor performance.
|
|
||||||
*/
|
|
||||||
if (amd_pstate_acpi_pm_profile_server() ||
|
|
||||||
- amd_pstate_acpi_pm_profile_undefined())
|
|
||||||
+ amd_pstate_acpi_pm_profile_undefined()) {
|
|
||||||
policy->policy = CPUFREQ_POLICY_PERFORMANCE;
|
|
||||||
- else
|
|
||||||
+ cpudata->epp_default = amd_pstate_get_epp(cpudata);
|
|
||||||
+ } else {
|
|
||||||
policy->policy = CPUFREQ_POLICY_POWERSAVE;
|
|
||||||
+ cpudata->epp_default = AMD_CPPC_EPP_BALANCE_PERFORMANCE;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (cpu_feature_enabled(X86_FEATURE_CPPC)) {
|
|
||||||
ret = rdmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ, &value);
|
|
||||||
@@ -1559,6 +1560,9 @@ static int amd_pstate_epp_cpu_init(struc
|
|
||||||
return ret;
|
|
||||||
WRITE_ONCE(cpudata->cppc_cap1_cached, value);
|
|
||||||
}
|
|
||||||
+ ret = amd_pstate_set_epp(cpudata, cpudata->epp_default);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
|
|
||||||
current_pstate_driver->adjust_perf = NULL;
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
|||||||
From 997fe7115fcb9392f31aa07f407675194452dc0a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kan Liang <kan.liang@linux.intel.com>
|
|
||||||
Date: Thu, 10 Oct 2024 07:26:03 -0700
|
|
||||||
Subject: perf/x86/rapl: Move the pmu allocation out of CPU hotplug
|
|
||||||
|
|
||||||
There are extra codes in the CPU hotplug function to allocate rapl pmus.
|
|
||||||
The generic PMU hotplug support is hard to be applied.
|
|
||||||
|
|
||||||
As long as the rapl pmus can be allocated upfront for each die/socket,
|
|
||||||
the code doesn't need to be implemented in the CPU hotplug function.
|
|
||||||
Move the code to the init_rapl_pmus(), and allocate a PMU for each
|
|
||||||
possible die/socket.
|
|
||||||
|
|
||||||
Tested-by: Oliver Sang <oliver.sang@intel.com>
|
|
||||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
|
||||||
Cc: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 44 ++++++++++++++++++++++++++++--------------
|
|
||||||
1 file changed, 30 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -602,19 +602,8 @@ static int rapl_cpu_online(unsigned int
|
|
||||||
struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
|
|
||||||
int target;
|
|
||||||
|
|
||||||
- if (!pmu) {
|
|
||||||
- pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
|
|
||||||
- if (!pmu)
|
|
||||||
- return -ENOMEM;
|
|
||||||
-
|
|
||||||
- raw_spin_lock_init(&pmu->lock);
|
|
||||||
- INIT_LIST_HEAD(&pmu->active_list);
|
|
||||||
- pmu->pmu = &rapl_pmus->pmu;
|
|
||||||
- pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
|
|
||||||
- rapl_hrtimer_init(pmu);
|
|
||||||
-
|
|
||||||
- rapl_pmus->pmus[rapl_pmu_idx] = pmu;
|
|
||||||
- }
|
|
||||||
+ if (!pmu)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if there is an online cpu in the package which collects rapl
|
|
||||||
@@ -707,6 +696,32 @@ static const struct attribute_group *rap
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static int __init init_rapl_pmu(void)
|
|
||||||
+{
|
|
||||||
+ struct rapl_pmu *pmu;
|
|
||||||
+ int idx;
|
|
||||||
+
|
|
||||||
+ for (idx = 0; idx < rapl_pmus->nr_rapl_pmu; idx++) {
|
|
||||||
+ pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
|
|
||||||
+ if (!pmu)
|
|
||||||
+ goto free;
|
|
||||||
+
|
|
||||||
+ raw_spin_lock_init(&pmu->lock);
|
|
||||||
+ INIT_LIST_HEAD(&pmu->active_list);
|
|
||||||
+ pmu->pmu = &rapl_pmus->pmu;
|
|
||||||
+ pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
|
|
||||||
+ rapl_hrtimer_init(pmu);
|
|
||||||
+
|
|
||||||
+ rapl_pmus->pmus[idx] = pmu;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+free:
|
|
||||||
+ for (; idx > 0; idx--)
|
|
||||||
+ kfree(rapl_pmus->pmus[idx - 1]);
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int __init init_rapl_pmus(void)
|
|
||||||
{
|
|
||||||
int nr_rapl_pmu = topology_max_packages();
|
|
||||||
@@ -730,7 +745,8 @@ static int __init init_rapl_pmus(void)
|
|
||||||
rapl_pmus->pmu.read = rapl_pmu_event_read;
|
|
||||||
rapl_pmus->pmu.module = THIS_MODULE;
|
|
||||||
rapl_pmus->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
|
|
||||||
- return 0;
|
|
||||||
+
|
|
||||||
+ return init_rapl_pmu();
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct rapl_model model_snb = {
|
|
@ -1,199 +0,0 @@
|
|||||||
From 423bd96e0e4522b19e2dca083b70ebbebb639acd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Kan Liang <kan.liang@linux.intel.com>
|
|
||||||
Date: Thu, 10 Oct 2024 07:26:04 -0700
|
|
||||||
Subject: perf/x86/rapl: Clean up cpumask and hotplug
|
|
||||||
|
|
||||||
The rapl pmu is die scope, which is supported by the generic perf_event
|
|
||||||
subsystem now.
|
|
||||||
|
|
||||||
Set the scope for the rapl PMU and remove all the cpumask and hotplug
|
|
||||||
codes.
|
|
||||||
|
|
||||||
Tested-by: Oliver Sang <oliver.sang@intel.com>
|
|
||||||
Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
|
|
||||||
Cc: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 90 +++-----------------------------------
|
|
||||||
include/linux/cpuhotplug.h | 1 -
|
|
||||||
2 files changed, 6 insertions(+), 85 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -148,7 +148,6 @@ struct rapl_model {
|
|
||||||
/* 1/2^hw_unit Joule */
|
|
||||||
static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;
|
|
||||||
static struct rapl_pmus *rapl_pmus;
|
|
||||||
-static cpumask_t rapl_cpu_mask;
|
|
||||||
static unsigned int rapl_cntr_mask;
|
|
||||||
static u64 rapl_timer_ms;
|
|
||||||
static struct perf_msr *rapl_msrs;
|
|
||||||
@@ -369,8 +368,6 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
if (event->cpu < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- event->event_caps |= PERF_EV_CAP_READ_ACTIVE_PKG;
|
|
||||||
-
|
|
||||||
if (!cfg || cfg >= NR_RAPL_DOMAINS + 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
@@ -389,7 +386,6 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
pmu = cpu_to_rapl_pmu(event->cpu);
|
|
||||||
if (!pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
- event->cpu = pmu->cpu;
|
|
||||||
event->pmu_private = pmu;
|
|
||||||
event->hw.event_base = rapl_msrs[bit].msr;
|
|
||||||
event->hw.config = cfg;
|
|
||||||
@@ -403,23 +399,6 @@ static void rapl_pmu_event_read(struct p
|
|
||||||
rapl_event_update(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static ssize_t rapl_get_attr_cpumask(struct device *dev,
|
|
||||||
- struct device_attribute *attr, char *buf)
|
|
||||||
-{
|
|
||||||
- return cpumap_print_to_pagebuf(true, buf, &rapl_cpu_mask);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static DEVICE_ATTR(cpumask, S_IRUGO, rapl_get_attr_cpumask, NULL);
|
|
||||||
-
|
|
||||||
-static struct attribute *rapl_pmu_attrs[] = {
|
|
||||||
- &dev_attr_cpumask.attr,
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static struct attribute_group rapl_pmu_attr_group = {
|
|
||||||
- .attrs = rapl_pmu_attrs,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03");
|
|
||||||
@@ -467,7 +446,6 @@ static struct attribute_group rapl_pmu_f
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct attribute_group *rapl_attr_groups[] = {
|
|
||||||
- &rapl_pmu_attr_group,
|
|
||||||
&rapl_pmu_format_group,
|
|
||||||
&rapl_pmu_events_group,
|
|
||||||
NULL,
|
|
||||||
@@ -570,54 +548,6 @@ static struct perf_msr amd_rapl_msrs[] =
|
|
||||||
[PERF_RAPL_PSYS] = { 0, &rapl_events_psys_group, NULL, false, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
-static int rapl_cpu_offline(unsigned int cpu)
|
|
||||||
-{
|
|
||||||
- struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
|
|
||||||
- int target;
|
|
||||||
-
|
|
||||||
- /* Check if exiting cpu is used for collecting rapl events */
|
|
||||||
- if (!cpumask_test_and_clear_cpu(cpu, &rapl_cpu_mask))
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- pmu->cpu = -1;
|
|
||||||
- /* Find a new cpu to collect rapl events */
|
|
||||||
- target = cpumask_any_but(get_rapl_pmu_cpumask(cpu), cpu);
|
|
||||||
-
|
|
||||||
- /* Migrate rapl events to the new target */
|
|
||||||
- if (target < nr_cpu_ids) {
|
|
||||||
- cpumask_set_cpu(target, &rapl_cpu_mask);
|
|
||||||
- pmu->cpu = target;
|
|
||||||
- perf_pmu_migrate_context(pmu->pmu, cpu, target);
|
|
||||||
- }
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int rapl_cpu_online(unsigned int cpu)
|
|
||||||
-{
|
|
||||||
- s32 rapl_pmu_idx = get_rapl_pmu_idx(cpu);
|
|
||||||
- if (rapl_pmu_idx < 0) {
|
|
||||||
- pr_err("topology_logical_(package/die)_id() returned a negative value");
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
- struct rapl_pmu *pmu = cpu_to_rapl_pmu(cpu);
|
|
||||||
- int target;
|
|
||||||
-
|
|
||||||
- if (!pmu)
|
|
||||||
- return -ENOMEM;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Check if there is an online cpu in the package which collects rapl
|
|
||||||
- * events already.
|
|
||||||
- */
|
|
||||||
- target = cpumask_any_and(&rapl_cpu_mask, get_rapl_pmu_cpumask(cpu));
|
|
||||||
- if (target < nr_cpu_ids)
|
|
||||||
- return 0;
|
|
||||||
-
|
|
||||||
- cpumask_set_cpu(cpu, &rapl_cpu_mask);
|
|
||||||
- pmu->cpu = cpu;
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static int rapl_check_hw_unit(struct rapl_model *rm)
|
|
||||||
{
|
|
||||||
u64 msr_rapl_power_unit_bits;
|
|
||||||
@@ -725,9 +655,12 @@ free:
|
|
||||||
static int __init init_rapl_pmus(void)
|
|
||||||
{
|
|
||||||
int nr_rapl_pmu = topology_max_packages();
|
|
||||||
+ int rapl_pmu_scope = PERF_PMU_SCOPE_PKG;
|
|
||||||
|
|
||||||
- if (!rapl_pmu_is_pkg_scope())
|
|
||||||
+ if (!rapl_pmu_is_pkg_scope()) {
|
|
||||||
nr_rapl_pmu *= topology_max_dies_per_package();
|
|
||||||
+ rapl_pmu_scope = PERF_PMU_SCOPE_DIE;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
rapl_pmus = kzalloc(struct_size(rapl_pmus, pmus, nr_rapl_pmu), GFP_KERNEL);
|
|
||||||
if (!rapl_pmus)
|
|
||||||
@@ -743,6 +676,7 @@ static int __init init_rapl_pmus(void)
|
|
||||||
rapl_pmus->pmu.start = rapl_pmu_event_start;
|
|
||||||
rapl_pmus->pmu.stop = rapl_pmu_event_stop;
|
|
||||||
rapl_pmus->pmu.read = rapl_pmu_event_read;
|
|
||||||
+ rapl_pmus->pmu.scope = rapl_pmu_scope;
|
|
||||||
rapl_pmus->pmu.module = THIS_MODULE;
|
|
||||||
rapl_pmus->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
|
|
||||||
|
|
||||||
@@ -892,24 +826,13 @@ static int __init rapl_pmu_init(void)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Install callbacks. Core will call them for each online cpu.
|
|
||||||
- */
|
|
||||||
- ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_RAPL_ONLINE,
|
|
||||||
- "perf/x86/rapl:online",
|
|
||||||
- rapl_cpu_online, rapl_cpu_offline);
|
|
||||||
- if (ret)
|
|
||||||
- goto out;
|
|
||||||
-
|
|
||||||
ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1);
|
|
||||||
if (ret)
|
|
||||||
- goto out1;
|
|
||||||
+ goto out;
|
|
||||||
|
|
||||||
rapl_advertise();
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
-out1:
|
|
||||||
- cpuhp_remove_state(CPUHP_AP_PERF_X86_RAPL_ONLINE);
|
|
||||||
out:
|
|
||||||
pr_warn("Initialization failed (%d), disabled\n", ret);
|
|
||||||
cleanup_rapl_pmus();
|
|
||||||
@@ -919,7 +842,6 @@ module_init(rapl_pmu_init);
|
|
||||||
|
|
||||||
static void __exit intel_rapl_exit(void)
|
|
||||||
{
|
|
||||||
- cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_RAPL_ONLINE);
|
|
||||||
perf_pmu_unregister(&rapl_pmus->pmu);
|
|
||||||
cleanup_rapl_pmus();
|
|
||||||
}
|
|
||||||
--- a/include/linux/cpuhotplug.h
|
|
||||||
+++ b/include/linux/cpuhotplug.h
|
|
||||||
@@ -208,7 +208,6 @@ enum cpuhp_state {
|
|
||||||
CPUHP_AP_PERF_X86_UNCORE_ONLINE,
|
|
||||||
CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE,
|
|
||||||
CPUHP_AP_PERF_X86_AMD_POWER_ONLINE,
|
|
||||||
- CPUHP_AP_PERF_X86_RAPL_ONLINE,
|
|
||||||
CPUHP_AP_PERF_S390_CF_ONLINE,
|
|
||||||
CPUHP_AP_PERF_S390_SF_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_CCI_ONLINE,
|
|
@ -1,40 +0,0 @@
|
|||||||
From 9e3190a0f75324a7dcb66da336584918243b2c77 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:07:57 +0000
|
|
||||||
Subject: perf/x86/rapl: Remove the unused get_rapl_pmu_cpumask() function
|
|
||||||
|
|
||||||
commit 9e9af8bbb5f9 ("perf/x86/rapl: Clean up cpumask and hotplug")
|
|
||||||
removes the cpumask handling from rapl. Post that, we no longer need the
|
|
||||||
get_rapl_pmu_cpumask() function. So remove it.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 8 +-------
|
|
||||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -153,7 +153,7 @@ static u64 rapl_timer_ms;
|
|
||||||
static struct perf_msr *rapl_msrs;
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Helper functions to get the correct topology macros according to the
|
|
||||||
+ * Helper function to get the correct topology id according to the
|
|
||||||
* RAPL PMU scope.
|
|
||||||
*/
|
|
||||||
static inline unsigned int get_rapl_pmu_idx(int cpu)
|
|
||||||
@@ -162,12 +162,6 @@ static inline unsigned int get_rapl_pmu_
|
|
||||||
topology_logical_die_id(cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static inline const struct cpumask *get_rapl_pmu_cpumask(int cpu)
|
|
||||||
-{
|
|
||||||
- return rapl_pmu_is_pkg_scope() ? topology_core_cpumask(cpu) :
|
|
||||||
- topology_die_cpumask(cpu);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
|
|
||||||
{
|
|
||||||
unsigned int rapl_pmu_idx = get_rapl_pmu_idx(cpu);
|
|
@ -1,79 +0,0 @@
|
|||||||
From 947046055803695b05b1021893860c50412a8d7b Mon Sep 17 00:00:00 2001
|
|
||||||
From: K Prateek Nayak <kprateek.nayak@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:07:58 +0000
|
|
||||||
Subject: x86/topology: Introduce topology_logical_core_id()
|
|
||||||
|
|
||||||
On x86, topology_core_id() returns a unique core ID within the PKG
|
|
||||||
domain. Looking at match_smt() suggests that a core ID just needs to be
|
|
||||||
unique within a LLC domain. For use cases such as the core RAPL PMU,
|
|
||||||
there exists a need for a unique core ID across the entire system with
|
|
||||||
multiple PKG domains. Introduce topology_logical_core_id() to derive a
|
|
||||||
unique core ID across the system.
|
|
||||||
|
|
||||||
Signed-off-by: K Prateek Nayak <kprateek.nayak@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
|
|
||||||
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
Documentation/arch/x86/topology.rst | 4 ++++
|
|
||||||
arch/x86/include/asm/processor.h | 1 +
|
|
||||||
arch/x86/include/asm/topology.h | 1 +
|
|
||||||
arch/x86/kernel/cpu/debugfs.c | 1 +
|
|
||||||
arch/x86/kernel/cpu/topology_common.c | 1 +
|
|
||||||
5 files changed, 8 insertions(+)
|
|
||||||
|
|
||||||
--- a/Documentation/arch/x86/topology.rst
|
|
||||||
+++ b/Documentation/arch/x86/topology.rst
|
|
||||||
@@ -135,6 +135,10 @@ Thread-related topology information in t
|
|
||||||
The ID of the core to which a thread belongs. It is also printed in /proc/cpuinfo
|
|
||||||
"core_id."
|
|
||||||
|
|
||||||
+ - topology_logical_core_id();
|
|
||||||
+
|
|
||||||
+ The logical core ID to which a thread belongs.
|
|
||||||
+
|
|
||||||
|
|
||||||
|
|
||||||
System topology examples
|
|
||||||
--- a/arch/x86/include/asm/processor.h
|
|
||||||
+++ b/arch/x86/include/asm/processor.h
|
|
||||||
@@ -98,6 +98,7 @@ struct cpuinfo_topology {
|
|
||||||
// Logical ID mappings
|
|
||||||
u32 logical_pkg_id;
|
|
||||||
u32 logical_die_id;
|
|
||||||
+ u32 logical_core_id;
|
|
||||||
|
|
||||||
// AMD Node ID and Nodes per Package info
|
|
||||||
u32 amd_node_id;
|
|
||||||
--- a/arch/x86/include/asm/topology.h
|
|
||||||
+++ b/arch/x86/include/asm/topology.h
|
|
||||||
@@ -143,6 +143,7 @@ extern const struct cpumask *cpu_cluster
|
|
||||||
#define topology_logical_package_id(cpu) (cpu_data(cpu).topo.logical_pkg_id)
|
|
||||||
#define topology_physical_package_id(cpu) (cpu_data(cpu).topo.pkg_id)
|
|
||||||
#define topology_logical_die_id(cpu) (cpu_data(cpu).topo.logical_die_id)
|
|
||||||
+#define topology_logical_core_id(cpu) (cpu_data(cpu).topo.logical_core_id)
|
|
||||||
#define topology_die_id(cpu) (cpu_data(cpu).topo.die_id)
|
|
||||||
#define topology_core_id(cpu) (cpu_data(cpu).topo.core_id)
|
|
||||||
#define topology_ppin(cpu) (cpu_data(cpu).ppin)
|
|
||||||
--- a/arch/x86/kernel/cpu/debugfs.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/debugfs.c
|
|
||||||
@@ -25,6 +25,7 @@ static int cpu_debug_show(struct seq_fil
|
|
||||||
seq_printf(m, "cpu_type: %s\n", get_topology_cpu_type_name(c));
|
|
||||||
seq_printf(m, "logical_pkg_id: %u\n", c->topo.logical_pkg_id);
|
|
||||||
seq_printf(m, "logical_die_id: %u\n", c->topo.logical_die_id);
|
|
||||||
+ seq_printf(m, "logical_core_id: %u\n", c->topo.logical_core_id);
|
|
||||||
seq_printf(m, "llc_id: %u\n", c->topo.llc_id);
|
|
||||||
seq_printf(m, "l2c_id: %u\n", c->topo.l2c_id);
|
|
||||||
seq_printf(m, "amd_node_id: %u\n", c->topo.amd_node_id);
|
|
||||||
--- a/arch/x86/kernel/cpu/topology_common.c
|
|
||||||
+++ b/arch/x86/kernel/cpu/topology_common.c
|
|
||||||
@@ -185,6 +185,7 @@ static void topo_set_ids(struct topo_sca
|
|
||||||
if (!early) {
|
|
||||||
c->topo.logical_pkg_id = topology_get_logical_id(apicid, TOPO_PKG_DOMAIN);
|
|
||||||
c->topo.logical_die_id = topology_get_logical_id(apicid, TOPO_DIE_DOMAIN);
|
|
||||||
+ c->topo.logical_core_id = topology_get_logical_id(apicid, TOPO_CORE_DOMAIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Package relative core ID */
|
|
@ -1,69 +0,0 @@
|
|||||||
From 8fd2da09b0c534e05a7b12eb578afae27ad20f7d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:07:59 +0000
|
|
||||||
Subject: perf/x86/rapl: Remove the cpu_to_rapl_pmu() function
|
|
||||||
|
|
||||||
Prepare for the addition of RAPL core energy counter support.
|
|
||||||
Post which, one CPU might be mapped to more than one rapl_pmu
|
|
||||||
(package/die one and a core one). So, remove the cpu_to_rapl_pmu()
|
|
||||||
function.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 24 +++++++++++-------------
|
|
||||||
1 file changed, 11 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -157,22 +157,15 @@ static struct perf_msr *rapl_msrs;
|
|
||||||
* RAPL PMU scope.
|
|
||||||
*/
|
|
||||||
static inline unsigned int get_rapl_pmu_idx(int cpu)
|
|
||||||
-{
|
|
||||||
+{ /*
|
|
||||||
+ * Returns unsigned int, which converts the '-1' return value
|
|
||||||
+ * (for non-existent mappings in topology map) to UINT_MAX, so
|
|
||||||
+ * the error check in the caller is simplified.
|
|
||||||
+ */
|
|
||||||
return rapl_pmu_is_pkg_scope() ? topology_logical_package_id(cpu) :
|
|
||||||
topology_logical_die_id(cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static inline struct rapl_pmu *cpu_to_rapl_pmu(unsigned int cpu)
|
|
||||||
-{
|
|
||||||
- unsigned int rapl_pmu_idx = get_rapl_pmu_idx(cpu);
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * The unsigned check also catches the '-1' return value for non
|
|
||||||
- * existent mappings in the topology map.
|
|
||||||
- */
|
|
||||||
- return rapl_pmu_idx < rapl_pmus->nr_rapl_pmu ? rapl_pmus->pmus[rapl_pmu_idx] : NULL;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
static inline u64 rapl_read_counter(struct perf_event *event)
|
|
||||||
{
|
|
||||||
u64 raw;
|
|
||||||
@@ -350,6 +343,7 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
u64 cfg = event->attr.config & RAPL_EVENT_MASK;
|
|
||||||
int bit, ret = 0;
|
|
||||||
struct rapl_pmu *pmu;
|
|
||||||
+ unsigned int rapl_pmu_idx;
|
|
||||||
|
|
||||||
/* only look at RAPL events */
|
|
||||||
if (event->attr.type != rapl_pmus->pmu.type)
|
|
||||||
@@ -376,8 +370,12 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
if (event->attr.sample_period) /* no sampling */
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
+ rapl_pmu_idx = get_rapl_pmu_idx(event->cpu);
|
|
||||||
+ if (rapl_pmu_idx >= rapl_pmus->nr_rapl_pmu)
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
/* must be done before validate_group */
|
|
||||||
- pmu = cpu_to_rapl_pmu(event->cpu);
|
|
||||||
+ pmu = rapl_pmus->pmus[rapl_pmu_idx];
|
|
||||||
if (!pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
event->pmu_private = pmu;
|
|
@ -1,242 +0,0 @@
|
|||||||
From 30e2cd787aeb9cb9c1148e07446aac76765f715e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:00 +0000
|
|
||||||
Subject: perf/x86/rapl: Rename rapl_pmu variables
|
|
||||||
|
|
||||||
Rename struct rapl_pmu variables from "pmu" to "rapl_pmu", to
|
|
||||||
avoid any confusion between the variables of two different
|
|
||||||
structs pmu and rapl_pmu. As rapl_pmu also contains a pointer to
|
|
||||||
struct pmu, which leads to situations in code like pmu->pmu,
|
|
||||||
which is needlessly confusing. Above scenario is replaced with
|
|
||||||
much more readable rapl_pmu->pmu with this change.
|
|
||||||
|
|
||||||
Also rename "pmus" member in rapl_pmus struct, for same reason.
|
|
||||||
|
|
||||||
No functional change.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 91 +++++++++++++++++++++---------------------
|
|
||||||
1 file changed, 46 insertions(+), 45 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -129,7 +129,7 @@ struct rapl_pmu {
|
|
||||||
struct rapl_pmus {
|
|
||||||
struct pmu pmu;
|
|
||||||
unsigned int nr_rapl_pmu;
|
|
||||||
- struct rapl_pmu *pmus[] __counted_by(nr_rapl_pmu);
|
|
||||||
+ struct rapl_pmu *rapl_pmu[] __counted_by(nr_rapl_pmu);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum rapl_unit_quirk {
|
|
||||||
@@ -227,34 +227,34 @@ static void rapl_start_hrtimer(struct ra
|
|
||||||
|
|
||||||
static enum hrtimer_restart rapl_hrtimer_handle(struct hrtimer *hrtimer)
|
|
||||||
{
|
|
||||||
- struct rapl_pmu *pmu = container_of(hrtimer, struct rapl_pmu, hrtimer);
|
|
||||||
+ struct rapl_pmu *rapl_pmu = container_of(hrtimer, struct rapl_pmu, hrtimer);
|
|
||||||
struct perf_event *event;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
- if (!pmu->n_active)
|
|
||||||
+ if (!rapl_pmu->n_active)
|
|
||||||
return HRTIMER_NORESTART;
|
|
||||||
|
|
||||||
- raw_spin_lock_irqsave(&pmu->lock, flags);
|
|
||||||
+ raw_spin_lock_irqsave(&rapl_pmu->lock, flags);
|
|
||||||
|
|
||||||
- list_for_each_entry(event, &pmu->active_list, active_entry)
|
|
||||||
+ list_for_each_entry(event, &rapl_pmu->active_list, active_entry)
|
|
||||||
rapl_event_update(event);
|
|
||||||
|
|
||||||
- raw_spin_unlock_irqrestore(&pmu->lock, flags);
|
|
||||||
+ raw_spin_unlock_irqrestore(&rapl_pmu->lock, flags);
|
|
||||||
|
|
||||||
- hrtimer_forward_now(hrtimer, pmu->timer_interval);
|
|
||||||
+ hrtimer_forward_now(hrtimer, rapl_pmu->timer_interval);
|
|
||||||
|
|
||||||
return HRTIMER_RESTART;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void rapl_hrtimer_init(struct rapl_pmu *pmu)
|
|
||||||
+static void rapl_hrtimer_init(struct rapl_pmu *rapl_pmu)
|
|
||||||
{
|
|
||||||
- struct hrtimer *hr = &pmu->hrtimer;
|
|
||||||
+ struct hrtimer *hr = &rapl_pmu->hrtimer;
|
|
||||||
|
|
||||||
hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
||||||
hr->function = rapl_hrtimer_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void __rapl_pmu_event_start(struct rapl_pmu *pmu,
|
|
||||||
+static void __rapl_pmu_event_start(struct rapl_pmu *rapl_pmu,
|
|
||||||
struct perf_event *event)
|
|
||||||
{
|
|
||||||
if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
|
|
||||||
@@ -262,39 +262,39 @@ static void __rapl_pmu_event_start(struc
|
|
||||||
|
|
||||||
event->hw.state = 0;
|
|
||||||
|
|
||||||
- list_add_tail(&event->active_entry, &pmu->active_list);
|
|
||||||
+ list_add_tail(&event->active_entry, &rapl_pmu->active_list);
|
|
||||||
|
|
||||||
local64_set(&event->hw.prev_count, rapl_read_counter(event));
|
|
||||||
|
|
||||||
- pmu->n_active++;
|
|
||||||
- if (pmu->n_active == 1)
|
|
||||||
- rapl_start_hrtimer(pmu);
|
|
||||||
+ rapl_pmu->n_active++;
|
|
||||||
+ if (rapl_pmu->n_active == 1)
|
|
||||||
+ rapl_start_hrtimer(rapl_pmu);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rapl_pmu_event_start(struct perf_event *event, int mode)
|
|
||||||
{
|
|
||||||
- struct rapl_pmu *pmu = event->pmu_private;
|
|
||||||
+ struct rapl_pmu *rapl_pmu = event->pmu_private;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
- raw_spin_lock_irqsave(&pmu->lock, flags);
|
|
||||||
- __rapl_pmu_event_start(pmu, event);
|
|
||||||
- raw_spin_unlock_irqrestore(&pmu->lock, flags);
|
|
||||||
+ raw_spin_lock_irqsave(&rapl_pmu->lock, flags);
|
|
||||||
+ __rapl_pmu_event_start(rapl_pmu, event);
|
|
||||||
+ raw_spin_unlock_irqrestore(&rapl_pmu->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rapl_pmu_event_stop(struct perf_event *event, int mode)
|
|
||||||
{
|
|
||||||
- struct rapl_pmu *pmu = event->pmu_private;
|
|
||||||
+ struct rapl_pmu *rapl_pmu = event->pmu_private;
|
|
||||||
struct hw_perf_event *hwc = &event->hw;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
- raw_spin_lock_irqsave(&pmu->lock, flags);
|
|
||||||
+ raw_spin_lock_irqsave(&rapl_pmu->lock, flags);
|
|
||||||
|
|
||||||
/* mark event as deactivated and stopped */
|
|
||||||
if (!(hwc->state & PERF_HES_STOPPED)) {
|
|
||||||
- WARN_ON_ONCE(pmu->n_active <= 0);
|
|
||||||
- pmu->n_active--;
|
|
||||||
- if (pmu->n_active == 0)
|
|
||||||
- hrtimer_cancel(&pmu->hrtimer);
|
|
||||||
+ WARN_ON_ONCE(rapl_pmu->n_active <= 0);
|
|
||||||
+ rapl_pmu->n_active--;
|
|
||||||
+ if (rapl_pmu->n_active == 0)
|
|
||||||
+ hrtimer_cancel(&rapl_pmu->hrtimer);
|
|
||||||
|
|
||||||
list_del(&event->active_entry);
|
|
||||||
|
|
||||||
@@ -312,23 +312,23 @@ static void rapl_pmu_event_stop(struct p
|
|
||||||
hwc->state |= PERF_HES_UPTODATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
- raw_spin_unlock_irqrestore(&pmu->lock, flags);
|
|
||||||
+ raw_spin_unlock_irqrestore(&rapl_pmu->lock, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rapl_pmu_event_add(struct perf_event *event, int mode)
|
|
||||||
{
|
|
||||||
- struct rapl_pmu *pmu = event->pmu_private;
|
|
||||||
+ struct rapl_pmu *rapl_pmu = event->pmu_private;
|
|
||||||
struct hw_perf_event *hwc = &event->hw;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
- raw_spin_lock_irqsave(&pmu->lock, flags);
|
|
||||||
+ raw_spin_lock_irqsave(&rapl_pmu->lock, flags);
|
|
||||||
|
|
||||||
hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
|
|
||||||
|
|
||||||
if (mode & PERF_EF_START)
|
|
||||||
- __rapl_pmu_event_start(pmu, event);
|
|
||||||
+ __rapl_pmu_event_start(rapl_pmu, event);
|
|
||||||
|
|
||||||
- raw_spin_unlock_irqrestore(&pmu->lock, flags);
|
|
||||||
+ raw_spin_unlock_irqrestore(&rapl_pmu->lock, flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -342,7 +342,7 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
{
|
|
||||||
u64 cfg = event->attr.config & RAPL_EVENT_MASK;
|
|
||||||
int bit, ret = 0;
|
|
||||||
- struct rapl_pmu *pmu;
|
|
||||||
+ struct rapl_pmu *rapl_pmu;
|
|
||||||
unsigned int rapl_pmu_idx;
|
|
||||||
|
|
||||||
/* only look at RAPL events */
|
|
||||||
@@ -375,10 +375,11 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* must be done before validate_group */
|
|
||||||
- pmu = rapl_pmus->pmus[rapl_pmu_idx];
|
|
||||||
- if (!pmu)
|
|
||||||
+ rapl_pmu = rapl_pmus->rapl_pmu[rapl_pmu_idx];
|
|
||||||
+ if (!rapl_pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
- event->pmu_private = pmu;
|
|
||||||
+
|
|
||||||
+ event->pmu_private = rapl_pmu;
|
|
||||||
event->hw.event_base = rapl_msrs[bit].msr;
|
|
||||||
event->hw.config = cfg;
|
|
||||||
event->hw.idx = bit;
|
|
||||||
@@ -605,7 +606,7 @@ static void cleanup_rapl_pmus(void)
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < rapl_pmus->nr_rapl_pmu; i++)
|
|
||||||
- kfree(rapl_pmus->pmus[i]);
|
|
||||||
+ kfree(rapl_pmus->rapl_pmu[i]);
|
|
||||||
kfree(rapl_pmus);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -620,27 +621,27 @@ static const struct attribute_group *rap
|
|
||||||
|
|
||||||
static int __init init_rapl_pmu(void)
|
|
||||||
{
|
|
||||||
- struct rapl_pmu *pmu;
|
|
||||||
+ struct rapl_pmu *rapl_pmu;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
for (idx = 0; idx < rapl_pmus->nr_rapl_pmu; idx++) {
|
|
||||||
- pmu = kzalloc(sizeof(*pmu), GFP_KERNEL);
|
|
||||||
- if (!pmu)
|
|
||||||
+ rapl_pmu = kzalloc(sizeof(*rapl_pmu), GFP_KERNEL);
|
|
||||||
+ if (!rapl_pmu)
|
|
||||||
goto free;
|
|
||||||
|
|
||||||
- raw_spin_lock_init(&pmu->lock);
|
|
||||||
- INIT_LIST_HEAD(&pmu->active_list);
|
|
||||||
- pmu->pmu = &rapl_pmus->pmu;
|
|
||||||
- pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
|
|
||||||
- rapl_hrtimer_init(pmu);
|
|
||||||
+ raw_spin_lock_init(&rapl_pmu->lock);
|
|
||||||
+ INIT_LIST_HEAD(&rapl_pmu->active_list);
|
|
||||||
+ rapl_pmu->pmu = &rapl_pmus->pmu;
|
|
||||||
+ rapl_pmu->timer_interval = ms_to_ktime(rapl_timer_ms);
|
|
||||||
+ rapl_hrtimer_init(rapl_pmu);
|
|
||||||
|
|
||||||
- rapl_pmus->pmus[idx] = pmu;
|
|
||||||
+ rapl_pmus->rapl_pmu[idx] = rapl_pmu;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
free:
|
|
||||||
for (; idx > 0; idx--)
|
|
||||||
- kfree(rapl_pmus->pmus[idx - 1]);
|
|
||||||
+ kfree(rapl_pmus->rapl_pmu[idx - 1]);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -654,7 +655,7 @@ static int __init init_rapl_pmus(void)
|
|
||||||
rapl_pmu_scope = PERF_PMU_SCOPE_DIE;
|
|
||||||
}
|
|
||||||
|
|
||||||
- rapl_pmus = kzalloc(struct_size(rapl_pmus, pmus, nr_rapl_pmu), GFP_KERNEL);
|
|
||||||
+ rapl_pmus = kzalloc(struct_size(rapl_pmus, rapl_pmu, nr_rapl_pmu), GFP_KERNEL);
|
|
||||||
if (!rapl_pmus)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
From 0f84d3bd0af2c300fe13d9f0f5131d0747a13f9e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:01 +0000
|
|
||||||
Subject: perf/x86/rapl: Make rapl_model struct global
|
|
||||||
|
|
||||||
Prepare for the addition of RAPL core energy counter support.
|
|
||||||
|
|
||||||
As there will always be just one rapl_model variable on a system, make it
|
|
||||||
global, to make it easier to access it from any function.
|
|
||||||
|
|
||||||
No functional change.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 16 ++++++++--------
|
|
||||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -151,6 +151,7 @@ static struct rapl_pmus *rapl_pmus;
|
|
||||||
static unsigned int rapl_cntr_mask;
|
|
||||||
static u64 rapl_timer_ms;
|
|
||||||
static struct perf_msr *rapl_msrs;
|
|
||||||
+static struct rapl_model *rapl_model;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Helper function to get the correct topology id according to the
|
|
||||||
@@ -541,18 +542,18 @@ static struct perf_msr amd_rapl_msrs[] =
|
|
||||||
[PERF_RAPL_PSYS] = { 0, &rapl_events_psys_group, NULL, false, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
-static int rapl_check_hw_unit(struct rapl_model *rm)
|
|
||||||
+static int rapl_check_hw_unit(void)
|
|
||||||
{
|
|
||||||
u64 msr_rapl_power_unit_bits;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* protect rdmsrl() to handle virtualization */
|
|
||||||
- if (rdmsrl_safe(rm->msr_power_unit, &msr_rapl_power_unit_bits))
|
|
||||||
+ if (rdmsrl_safe(rapl_model->msr_power_unit, &msr_rapl_power_unit_bits))
|
|
||||||
return -1;
|
|
||||||
for (i = 0; i < NR_RAPL_DOMAINS; i++)
|
|
||||||
rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
|
||||||
|
|
||||||
- switch (rm->unit_quirk) {
|
|
||||||
+ switch (rapl_model->unit_quirk) {
|
|
||||||
/*
|
|
||||||
* DRAM domain on HSW server and KNL has fixed energy unit which can be
|
|
||||||
* different than the unit from power unit MSR. See
|
|
||||||
@@ -797,21 +798,20 @@ MODULE_DEVICE_TABLE(x86cpu, rapl_model_m
|
|
||||||
static int __init rapl_pmu_init(void)
|
|
||||||
{
|
|
||||||
const struct x86_cpu_id *id;
|
|
||||||
- struct rapl_model *rm;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
id = x86_match_cpu(rapl_model_match);
|
|
||||||
if (!id)
|
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
- rm = (struct rapl_model *) id->driver_data;
|
|
||||||
+ rapl_model = (struct rapl_model *) id->driver_data;
|
|
||||||
|
|
||||||
- rapl_msrs = rm->rapl_msrs;
|
|
||||||
+ rapl_msrs = rapl_model->rapl_msrs;
|
|
||||||
|
|
||||||
rapl_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_MAX,
|
|
||||||
- false, (void *) &rm->events);
|
|
||||||
+ false, (void *) &rapl_model->events);
|
|
||||||
|
|
||||||
- ret = rapl_check_hw_unit(rm);
|
|
||||||
+ ret = rapl_check_hw_unit();
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
|||||||
From 395cf3513aaf79c95c611ce97ba451eaf6470c44 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:02 +0000
|
|
||||||
Subject: perf/x86/rapl: Add arguments to the init and cleanup functions
|
|
||||||
|
|
||||||
Prepare for the addition of RAPL core energy counter support.
|
|
||||||
|
|
||||||
Add arguments to the init and cleanup functions, which will help in
|
|
||||||
initialization and cleaning up of two separate PMUs.
|
|
||||||
|
|
||||||
No functional change.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 28 ++++++++++++++++------------
|
|
||||||
1 file changed, 16 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -602,7 +602,7 @@ static void __init rapl_advertise(void)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void cleanup_rapl_pmus(void)
|
|
||||||
+static void cleanup_rapl_pmus(struct rapl_pmus *rapl_pmus)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
@@ -620,7 +620,7 @@ static const struct attribute_group *rap
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static int __init init_rapl_pmu(void)
|
|
||||||
+static int __init init_rapl_pmu(struct rapl_pmus *rapl_pmus)
|
|
||||||
{
|
|
||||||
struct rapl_pmu *rapl_pmu;
|
|
||||||
int idx;
|
|
||||||
@@ -646,20 +646,20 @@ free:
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int __init init_rapl_pmus(void)
|
|
||||||
+static int __init init_rapl_pmus(struct rapl_pmus **rapl_pmus_ptr, int rapl_pmu_scope)
|
|
||||||
{
|
|
||||||
int nr_rapl_pmu = topology_max_packages();
|
|
||||||
- int rapl_pmu_scope = PERF_PMU_SCOPE_PKG;
|
|
||||||
+ struct rapl_pmus *rapl_pmus;
|
|
||||||
|
|
||||||
- if (!rapl_pmu_is_pkg_scope()) {
|
|
||||||
- nr_rapl_pmu *= topology_max_dies_per_package();
|
|
||||||
- rapl_pmu_scope = PERF_PMU_SCOPE_DIE;
|
|
||||||
- }
|
|
||||||
+ if (rapl_pmu_scope == PERF_PMU_SCOPE_DIE)
|
|
||||||
+ nr_rapl_pmu *= topology_max_dies_per_package();
|
|
||||||
|
|
||||||
rapl_pmus = kzalloc(struct_size(rapl_pmus, rapl_pmu, nr_rapl_pmu), GFP_KERNEL);
|
|
||||||
if (!rapl_pmus)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
+ *rapl_pmus_ptr = rapl_pmus;
|
|
||||||
+
|
|
||||||
rapl_pmus->nr_rapl_pmu = nr_rapl_pmu;
|
|
||||||
rapl_pmus->pmu.attr_groups = rapl_attr_groups;
|
|
||||||
rapl_pmus->pmu.attr_update = rapl_attr_update;
|
|
||||||
@@ -674,7 +674,7 @@ static int __init init_rapl_pmus(void)
|
|
||||||
rapl_pmus->pmu.module = THIS_MODULE;
|
|
||||||
rapl_pmus->pmu.capabilities = PERF_PMU_CAP_NO_EXCLUDE;
|
|
||||||
|
|
||||||
- return init_rapl_pmu();
|
|
||||||
+ return init_rapl_pmu(rapl_pmus);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct rapl_model model_snb = {
|
|
||||||
@@ -798,8 +798,12 @@ MODULE_DEVICE_TABLE(x86cpu, rapl_model_m
|
|
||||||
static int __init rapl_pmu_init(void)
|
|
||||||
{
|
|
||||||
const struct x86_cpu_id *id;
|
|
||||||
+ int rapl_pmu_scope = PERF_PMU_SCOPE_DIE;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
+ if (rapl_pmu_is_pkg_scope())
|
|
||||||
+ rapl_pmu_scope = PERF_PMU_SCOPE_PKG;
|
|
||||||
+
|
|
||||||
id = x86_match_cpu(rapl_model_match);
|
|
||||||
if (!id)
|
|
||||||
return -ENODEV;
|
|
||||||
@@ -815,7 +819,7 @@ static int __init rapl_pmu_init(void)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = init_rapl_pmus();
|
|
||||||
+ ret = init_rapl_pmus(&rapl_pmus, rapl_pmu_scope);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
@@ -828,7 +832,7 @@ static int __init rapl_pmu_init(void)
|
|
||||||
|
|
||||||
out:
|
|
||||||
pr_warn("Initialization failed (%d), disabled\n", ret);
|
|
||||||
- cleanup_rapl_pmus();
|
|
||||||
+ cleanup_rapl_pmus(rapl_pmus);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
module_init(rapl_pmu_init);
|
|
||||||
@@ -836,6 +840,6 @@ module_init(rapl_pmu_init);
|
|
||||||
static void __exit intel_rapl_exit(void)
|
|
||||||
{
|
|
||||||
perf_pmu_unregister(&rapl_pmus->pmu);
|
|
||||||
- cleanup_rapl_pmus();
|
|
||||||
+ cleanup_rapl_pmus(rapl_pmus);
|
|
||||||
}
|
|
||||||
module_exit(intel_rapl_exit);
|
|
@ -1,362 +0,0 @@
|
|||||||
From 98d0cb818ba4695b9a41ab83b7c00ec1cbdf1b35 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:03 +0000
|
|
||||||
Subject: perf/x86/rapl: Modify the generic variable names to *_pkg*
|
|
||||||
|
|
||||||
Prepare for the addition of RAPL core energy counter support.
|
|
||||||
|
|
||||||
Replace the generic names with *_pkg*, to later on differentiate between
|
|
||||||
the scopes of the two different PMUs and their variables.
|
|
||||||
|
|
||||||
No functional change.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 120 ++++++++++++++++++++---------------------
|
|
||||||
1 file changed, 60 insertions(+), 60 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -70,18 +70,18 @@ MODULE_LICENSE("GPL");
|
|
||||||
/*
|
|
||||||
* RAPL energy status counters
|
|
||||||
*/
|
|
||||||
-enum perf_rapl_events {
|
|
||||||
+enum perf_rapl_pkg_events {
|
|
||||||
PERF_RAPL_PP0 = 0, /* all cores */
|
|
||||||
PERF_RAPL_PKG, /* entire package */
|
|
||||||
PERF_RAPL_RAM, /* DRAM */
|
|
||||||
PERF_RAPL_PP1, /* gpu */
|
|
||||||
PERF_RAPL_PSYS, /* psys */
|
|
||||||
|
|
||||||
- PERF_RAPL_MAX,
|
|
||||||
- NR_RAPL_DOMAINS = PERF_RAPL_MAX,
|
|
||||||
+ PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
+ NR_RAPL_PKG_DOMAINS = PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const char *const rapl_domain_names[NR_RAPL_DOMAINS] __initconst = {
|
|
||||||
+static const char *const rapl_pkg_domain_names[NR_RAPL_PKG_DOMAINS] __initconst = {
|
|
||||||
"pp0-core",
|
|
||||||
"package",
|
|
||||||
"dram",
|
|
||||||
@@ -112,7 +112,7 @@ static struct perf_pmu_events_attr event
|
|
||||||
* considered as either pkg-scope or die-scope, and we are considering
|
|
||||||
* them as die-scope.
|
|
||||||
*/
|
|
||||||
-#define rapl_pmu_is_pkg_scope() \
|
|
||||||
+#define rapl_pkg_pmu_is_pkg_scope() \
|
|
||||||
(boot_cpu_data.x86_vendor == X86_VENDOR_AMD || \
|
|
||||||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
|
|
||||||
|
|
||||||
@@ -139,16 +139,16 @@ enum rapl_unit_quirk {
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rapl_model {
|
|
||||||
- struct perf_msr *rapl_msrs;
|
|
||||||
- unsigned long events;
|
|
||||||
+ struct perf_msr *rapl_pkg_msrs;
|
|
||||||
+ unsigned long pkg_events;
|
|
||||||
unsigned int msr_power_unit;
|
|
||||||
enum rapl_unit_quirk unit_quirk;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 1/2^hw_unit Joule */
|
|
||||||
-static int rapl_hw_unit[NR_RAPL_DOMAINS] __read_mostly;
|
|
||||||
-static struct rapl_pmus *rapl_pmus;
|
|
||||||
-static unsigned int rapl_cntr_mask;
|
|
||||||
+static int rapl_pkg_hw_unit[NR_RAPL_PKG_DOMAINS] __read_mostly;
|
|
||||||
+static struct rapl_pmus *rapl_pmus_pkg;
|
|
||||||
+static unsigned int rapl_pkg_cntr_mask;
|
|
||||||
static u64 rapl_timer_ms;
|
|
||||||
static struct perf_msr *rapl_msrs;
|
|
||||||
static struct rapl_model *rapl_model;
|
|
||||||
@@ -163,8 +163,8 @@ static inline unsigned int get_rapl_pmu_
|
|
||||||
* (for non-existent mappings in topology map) to UINT_MAX, so
|
|
||||||
* the error check in the caller is simplified.
|
|
||||||
*/
|
|
||||||
- return rapl_pmu_is_pkg_scope() ? topology_logical_package_id(cpu) :
|
|
||||||
- topology_logical_die_id(cpu);
|
|
||||||
+ return rapl_pkg_pmu_is_pkg_scope() ? topology_logical_package_id(cpu) :
|
|
||||||
+ topology_logical_die_id(cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u64 rapl_read_counter(struct perf_event *event)
|
|
||||||
@@ -176,7 +176,7 @@ static inline u64 rapl_read_counter(stru
|
|
||||||
|
|
||||||
static inline u64 rapl_scale(u64 v, int cfg)
|
|
||||||
{
|
|
||||||
- if (cfg > NR_RAPL_DOMAINS) {
|
|
||||||
+ if (cfg > NR_RAPL_PKG_DOMAINS) {
|
|
||||||
pr_warn("Invalid domain %d, failed to scale data\n", cfg);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
@@ -186,7 +186,7 @@ static inline u64 rapl_scale(u64 v, int
|
|
||||||
* or use ldexp(count, -32).
|
|
||||||
* Watts = Joules/Time delta
|
|
||||||
*/
|
|
||||||
- return v << (32 - rapl_hw_unit[cfg - 1]);
|
|
||||||
+ return v << (32 - rapl_pkg_hw_unit[cfg - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 rapl_event_update(struct perf_event *event)
|
|
||||||
@@ -347,7 +347,7 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
unsigned int rapl_pmu_idx;
|
|
||||||
|
|
||||||
/* only look at RAPL events */
|
|
||||||
- if (event->attr.type != rapl_pmus->pmu.type)
|
|
||||||
+ if (event->attr.type != rapl_pmus_pkg->pmu.type)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
/* check only supported bits are set */
|
|
||||||
@@ -357,14 +357,14 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
if (event->cpu < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- if (!cfg || cfg >= NR_RAPL_DOMAINS + 1)
|
|
||||||
+ if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- cfg = array_index_nospec((long)cfg, NR_RAPL_DOMAINS + 1);
|
|
||||||
+ cfg = array_index_nospec((long)cfg, NR_RAPL_PKG_DOMAINS + 1);
|
|
||||||
bit = cfg - 1;
|
|
||||||
|
|
||||||
/* check event supported */
|
|
||||||
- if (!(rapl_cntr_mask & (1 << bit)))
|
|
||||||
+ if (!(rapl_pkg_cntr_mask & (1 << bit)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* unsupported modes and filters */
|
|
||||||
@@ -372,11 +372,11 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
rapl_pmu_idx = get_rapl_pmu_idx(event->cpu);
|
|
||||||
- if (rapl_pmu_idx >= rapl_pmus->nr_rapl_pmu)
|
|
||||||
+ if (rapl_pmu_idx >= rapl_pmus_pkg->nr_rapl_pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* must be done before validate_group */
|
|
||||||
- rapl_pmu = rapl_pmus->rapl_pmu[rapl_pmu_idx];
|
|
||||||
+ rapl_pmu = rapl_pmus_pkg->rapl_pmu[rapl_pmu_idx];
|
|
||||||
if (!rapl_pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
@@ -530,11 +530,11 @@ static struct perf_msr intel_rapl_spr_ms
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * Force to PERF_RAPL_MAX size due to:
|
|
||||||
- * - perf_msr_probe(PERF_RAPL_MAX)
|
|
||||||
+ * Force to PERF_RAPL_PKG_EVENTS_MAX size due to:
|
|
||||||
+ * - perf_msr_probe(PERF_RAPL_PKG_EVENTS_MAX)
|
|
||||||
* - want to use same event codes across both architectures
|
|
||||||
*/
|
|
||||||
-static struct perf_msr amd_rapl_msrs[] = {
|
|
||||||
+static struct perf_msr amd_rapl_pkg_msrs[] = {
|
|
||||||
[PERF_RAPL_PP0] = { 0, &rapl_events_cores_group, NULL, false, 0 },
|
|
||||||
[PERF_RAPL_PKG] = { MSR_AMD_PKG_ENERGY_STATUS, &rapl_events_pkg_group, test_msr, false, RAPL_MSR_MASK },
|
|
||||||
[PERF_RAPL_RAM] = { 0, &rapl_events_ram_group, NULL, false, 0 },
|
|
||||||
@@ -550,8 +550,8 @@ static int rapl_check_hw_unit(void)
|
|
||||||
/* protect rdmsrl() to handle virtualization */
|
|
||||||
if (rdmsrl_safe(rapl_model->msr_power_unit, &msr_rapl_power_unit_bits))
|
|
||||||
return -1;
|
|
||||||
- for (i = 0; i < NR_RAPL_DOMAINS; i++)
|
|
||||||
- rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
|
||||||
+ for (i = 0; i < NR_RAPL_PKG_DOMAINS; i++)
|
|
||||||
+ rapl_pkg_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
|
||||||
|
|
||||||
switch (rapl_model->unit_quirk) {
|
|
||||||
/*
|
|
||||||
@@ -561,11 +561,11 @@ static int rapl_check_hw_unit(void)
|
|
||||||
* of 2. Datasheet, September 2014, Reference Number: 330784-001 "
|
|
||||||
*/
|
|
||||||
case RAPL_UNIT_QUIRK_INTEL_HSW:
|
|
||||||
- rapl_hw_unit[PERF_RAPL_RAM] = 16;
|
|
||||||
+ rapl_pkg_hw_unit[PERF_RAPL_RAM] = 16;
|
|
||||||
break;
|
|
||||||
/* SPR uses a fixed energy unit for Psys domain. */
|
|
||||||
case RAPL_UNIT_QUIRK_INTEL_SPR:
|
|
||||||
- rapl_hw_unit[PERF_RAPL_PSYS] = 0;
|
|
||||||
+ rapl_pkg_hw_unit[PERF_RAPL_PSYS] = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
@@ -580,9 +580,9 @@ static int rapl_check_hw_unit(void)
|
|
||||||
* if hw unit is 32, then we use 2 ms 1/200/2
|
|
||||||
*/
|
|
||||||
rapl_timer_ms = 2;
|
|
||||||
- if (rapl_hw_unit[0] < 32) {
|
|
||||||
+ if (rapl_pkg_hw_unit[0] < 32) {
|
|
||||||
rapl_timer_ms = (1000 / (2 * 100));
|
|
||||||
- rapl_timer_ms *= (1ULL << (32 - rapl_hw_unit[0] - 1));
|
|
||||||
+ rapl_timer_ms *= (1ULL << (32 - rapl_pkg_hw_unit[0] - 1));
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -592,12 +592,12 @@ static void __init rapl_advertise(void)
|
|
||||||
int i;
|
|
||||||
|
|
||||||
pr_info("API unit is 2^-32 Joules, %d fixed counters, %llu ms ovfl timer\n",
|
|
||||||
- hweight32(rapl_cntr_mask), rapl_timer_ms);
|
|
||||||
+ hweight32(rapl_pkg_cntr_mask), rapl_timer_ms);
|
|
||||||
|
|
||||||
- for (i = 0; i < NR_RAPL_DOMAINS; i++) {
|
|
||||||
- if (rapl_cntr_mask & (1 << i)) {
|
|
||||||
+ for (i = 0; i < NR_RAPL_PKG_DOMAINS; i++) {
|
|
||||||
+ if (rapl_pkg_cntr_mask & (1 << i)) {
|
|
||||||
pr_info("hw unit of domain %s 2^-%d Joules\n",
|
|
||||||
- rapl_domain_names[i], rapl_hw_unit[i]);
|
|
||||||
+ rapl_pkg_domain_names[i], rapl_pkg_hw_unit[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -678,71 +678,71 @@ static int __init init_rapl_pmus(struct
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct rapl_model model_snb = {
|
|
||||||
- .events = BIT(PERF_RAPL_PP0) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PP0) |
|
|
||||||
BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_PP1),
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_snbep = {
|
|
||||||
- .events = BIT(PERF_RAPL_PP0) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PP0) |
|
|
||||||
BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_RAM),
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_hsw = {
|
|
||||||
- .events = BIT(PERF_RAPL_PP0) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PP0) |
|
|
||||||
BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_RAM) |
|
|
||||||
BIT(PERF_RAPL_PP1),
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_hsx = {
|
|
||||||
- .events = BIT(PERF_RAPL_PP0) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PP0) |
|
|
||||||
BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_RAM),
|
|
||||||
.unit_quirk = RAPL_UNIT_QUIRK_INTEL_HSW,
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_knl = {
|
|
||||||
- .events = BIT(PERF_RAPL_PKG) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_RAM),
|
|
||||||
.unit_quirk = RAPL_UNIT_QUIRK_INTEL_HSW,
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_skl = {
|
|
||||||
- .events = BIT(PERF_RAPL_PP0) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PP0) |
|
|
||||||
BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_RAM) |
|
|
||||||
BIT(PERF_RAPL_PP1) |
|
|
||||||
BIT(PERF_RAPL_PSYS),
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_spr = {
|
|
||||||
- .events = BIT(PERF_RAPL_PP0) |
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PP0) |
|
|
||||||
BIT(PERF_RAPL_PKG) |
|
|
||||||
BIT(PERF_RAPL_RAM) |
|
|
||||||
BIT(PERF_RAPL_PSYS),
|
|
||||||
.unit_quirk = RAPL_UNIT_QUIRK_INTEL_SPR,
|
|
||||||
.msr_power_unit = MSR_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = intel_rapl_spr_msrs,
|
|
||||||
+ .rapl_pkg_msrs = intel_rapl_spr_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rapl_model model_amd_hygon = {
|
|
||||||
- .events = BIT(PERF_RAPL_PKG),
|
|
||||||
+ .pkg_events = BIT(PERF_RAPL_PKG),
|
|
||||||
.msr_power_unit = MSR_AMD_RAPL_POWER_UNIT,
|
|
||||||
- .rapl_msrs = amd_rapl_msrs,
|
|
||||||
+ .rapl_pkg_msrs = amd_rapl_pkg_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct x86_cpu_id rapl_model_match[] __initconst = {
|
|
||||||
@@ -798,11 +798,11 @@ MODULE_DEVICE_TABLE(x86cpu, rapl_model_m
|
|
||||||
static int __init rapl_pmu_init(void)
|
|
||||||
{
|
|
||||||
const struct x86_cpu_id *id;
|
|
||||||
- int rapl_pmu_scope = PERF_PMU_SCOPE_DIE;
|
|
||||||
+ int rapl_pkg_pmu_scope = PERF_PMU_SCOPE_DIE;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- if (rapl_pmu_is_pkg_scope())
|
|
||||||
- rapl_pmu_scope = PERF_PMU_SCOPE_PKG;
|
|
||||||
+ if (rapl_pkg_pmu_is_pkg_scope())
|
|
||||||
+ rapl_pkg_pmu_scope = PERF_PMU_SCOPE_PKG;
|
|
||||||
|
|
||||||
id = x86_match_cpu(rapl_model_match);
|
|
||||||
if (!id)
|
|
||||||
@@ -810,20 +810,20 @@ static int __init rapl_pmu_init(void)
|
|
||||||
|
|
||||||
rapl_model = (struct rapl_model *) id->driver_data;
|
|
||||||
|
|
||||||
- rapl_msrs = rapl_model->rapl_msrs;
|
|
||||||
+ rapl_msrs = rapl_model->rapl_pkg_msrs;
|
|
||||||
|
|
||||||
- rapl_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_MAX,
|
|
||||||
- false, (void *) &rapl_model->events);
|
|
||||||
+ rapl_pkg_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
+ false, (void *) &rapl_model->pkg_events);
|
|
||||||
|
|
||||||
ret = rapl_check_hw_unit();
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = init_rapl_pmus(&rapl_pmus, rapl_pmu_scope);
|
|
||||||
+ ret = init_rapl_pmus(&rapl_pmus_pkg, rapl_pkg_pmu_scope);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = perf_pmu_register(&rapl_pmus->pmu, "power", -1);
|
|
||||||
+ ret = perf_pmu_register(&rapl_pmus_pkg->pmu, "power", -1);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
@@ -832,14 +832,14 @@ static int __init rapl_pmu_init(void)
|
|
||||||
|
|
||||||
out:
|
|
||||||
pr_warn("Initialization failed (%d), disabled\n", ret);
|
|
||||||
- cleanup_rapl_pmus(rapl_pmus);
|
|
||||||
+ cleanup_rapl_pmus(rapl_pmus_pkg);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
module_init(rapl_pmu_init);
|
|
||||||
|
|
||||||
static void __exit intel_rapl_exit(void)
|
|
||||||
{
|
|
||||||
- perf_pmu_unregister(&rapl_pmus->pmu);
|
|
||||||
- cleanup_rapl_pmus(rapl_pmus);
|
|
||||||
+ perf_pmu_unregister(&rapl_pmus_pkg->pmu);
|
|
||||||
+ cleanup_rapl_pmus(rapl_pmus_pkg);
|
|
||||||
}
|
|
||||||
module_exit(intel_rapl_exit);
|
|
@ -1,48 +0,0 @@
|
|||||||
From ea8de8012d6d6ef2c24c45a56f230e3a7fcb8ce7 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:04 +0000
|
|
||||||
Subject: perf/x86/rapl: Remove the global variable rapl_msrs
|
|
||||||
|
|
||||||
Prepare for the addition of RAPL core energy counter support.
|
|
||||||
|
|
||||||
After making the rapl_model struct global, the rapl_msrs global
|
|
||||||
variable isn't needed, so remove it.
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 7 ++-----
|
|
||||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -150,7 +150,6 @@ static int rapl_pkg_hw_unit[NR_RAPL_PKG_
|
|
||||||
static struct rapl_pmus *rapl_pmus_pkg;
|
|
||||||
static unsigned int rapl_pkg_cntr_mask;
|
|
||||||
static u64 rapl_timer_ms;
|
|
||||||
-static struct perf_msr *rapl_msrs;
|
|
||||||
static struct rapl_model *rapl_model;
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -381,7 +380,7 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
event->pmu_private = rapl_pmu;
|
|
||||||
- event->hw.event_base = rapl_msrs[bit].msr;
|
|
||||||
+ event->hw.event_base = rapl_model->rapl_pkg_msrs[bit].msr;
|
|
||||||
event->hw.config = cfg;
|
|
||||||
event->hw.idx = bit;
|
|
||||||
|
|
||||||
@@ -810,9 +809,7 @@ static int __init rapl_pmu_init(void)
|
|
||||||
|
|
||||||
rapl_model = (struct rapl_model *) id->driver_data;
|
|
||||||
|
|
||||||
- rapl_msrs = rapl_model->rapl_pkg_msrs;
|
|
||||||
-
|
|
||||||
- rapl_pkg_cntr_mask = perf_msr_probe(rapl_msrs, PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
+ rapl_pkg_cntr_mask = perf_msr_probe(rapl_model->rapl_pkg_msrs, PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
false, (void *) &rapl_model->pkg_events);
|
|
||||||
|
|
||||||
ret = rapl_check_hw_unit();
|
|
@ -1,81 +0,0 @@
|
|||||||
From 8cbd0e18e5b36bbfdb5ca8931a7668c7963be8e5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:05 +0000
|
|
||||||
Subject: perf/x86/rapl: Move the cntr_mask to rapl_pmus struct
|
|
||||||
|
|
||||||
Prepare for the addition of RAPL core energy counter support.
|
|
||||||
|
|
||||||
Move cntr_mask to rapl_pmus struct instead of adding a new global
|
|
||||||
cntr_mask for the new RAPL power_core PMU. This will also ensure that
|
|
||||||
the second "core_cntr_mask" is only created if needed (i.e. in case of
|
|
||||||
AMD CPUs).
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
Reviewed-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
Tested-by: Zhang Rui <rui.zhang@intel.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 15 ++++++++-------
|
|
||||||
1 file changed, 8 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -129,6 +129,7 @@ struct rapl_pmu {
|
|
||||||
struct rapl_pmus {
|
|
||||||
struct pmu pmu;
|
|
||||||
unsigned int nr_rapl_pmu;
|
|
||||||
+ unsigned int cntr_mask;
|
|
||||||
struct rapl_pmu *rapl_pmu[] __counted_by(nr_rapl_pmu);
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -148,7 +149,6 @@ struct rapl_model {
|
|
||||||
/* 1/2^hw_unit Joule */
|
|
||||||
static int rapl_pkg_hw_unit[NR_RAPL_PKG_DOMAINS] __read_mostly;
|
|
||||||
static struct rapl_pmus *rapl_pmus_pkg;
|
|
||||||
-static unsigned int rapl_pkg_cntr_mask;
|
|
||||||
static u64 rapl_timer_ms;
|
|
||||||
static struct rapl_model *rapl_model;
|
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
bit = cfg - 1;
|
|
||||||
|
|
||||||
/* check event supported */
|
|
||||||
- if (!(rapl_pkg_cntr_mask & (1 << bit)))
|
|
||||||
+ if (!(rapl_pmus_pkg->cntr_mask & (1 << bit)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
/* unsupported modes and filters */
|
|
||||||
@@ -591,10 +591,10 @@ static void __init rapl_advertise(void)
|
|
||||||
int i;
|
|
||||||
|
|
||||||
pr_info("API unit is 2^-32 Joules, %d fixed counters, %llu ms ovfl timer\n",
|
|
||||||
- hweight32(rapl_pkg_cntr_mask), rapl_timer_ms);
|
|
||||||
+ hweight32(rapl_pmus_pkg->cntr_mask), rapl_timer_ms);
|
|
||||||
|
|
||||||
for (i = 0; i < NR_RAPL_PKG_DOMAINS; i++) {
|
|
||||||
- if (rapl_pkg_cntr_mask & (1 << i)) {
|
|
||||||
+ if (rapl_pmus_pkg->cntr_mask & (1 << i)) {
|
|
||||||
pr_info("hw unit of domain %s 2^-%d Joules\n",
|
|
||||||
rapl_pkg_domain_names[i], rapl_pkg_hw_unit[i]);
|
|
||||||
}
|
|
||||||
@@ -809,9 +809,6 @@ static int __init rapl_pmu_init(void)
|
|
||||||
|
|
||||||
rapl_model = (struct rapl_model *) id->driver_data;
|
|
||||||
|
|
||||||
- rapl_pkg_cntr_mask = perf_msr_probe(rapl_model->rapl_pkg_msrs, PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
- false, (void *) &rapl_model->pkg_events);
|
|
||||||
-
|
|
||||||
ret = rapl_check_hw_unit();
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
@@ -820,6 +817,10 @@ static int __init rapl_pmu_init(void)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
+ rapl_pmus_pkg->cntr_mask = perf_msr_probe(rapl_model->rapl_pkg_msrs,
|
|
||||||
+ PERF_RAPL_PKG_EVENTS_MAX, false,
|
|
||||||
+ (void *) &rapl_model->pkg_events);
|
|
||||||
+
|
|
||||||
ret = perf_pmu_register(&rapl_pmus_pkg->pmu, "power", -1);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
@ -1,444 +0,0 @@
|
|||||||
From 27bdf22a4c7815831d38acd1cb08e5aa6ce95ea0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Date: Fri, 15 Nov 2024 06:08:06 +0000
|
|
||||||
Subject: perf/x86/rapl: Add core energy counter support for AMD CPUs
|
|
||||||
|
|
||||||
Add a new "power_core" PMU and "energy-core" event for monitoring
|
|
||||||
energy consumption by each individual core. The existing energy-cores
|
|
||||||
event aggregates the energy consumption of CPU cores at the package level.
|
|
||||||
This new event aligns with the AMD's per-core energy counters.
|
|
||||||
|
|
||||||
Tested the package level and core level PMU counters with workloads
|
|
||||||
pinned to different CPUs.
|
|
||||||
|
|
||||||
Results with workload pinned to CPU 4 in core 4 on an AMD Zen4 Genoa
|
|
||||||
machine:
|
|
||||||
|
|
||||||
$ sudo perf stat --per-core -e power_core/energy-core/ -- taskset -c 4 stress-ng --matrix 1 --timeout 5s
|
|
||||||
stress-ng: info: [21250] setting to a 5 second run per stressor
|
|
||||||
stress-ng: info: [21250] dispatching hogs: 1 matrix
|
|
||||||
stress-ng: info: [21250] successful run completed in 5.00s
|
|
||||||
|
|
||||||
Performance counter stats for 'system wide':
|
|
||||||
|
|
||||||
S0-D0-C0 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D0-C1 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D0-C2 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D0-C3 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D0-C4 1 8.43 Joules power_core/energy-core/
|
|
||||||
S0-D0-C5 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D0-C6 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D0-C7 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D1-C8 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D1-C9 1 0.00 Joules power_core/energy-core/
|
|
||||||
S0-D1-C10 1 0.00 Joules power_core/energy-core/
|
|
||||||
|
|
||||||
Signed-off-by: Dhananjay Ugwekar <Dhananjay.Ugwekar@amd.com>
|
|
||||||
Reviewed-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 185 +++++++++++++++++++++++++++++++++--------
|
|
||||||
1 file changed, 152 insertions(+), 33 deletions(-)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -39,6 +39,10 @@
|
|
||||||
* event: rapl_energy_psys
|
|
||||||
* perf code: 0x5
|
|
||||||
*
|
|
||||||
+ * core counter: consumption of a single physical core
|
|
||||||
+ * event: rapl_energy_core (power_core PMU)
|
|
||||||
+ * perf code: 0x1
|
|
||||||
+ *
|
|
||||||
* We manage those counters as free running (read-only). They may be
|
|
||||||
* use simultaneously by other tools, such as turbostat.
|
|
||||||
*
|
|
||||||
@@ -81,6 +85,10 @@ enum perf_rapl_pkg_events {
|
|
||||||
NR_RAPL_PKG_DOMAINS = PERF_RAPL_PKG_EVENTS_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
+#define PERF_RAPL_CORE 0 /* single core */
|
|
||||||
+#define PERF_RAPL_CORE_EVENTS_MAX 1
|
|
||||||
+#define NR_RAPL_CORE_DOMAINS PERF_RAPL_CORE_EVENTS_MAX
|
|
||||||
+
|
|
||||||
static const char *const rapl_pkg_domain_names[NR_RAPL_PKG_DOMAINS] __initconst = {
|
|
||||||
"pp0-core",
|
|
||||||
"package",
|
|
||||||
@@ -89,6 +97,8 @@ static const char *const rapl_pkg_domain
|
|
||||||
"psys",
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const char *const rapl_core_domain_name __initconst = "core";
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* event code: LSB 8 bits, passed in attr->config
|
|
||||||
* any other bit is reserved
|
|
||||||
@@ -141,14 +151,18 @@ enum rapl_unit_quirk {
|
|
||||||
|
|
||||||
struct rapl_model {
|
|
||||||
struct perf_msr *rapl_pkg_msrs;
|
|
||||||
+ struct perf_msr *rapl_core_msrs;
|
|
||||||
unsigned long pkg_events;
|
|
||||||
+ unsigned long core_events;
|
|
||||||
unsigned int msr_power_unit;
|
|
||||||
enum rapl_unit_quirk unit_quirk;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 1/2^hw_unit Joule */
|
|
||||||
static int rapl_pkg_hw_unit[NR_RAPL_PKG_DOMAINS] __read_mostly;
|
|
||||||
+static int rapl_core_hw_unit __read_mostly;
|
|
||||||
static struct rapl_pmus *rapl_pmus_pkg;
|
|
||||||
+static struct rapl_pmus *rapl_pmus_core;
|
|
||||||
static u64 rapl_timer_ms;
|
|
||||||
static struct rapl_model *rapl_model;
|
|
||||||
|
|
||||||
@@ -156,14 +170,23 @@ static struct rapl_model *rapl_model;
|
|
||||||
* Helper function to get the correct topology id according to the
|
|
||||||
* RAPL PMU scope.
|
|
||||||
*/
|
|
||||||
-static inline unsigned int get_rapl_pmu_idx(int cpu)
|
|
||||||
-{ /*
|
|
||||||
+static inline unsigned int get_rapl_pmu_idx(int cpu, int scope)
|
|
||||||
+{
|
|
||||||
+ /*
|
|
||||||
* Returns unsigned int, which converts the '-1' return value
|
|
||||||
* (for non-existent mappings in topology map) to UINT_MAX, so
|
|
||||||
* the error check in the caller is simplified.
|
|
||||||
*/
|
|
||||||
- return rapl_pkg_pmu_is_pkg_scope() ? topology_logical_package_id(cpu) :
|
|
||||||
- topology_logical_die_id(cpu);
|
|
||||||
+ switch (scope) {
|
|
||||||
+ case PERF_PMU_SCOPE_PKG:
|
|
||||||
+ return topology_logical_package_id(cpu);
|
|
||||||
+ case PERF_PMU_SCOPE_DIE:
|
|
||||||
+ return topology_logical_die_id(cpu);
|
|
||||||
+ case PERF_PMU_SCOPE_CORE:
|
|
||||||
+ return topology_logical_core_id(cpu);
|
|
||||||
+ default:
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u64 rapl_read_counter(struct perf_event *event)
|
|
||||||
@@ -173,19 +196,20 @@ static inline u64 rapl_read_counter(stru
|
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static inline u64 rapl_scale(u64 v, int cfg)
|
|
||||||
+static inline u64 rapl_scale(u64 v, struct perf_event *event)
|
|
||||||
{
|
|
||||||
- if (cfg > NR_RAPL_PKG_DOMAINS) {
|
|
||||||
- pr_warn("Invalid domain %d, failed to scale data\n", cfg);
|
|
||||||
- return v;
|
|
||||||
- }
|
|
||||||
+ int hw_unit = rapl_pkg_hw_unit[event->hw.config - 1];
|
|
||||||
+
|
|
||||||
+ if (event->pmu->scope == PERF_PMU_SCOPE_CORE)
|
|
||||||
+ hw_unit = rapl_core_hw_unit;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* scale delta to smallest unit (1/2^32)
|
|
||||||
* users must then scale back: count * 1/(1e9*2^32) to get Joules
|
|
||||||
* or use ldexp(count, -32).
|
|
||||||
* Watts = Joules/Time delta
|
|
||||||
*/
|
|
||||||
- return v << (32 - rapl_pkg_hw_unit[cfg - 1]);
|
|
||||||
+ return v << (32 - hw_unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static u64 rapl_event_update(struct perf_event *event)
|
|
||||||
@@ -212,7 +236,7 @@ static u64 rapl_event_update(struct perf
|
|
||||||
delta = (new_raw_count << shift) - (prev_raw_count << shift);
|
|
||||||
delta >>= shift;
|
|
||||||
|
|
||||||
- sdelta = rapl_scale(delta, event->hw.config);
|
|
||||||
+ sdelta = rapl_scale(delta, event);
|
|
||||||
|
|
||||||
local64_add(sdelta, &event->count);
|
|
||||||
|
|
||||||
@@ -341,13 +365,14 @@ static void rapl_pmu_event_del(struct pe
|
|
||||||
static int rapl_pmu_event_init(struct perf_event *event)
|
|
||||||
{
|
|
||||||
u64 cfg = event->attr.config & RAPL_EVENT_MASK;
|
|
||||||
- int bit, ret = 0;
|
|
||||||
+ int bit, rapl_pmus_scope, ret = 0;
|
|
||||||
struct rapl_pmu *rapl_pmu;
|
|
||||||
unsigned int rapl_pmu_idx;
|
|
||||||
+ struct rapl_pmus *rapl_pmus;
|
|
||||||
|
|
||||||
- /* only look at RAPL events */
|
|
||||||
- if (event->attr.type != rapl_pmus_pkg->pmu.type)
|
|
||||||
- return -ENOENT;
|
|
||||||
+ /* unsupported modes and filters */
|
|
||||||
+ if (event->attr.sample_period) /* no sampling */
|
|
||||||
+ return -EINVAL;
|
|
||||||
|
|
||||||
/* check only supported bits are set */
|
|
||||||
if (event->attr.config & ~RAPL_EVENT_MASK)
|
|
||||||
@@ -356,31 +381,49 @@ static int rapl_pmu_event_init(struct pe
|
|
||||||
if (event->cpu < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
|
|
||||||
+ rapl_pmus = container_of(event->pmu, struct rapl_pmus, pmu);
|
|
||||||
+ if (!rapl_pmus)
|
|
||||||
return -EINVAL;
|
|
||||||
+ rapl_pmus_scope = rapl_pmus->pmu.scope;
|
|
||||||
|
|
||||||
- cfg = array_index_nospec((long)cfg, NR_RAPL_PKG_DOMAINS + 1);
|
|
||||||
- bit = cfg - 1;
|
|
||||||
-
|
|
||||||
- /* check event supported */
|
|
||||||
- if (!(rapl_pmus_pkg->cntr_mask & (1 << bit)))
|
|
||||||
+ if (rapl_pmus_scope == PERF_PMU_SCOPE_PKG || rapl_pmus_scope == PERF_PMU_SCOPE_DIE) {
|
|
||||||
+ /* only look at RAPL package events */
|
|
||||||
+ if (event->attr.type != rapl_pmus_pkg->pmu.type)
|
|
||||||
+ return -ENOENT;
|
|
||||||
+
|
|
||||||
+ cfg = array_index_nospec((long)cfg, NR_RAPL_PKG_DOMAINS + 1);
|
|
||||||
+ if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
+ bit = cfg - 1;
|
|
||||||
+ event->hw.event_base = rapl_model->rapl_pkg_msrs[bit].msr;
|
|
||||||
+ } else if (rapl_pmus_scope == PERF_PMU_SCOPE_CORE) {
|
|
||||||
+ /* only look at RAPL core events */
|
|
||||||
+ if (event->attr.type != rapl_pmus_core->pmu.type)
|
|
||||||
+ return -ENOENT;
|
|
||||||
+
|
|
||||||
+ cfg = array_index_nospec((long)cfg, NR_RAPL_CORE_DOMAINS + 1);
|
|
||||||
+ if (!cfg || cfg >= NR_RAPL_PKG_DOMAINS + 1)
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
+ bit = cfg - 1;
|
|
||||||
+ event->hw.event_base = rapl_model->rapl_core_msrs[bit].msr;
|
|
||||||
+ } else
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- /* unsupported modes and filters */
|
|
||||||
- if (event->attr.sample_period) /* no sampling */
|
|
||||||
+ /* check event supported */
|
|
||||||
+ if (!(rapl_pmus->cntr_mask & (1 << bit)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
- rapl_pmu_idx = get_rapl_pmu_idx(event->cpu);
|
|
||||||
- if (rapl_pmu_idx >= rapl_pmus_pkg->nr_rapl_pmu)
|
|
||||||
+ rapl_pmu_idx = get_rapl_pmu_idx(event->cpu, rapl_pmus_scope);
|
|
||||||
+ if (rapl_pmu_idx >= rapl_pmus->nr_rapl_pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
-
|
|
||||||
/* must be done before validate_group */
|
|
||||||
- rapl_pmu = rapl_pmus_pkg->rapl_pmu[rapl_pmu_idx];
|
|
||||||
+ rapl_pmu = rapl_pmus->rapl_pmu[rapl_pmu_idx];
|
|
||||||
if (!rapl_pmu)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
event->pmu_private = rapl_pmu;
|
|
||||||
- event->hw.event_base = rapl_model->rapl_pkg_msrs[bit].msr;
|
|
||||||
event->hw.config = cfg;
|
|
||||||
event->hw.idx = bit;
|
|
||||||
|
|
||||||
@@ -397,12 +440,14 @@ RAPL_EVENT_ATTR_STR(energy-pkg , rapl
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-psys, rapl_psys, "event=0x05");
|
|
||||||
+RAPL_EVENT_ATTR_STR(energy-core, rapl_core, "event=0x01");
|
|
||||||
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-psys.unit, rapl_psys_unit, "Joules");
|
|
||||||
+RAPL_EVENT_ATTR_STR(energy-core.unit, rapl_core_unit, "Joules");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* we compute in 0.23 nJ increments regardless of MSR
|
|
||||||
@@ -412,6 +457,7 @@ RAPL_EVENT_ATTR_STR(energy-pkg.scale,
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10");
|
|
||||||
RAPL_EVENT_ATTR_STR(energy-psys.scale, rapl_psys_scale, "2.3283064365386962890625e-10");
|
|
||||||
+RAPL_EVENT_ATTR_STR(energy-core.scale, rapl_core_scale, "2.3283064365386962890625e-10");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are no default events, but we need to create
|
|
||||||
@@ -444,6 +490,12 @@ static const struct attribute_group *rap
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct attribute_group *rapl_core_attr_groups[] = {
|
|
||||||
+ &rapl_pmu_format_group,
|
|
||||||
+ &rapl_pmu_events_group,
|
|
||||||
+ NULL,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct attribute *rapl_events_cores[] = {
|
|
||||||
EVENT_PTR(rapl_cores),
|
|
||||||
EVENT_PTR(rapl_cores_unit),
|
|
||||||
@@ -504,6 +556,18 @@ static struct attribute_group rapl_event
|
|
||||||
.attrs = rapl_events_psys,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *rapl_events_core[] = {
|
|
||||||
+ EVENT_PTR(rapl_core),
|
|
||||||
+ EVENT_PTR(rapl_core_unit),
|
|
||||||
+ EVENT_PTR(rapl_core_scale),
|
|
||||||
+ NULL,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group rapl_events_core_group = {
|
|
||||||
+ .name = "events",
|
|
||||||
+ .attrs = rapl_events_core,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static bool test_msr(int idx, void *data)
|
|
||||||
{
|
|
||||||
return test_bit(idx, (unsigned long *) data);
|
|
||||||
@@ -541,6 +605,11 @@ static struct perf_msr amd_rapl_pkg_msrs
|
|
||||||
[PERF_RAPL_PSYS] = { 0, &rapl_events_psys_group, NULL, false, 0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct perf_msr amd_rapl_core_msrs[] = {
|
|
||||||
+ [PERF_RAPL_CORE] = { MSR_AMD_CORE_ENERGY_STATUS, &rapl_events_core_group,
|
|
||||||
+ test_msr, false, RAPL_MSR_MASK },
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int rapl_check_hw_unit(void)
|
|
||||||
{
|
|
||||||
u64 msr_rapl_power_unit_bits;
|
|
||||||
@@ -552,6 +621,8 @@ static int rapl_check_hw_unit(void)
|
|
||||||
for (i = 0; i < NR_RAPL_PKG_DOMAINS; i++)
|
|
||||||
rapl_pkg_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
|
||||||
|
|
||||||
+ rapl_core_hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
|
|
||||||
+
|
|
||||||
switch (rapl_model->unit_quirk) {
|
|
||||||
/*
|
|
||||||
* DRAM domain on HSW server and KNL has fixed energy unit which can be
|
|
||||||
@@ -570,7 +641,6 @@ static int rapl_check_hw_unit(void)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Calculate the timer rate:
|
|
||||||
* Use reference of 200W for scaling the timeout to avoid counter
|
|
||||||
@@ -589,9 +659,13 @@ static int rapl_check_hw_unit(void)
|
|
||||||
static void __init rapl_advertise(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
+ int num_counters = hweight32(rapl_pmus_pkg->cntr_mask);
|
|
||||||
+
|
|
||||||
+ if (rapl_pmus_core)
|
|
||||||
+ num_counters += hweight32(rapl_pmus_core->cntr_mask);
|
|
||||||
|
|
||||||
pr_info("API unit is 2^-32 Joules, %d fixed counters, %llu ms ovfl timer\n",
|
|
||||||
- hweight32(rapl_pmus_pkg->cntr_mask), rapl_timer_ms);
|
|
||||||
+ num_counters, rapl_timer_ms);
|
|
||||||
|
|
||||||
for (i = 0; i < NR_RAPL_PKG_DOMAINS; i++) {
|
|
||||||
if (rapl_pmus_pkg->cntr_mask & (1 << i)) {
|
|
||||||
@@ -599,6 +673,10 @@ static void __init rapl_advertise(void)
|
|
||||||
rapl_pkg_domain_names[i], rapl_pkg_hw_unit[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (rapl_pmus_core && (rapl_pmus_core->cntr_mask & (1 << PERF_RAPL_CORE)))
|
|
||||||
+ pr_info("hw unit of domain %s 2^-%d Joules\n",
|
|
||||||
+ rapl_core_domain_name, rapl_core_hw_unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cleanup_rapl_pmus(struct rapl_pmus *rapl_pmus)
|
|
||||||
@@ -619,6 +697,10 @@ static const struct attribute_group *rap
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct attribute_group *rapl_core_attr_update[] = {
|
|
||||||
+ &rapl_events_core_group,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int __init init_rapl_pmu(struct rapl_pmus *rapl_pmus)
|
|
||||||
{
|
|
||||||
struct rapl_pmu *rapl_pmu;
|
|
||||||
@@ -645,13 +727,22 @@ free:
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int __init init_rapl_pmus(struct rapl_pmus **rapl_pmus_ptr, int rapl_pmu_scope)
|
|
||||||
+static int __init init_rapl_pmus(struct rapl_pmus **rapl_pmus_ptr, int rapl_pmu_scope,
|
|
||||||
+ const struct attribute_group **rapl_attr_groups,
|
|
||||||
+ const struct attribute_group **rapl_attr_update)
|
|
||||||
{
|
|
||||||
int nr_rapl_pmu = topology_max_packages();
|
|
||||||
struct rapl_pmus *rapl_pmus;
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * rapl_pmu_scope must be either PKG, DIE or CORE
|
|
||||||
+ */
|
|
||||||
if (rapl_pmu_scope == PERF_PMU_SCOPE_DIE)
|
|
||||||
nr_rapl_pmu *= topology_max_dies_per_package();
|
|
||||||
+ else if (rapl_pmu_scope == PERF_PMU_SCOPE_CORE)
|
|
||||||
+ nr_rapl_pmu *= topology_num_cores_per_package();
|
|
||||||
+ else if (rapl_pmu_scope != PERF_PMU_SCOPE_PKG)
|
|
||||||
+ return -EINVAL;
|
|
||||||
|
|
||||||
rapl_pmus = kzalloc(struct_size(rapl_pmus, rapl_pmu, nr_rapl_pmu), GFP_KERNEL);
|
|
||||||
if (!rapl_pmus)
|
|
||||||
@@ -740,8 +831,10 @@ static struct rapl_model model_spr = {
|
|
||||||
|
|
||||||
static struct rapl_model model_amd_hygon = {
|
|
||||||
.pkg_events = BIT(PERF_RAPL_PKG),
|
|
||||||
+ .core_events = BIT(PERF_RAPL_CORE),
|
|
||||||
.msr_power_unit = MSR_AMD_RAPL_POWER_UNIT,
|
|
||||||
.rapl_pkg_msrs = amd_rapl_pkg_msrs,
|
|
||||||
+ .rapl_core_msrs = amd_rapl_core_msrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct x86_cpu_id rapl_model_match[] __initconst = {
|
|
||||||
@@ -813,7 +906,8 @@ static int __init rapl_pmu_init(void)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = init_rapl_pmus(&rapl_pmus_pkg, rapl_pkg_pmu_scope);
|
|
||||||
+ ret = init_rapl_pmus(&rapl_pmus_pkg, rapl_pkg_pmu_scope, rapl_attr_groups,
|
|
||||||
+ rapl_attr_update);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
@@ -825,6 +919,27 @@ static int __init rapl_pmu_init(void)
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
+ if (rapl_model->core_events) {
|
|
||||||
+ ret = init_rapl_pmus(&rapl_pmus_core, PERF_PMU_SCOPE_CORE,
|
|
||||||
+ rapl_core_attr_groups,
|
|
||||||
+ rapl_core_attr_update);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_warn("power-core PMU initialization failed (%d)\n", ret);
|
|
||||||
+ goto core_init_failed;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ rapl_pmus_core->cntr_mask = perf_msr_probe(rapl_model->rapl_core_msrs,
|
|
||||||
+ PERF_RAPL_CORE_EVENTS_MAX, false,
|
|
||||||
+ (void *) &rapl_model->core_events);
|
|
||||||
+
|
|
||||||
+ ret = perf_pmu_register(&rapl_pmus_core->pmu, "power_core", -1);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_warn("power-core PMU registration failed (%d)\n", ret);
|
|
||||||
+ cleanup_rapl_pmus(rapl_pmus_core);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+core_init_failed:
|
|
||||||
rapl_advertise();
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
@@ -837,6 +952,10 @@ module_init(rapl_pmu_init);
|
|
||||||
|
|
||||||
static void __exit intel_rapl_exit(void)
|
|
||||||
{
|
|
||||||
+ if (rapl_pmus_core) {
|
|
||||||
+ perf_pmu_unregister(&rapl_pmus_core->pmu);
|
|
||||||
+ cleanup_rapl_pmus(rapl_pmus_core);
|
|
||||||
+ }
|
|
||||||
perf_pmu_unregister(&rapl_pmus_pkg->pmu);
|
|
||||||
cleanup_rapl_pmus(rapl_pmus_pkg);
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
From c66779234fa7ba71cefa1c4eb283db53a3cb5303 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Oleksandr Natalenko <oleksandr@natalenko.name>
|
|
||||||
Date: Sat, 23 Nov 2024 12:45:28 +0100
|
|
||||||
Subject: amd-rapl-6.12: fix clang-built kernel not booting
|
|
||||||
|
|
||||||
Link: https://lore.kernel.org/lkml/7eaf557d-7e85-4fd3-abee-f84ac01d92c1@amd.com/
|
|
||||||
Signed-off-by: Oleksandr Natalenko <oleksandr@natalenko.name>
|
|
||||||
---
|
|
||||||
arch/x86/events/rapl.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
--- a/arch/x86/events/rapl.c
|
|
||||||
+++ b/arch/x86/events/rapl.c
|
|
||||||
@@ -699,6 +699,7 @@ static const struct attribute_group *rap
|
|
||||||
|
|
||||||
static const struct attribute_group *rapl_core_attr_update[] = {
|
|
||||||
&rapl_events_core_group,
|
|
||||||
+ NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int __init init_rapl_pmu(struct rapl_pmus *rapl_pmus)
|
|
@ -46,7 +46,7 @@ Suggested-by: David Hildenbrand <david@redhat.com>
|
|||||||
hugetlb_zap_begin(vma, &range.start, &range.end);
|
hugetlb_zap_begin(vma, &range.start, &range.end);
|
||||||
--- a/mm/mmap.c
|
--- a/mm/mmap.c
|
||||||
+++ b/mm/mmap.c
|
+++ b/mm/mmap.c
|
||||||
@@ -1927,7 +1927,6 @@ void exit_mmap(struct mm_struct *mm)
|
@@ -1931,7 +1931,6 @@ void exit_mmap(struct mm_struct *mm)
|
||||||
goto destroy;
|
goto destroy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ Suggested-by: David Hildenbrand <david@redhat.com>
|
|||||||
flush_cache_mm(mm);
|
flush_cache_mm(mm);
|
||||||
tlb_gather_mmu_fullmm(&tlb, mm);
|
tlb_gather_mmu_fullmm(&tlb, mm);
|
||||||
/* update_hiwater_rss(mm) here? but nobody should be looking */
|
/* update_hiwater_rss(mm) here? but nobody should be looking */
|
||||||
@@ -2370,7 +2369,6 @@ int relocate_vma_down(struct vm_area_str
|
@@ -2374,7 +2373,6 @@ int relocate_vma_down(struct vm_area_str
|
||||||
vma, new_start, length, false, true))
|
vma, new_start, length, false, true))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1,27 +0,0 @@
|
|||||||
From 6f554b20207f69146c07be3743b115e42f443627 Mon Sep 17 00:00:00 2001
|
|
||||||
From: "Jan Alexander Steffens (heftig)" <heftig@archlinux.org>
|
|
||||||
Date: Fri, 27 Dec 2024 15:08:09 +0100
|
|
||||||
Subject: drm/amdgpu: Add missing statement in resume_phase3
|
|
||||||
|
|
||||||
Fixes: 73dae652dcac776296890da215ee7dec357a1032
|
|
||||||
See: https://gitlab.freedesktop.org/drm/amd/-/issues/3853#note_2714815
|
|
||||||
For: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/101
|
|
||||||
---
|
|
||||||
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
|
||||||
index 29b8346b..cbca5fa7 100644
|
|
||||||
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
|
||||||
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
|
|
||||||
@@ -3723,6 +3723,7 @@ static int amdgpu_device_ip_resume_phase3(struct amdgpu_device *adev)
|
|
||||||
r = adev->ip_blocks[i].version->funcs->resume(adev);
|
|
||||||
if (r)
|
|
||||||
return r;
|
|
||||||
+ adev->ip_blocks[i].status.hw = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.45.2
|
|
||||||
|
|
@ -102,7 +102,7 @@ Contains:
|
|||||||
|
|
||||||
--- a/mm/vmscan.c
|
--- a/mm/vmscan.c
|
||||||
+++ b/mm/vmscan.c
|
+++ b/mm/vmscan.c
|
||||||
@@ -6346,7 +6346,7 @@ retry:
|
@@ -6353,7 +6353,7 @@ retry:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ Contains:
|
|||||||
{
|
{
|
||||||
struct zone *zone;
|
struct zone *zone;
|
||||||
unsigned long pfmemalloc_reserve = 0;
|
unsigned long pfmemalloc_reserve = 0;
|
||||||
@@ -6375,6 +6375,10 @@ static bool allow_direct_reclaim(pg_data
|
@@ -6382,6 +6382,10 @@ static bool allow_direct_reclaim(pg_data
|
||||||
|
|
||||||
wmark_ok = free_pages > pfmemalloc_reserve / 2;
|
wmark_ok = free_pages > pfmemalloc_reserve / 2;
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ Contains:
|
|||||||
/* kswapd must be awake if processes are being throttled */
|
/* kswapd must be awake if processes are being throttled */
|
||||||
if (!wmark_ok && waitqueue_active(&pgdat->kswapd_wait)) {
|
if (!wmark_ok && waitqueue_active(&pgdat->kswapd_wait)) {
|
||||||
if (READ_ONCE(pgdat->kswapd_highest_zoneidx) > ZONE_NORMAL)
|
if (READ_ONCE(pgdat->kswapd_highest_zoneidx) > ZONE_NORMAL)
|
||||||
@@ -6440,7 +6444,7 @@ static bool throttle_direct_reclaim(gfp_
|
@@ -6447,7 +6451,7 @@ static bool throttle_direct_reclaim(gfp_
|
||||||
|
|
||||||
/* Throttle based on the first usable node */
|
/* Throttle based on the first usable node */
|
||||||
pgdat = zone->zone_pgdat;
|
pgdat = zone->zone_pgdat;
|
||||||
@ -131,7 +131,7 @@ Contains:
|
|||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -6462,11 +6466,14 @@ static bool throttle_direct_reclaim(gfp_
|
@@ -6469,11 +6473,14 @@ static bool throttle_direct_reclaim(gfp_
|
||||||
*/
|
*/
|
||||||
if (!(gfp_mask & __GFP_FS))
|
if (!(gfp_mask & __GFP_FS))
|
||||||
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
|
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
|
||||||
@ -148,7 +148,7 @@ Contains:
|
|||||||
|
|
||||||
if (fatal_signal_pending(current))
|
if (fatal_signal_pending(current))
|
||||||
return true;
|
return true;
|
||||||
@@ -6969,14 +6976,14 @@ restart:
|
@@ -6976,14 +6983,14 @@ restart:
|
||||||
* able to safely make forward progress. Wake them
|
* able to safely make forward progress. Wake them
|
||||||
*/
|
*/
|
||||||
if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
|
if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
|
||||||
|
60
debian/patches/series
vendored
60
debian/patches/series
vendored
@ -166,65 +166,6 @@ misc-ntsync7/0018-ntsync-No-longer-depend-on-BROKEN.patch
|
|||||||
|
|
||||||
misc-openwrt/0001-mac80211-ignore-AP-power-level-when-tx-power-type-is.patch
|
misc-openwrt/0001-mac80211-ignore-AP-power-level-when-tx-power-type-is.patch
|
||||||
|
|
||||||
patchset-pf/amd-pstate/0001-cpufreq-amd-pstate-add-quirk-for-Ryzen-3000-series-p.patch
|
|
||||||
patchset-pf/amd-pstate/0002-cpufreq-amd-pstate-Fix-non-kerneldoc-comment.patch
|
|
||||||
patchset-pf/amd-pstate/0003-cpufreq-amd-pstate-Rename-MSR-and-shared-memory-spec.patch
|
|
||||||
patchset-pf/amd-pstate/0004-cpufreq-amd-pstate-Use-amd_pstate_update_min_max_lim.patch
|
|
||||||
patchset-pf/amd-pstate/0005-cpufreq-amd-pstate-Drop-needless-EPP-initialization.patch
|
|
||||||
patchset-pf/amd-pstate/0006-cpufreq-amd-pstate-Remove-the-redundant-verify-funct.patch
|
|
||||||
patchset-pf/amd-pstate/0007-cpufreq-amd-pstate-Set-the-initial-min_freq-to-lowes.patch
|
|
||||||
patchset-pf/amd-pstate/0008-cpufreq-amd-pstate-Call-amd_pstate_register-in-amd_p.patch
|
|
||||||
patchset-pf/amd-pstate/0009-cpufreq-amd-pstate-Call-amd_pstate_set_driver-in-amd.patch
|
|
||||||
patchset-pf/amd-pstate/0010-cpufreq-amd-pstate-Remove-the-switch-case-in-amd_pst.patch
|
|
||||||
patchset-pf/amd-pstate/0011-cpufreq-amd-pstate-Remove-the-redundant-amd_pstate_s.patch
|
|
||||||
patchset-pf/amd-pstate/0012-cpufreq-amd-pstate-ut-Add-fix-for-min-freq-unit-test.patch
|
|
||||||
patchset-pf/amd-pstate/0013-amd-pstate-Switch-to-amd-pstate-by-default-on-some-S.patch
|
|
||||||
patchset-pf/amd-pstate/0014-cpufreq-amd-pstate-Rename-functions-that-enable-CPPC.patch
|
|
||||||
patchset-pf/amd-pstate/0015-cpufreq-amd-pstate-Do-not-attempt-to-clear-MSR_AMD_C.patch
|
|
||||||
patchset-pf/amd-pstate/0016-cpufreq-amd-pstate-Call-cppc_set_epp_perf-in-the-ree.patch
|
|
||||||
patchset-pf/amd-pstate/0017-cpufreq-amd-pstate-Align-offline-flow-of-shared-memo.patch
|
|
||||||
patchset-pf/amd-pstate/0018-x86-cpufeatures-Rename-X86_FEATURE_FAST_CPPC-to-have.patch
|
|
||||||
patchset-pf/amd-pstate/0019-x86-cpufeatures-Add-feature-bits-for-AMD-heterogeneo.patch
|
|
||||||
patchset-pf/amd-pstate/0020-x86-cpu-Enable-SD_ASYM_PACKING-for-PKG-Domain-on-AMD.patch
|
|
||||||
patchset-pf/amd-pstate/0021-x86-cpu-Add-CPU-type-to-struct-cpuinfo_topology.patch
|
|
||||||
patchset-pf/amd-pstate/0022-x86-amd-Use-heterogeneous-core-topology-for-identify.patch
|
|
||||||
patchset-pf/amd-pstate/0023-cpufreq-amd-pstate-Push-adjust_perf-vfunc-init-into-.patch
|
|
||||||
patchset-pf/amd-pstate/0024-cpufreq-amd-pstate-Move-registration-after-static-fu.patch
|
|
||||||
patchset-pf/amd-pstate/0025-cpufreq-amd-pstate-Convert-the-amd_pstate_get-set_ep.patch
|
|
||||||
patchset-pf/amd-pstate/0026-cpufreq-amd-pstate-Move-the-invocation-of-amd_pstate.patch
|
|
||||||
patchset-pf/amd-pstate/0027-cpufreq-amd-pstate-Refactor-amd_pstate_epp_reenable-.patch
|
|
||||||
patchset-pf/amd-pstate/0028-cpufreq-amd-pstate-Remove-the-cppc_state-check-in-of.patch
|
|
||||||
patchset-pf/amd-pstate/0029-cpufreq-amd-pstate-Merge-amd_pstate_epp_cpu_offline-.patch
|
|
||||||
patchset-pf/amd-pstate/0030-cpufreq-amd-pstate-Add-trace-event-for-EPP-perf-upda.patch
|
|
||||||
patchset-pf/amd-pstate/0031-cpufreq-amd-pstate-convert-mutex-use-to-guard.patch
|
|
||||||
patchset-pf/amd-pstate/0032-cpufreq-amd-pstate-Drop-cached-epp_policy-variable.patch
|
|
||||||
patchset-pf/amd-pstate/0033-cpufreq-amd-pstate-Use-FIELD_PREP-and-FIELD_GET-macr.patch
|
|
||||||
patchset-pf/amd-pstate/0034-cpufreq-amd-pstate-Store-the-boost-numerator-as-high.patch
|
|
||||||
patchset-pf/amd-pstate/0035-cpufreq-amd-pstate-Use-boost-numerator-for-upper-bou.patch
|
|
||||||
patchset-pf/amd-pstate/0036-cpufreq-amd-pstate-Only-update-the-cached-value-in-m.patch
|
|
||||||
patchset-pf/amd-pstate/0037-cpufreq-amd-pstate-store-all-values-in-cpudata-struc.patch
|
|
||||||
patchset-pf/amd-pstate/0038-cpufreq-amd-pstate-Change-amd_pstate_update_perf-to-.patch
|
|
||||||
patchset-pf/amd-pstate/0039-cpufreq-amd-pstate-Move-limit-updating-code.patch
|
|
||||||
patchset-pf/amd-pstate/0040-cpufreq-amd-pstate-Cache-EPP-value-and-use-that-ever.patch
|
|
||||||
patchset-pf/amd-pstate/0041-cpufreq-amd-pstate-Always-write-EPP-value-when-updat.patch
|
|
||||||
patchset-pf/amd-pstate/0042-cpufreq-amd-pstate-Check-if-CPPC-request-has-changed.patch
|
|
||||||
patchset-pf/amd-pstate/0043-cpufreq-amd-pstate-Drop-ret-variable-from-amd_pstate.patch
|
|
||||||
patchset-pf/amd-pstate/0044-cpufreq-amd-pstate-Set-different-default-EPP-policy-.patch
|
|
||||||
|
|
||||||
patchset-pf/amd-rapl/0001-perf-x86-rapl-Move-the-pmu-allocation-out-of-CPU-hot.patch
|
|
||||||
patchset-pf/amd-rapl/0002-perf-x86-rapl-Clean-up-cpumask-and-hotplug.patch
|
|
||||||
patchset-pf/amd-rapl/0003-perf-x86-rapl-Remove-the-unused-get_rapl_pmu_cpumask.patch
|
|
||||||
patchset-pf/amd-rapl/0004-x86-topology-Introduce-topology_logical_core_id.patch
|
|
||||||
patchset-pf/amd-rapl/0005-perf-x86-rapl-Remove-the-cpu_to_rapl_pmu-function.patch
|
|
||||||
patchset-pf/amd-rapl/0006-perf-x86-rapl-Rename-rapl_pmu-variables.patch
|
|
||||||
patchset-pf/amd-rapl/0007-perf-x86-rapl-Make-rapl_model-struct-global.patch
|
|
||||||
patchset-pf/amd-rapl/0008-perf-x86-rapl-Add-arguments-to-the-init-and-cleanup-.patch
|
|
||||||
patchset-pf/amd-rapl/0009-perf-x86-rapl-Modify-the-generic-variable-names-to-_.patch
|
|
||||||
patchset-pf/amd-rapl/0010-perf-x86-rapl-Remove-the-global-variable-rapl_msrs.patch
|
|
||||||
patchset-pf/amd-rapl/0011-perf-x86-rapl-Move-the-cntr_mask-to-rapl_pmus-struct.patch
|
|
||||||
patchset-pf/amd-rapl/0012-perf-x86-rapl-Add-core-energy-counter-support-for-AM.patch
|
|
||||||
patchset-pf/amd-rapl/0013-amd-rapl-6.12-fix-clang-built-kernel-not-booting.patch
|
|
||||||
|
|
||||||
patchset-pf/cpuidle/0001-cpuidle-menu-Remove-iowait-influence.patch
|
patchset-pf/cpuidle/0001-cpuidle-menu-Remove-iowait-influence.patch
|
||||||
patchset-pf/cpuidle/0002-cpuidle-Prefer-teo-over-menu-governor.patch
|
patchset-pf/cpuidle/0002-cpuidle-Prefer-teo-over-menu-governor.patch
|
||||||
|
|
||||||
@ -323,4 +264,3 @@ patchset-pf/fixes/0002-drivers-firmware-skip-simpledrm-if-nvidia-drm.modese.patc
|
|||||||
patchset-pf/fixes/0003-USB-core-Disable-LPM-only-for-non-suspended-ports.patch
|
patchset-pf/fixes/0003-USB-core-Disable-LPM-only-for-non-suspended-ports.patch
|
||||||
|
|
||||||
patchset-zen/fixes/0001-futex-improve-user-space-accesses.patch
|
patchset-zen/fixes/0001-futex-improve-user-space-accesses.patch
|
||||||
patchset-zen/fixes/0002-drm-amdgpu-Add-missing-statement-in-resume_phase3.patch
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user