From: "Gautham R. Shenoy" <gautham.shenoy@amd.com>
To: Mario Limonciello <mario.limonciello@amd.com>,
"Rafael J . Wysocki" <rafael@kernel.org>,
Viresh Kumar <viresh.kumar@linaro.org>,
K Prateek Nayak <kprateek.nayak@amd.com>
Cc: <linux-kernel@vger.kernel.org>, <linux-pm@vger.kernel.org>,
"Gautham R. Shenoy" <gautham.shenoy@amd.com>,
Mario Limonciello <superm1@kernel.org>
Subject: [PATCH v4 03/12] amd-pstate: Make certain freq_attrs conditionally visible
Date: Thu, 26 Mar 2026 17:17:47 +0530 [thread overview]
Message-ID: <20260326114756.20374-4-gautham.shenoy@amd.com> (raw)
In-Reply-To: <20260326114756.20374-1-gautham.shenoy@amd.com>
Certain amd_pstate freq_attrs such as amd_pstate_hw_prefcore and
amd_pstate_prefcore_ranking are enabled even when preferred core is
not supported on the platform.
Similarly there are common freq_attrs between the amd-pstate and the
amd-pstate-epp drivers (eg: amd_pstate_max_freq,
amd_pstate_lowest_nonlinear_freq, etc.) but are duplicated in two
different freq_attr structs.
Unify all the attributes in a single place and associate each of them
with a visibility function that determines whether the attribute
should be visible based on the underlying platform support and the
current amd_pstate mode.
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Gautham R. Shenoy <gautham.shenoy@amd.com>
---
drivers/cpufreq/amd-pstate.c | 124 ++++++++++++++++++++++++++---------
1 file changed, 93 insertions(+), 31 deletions(-)
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 24cdeffbcd40..4de2037a414c 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1220,12 +1220,87 @@ static ssize_t show_energy_performance_preference(
return sysfs_emit(buf, "%s\n", energy_perf_strings[preference]);
}
+cpufreq_freq_attr_ro(amd_pstate_max_freq);
+cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
+
+cpufreq_freq_attr_ro(amd_pstate_highest_perf);
+cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
+cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
+cpufreq_freq_attr_rw(energy_performance_preference);
+cpufreq_freq_attr_ro(energy_performance_available_preferences);
+
+struct freq_attr_visibility {
+ struct freq_attr *attr;
+ bool (*visibility_fn)(void);
+};
+
+/* For attributes which are always visible */
+static bool always_visible(void)
+{
+ return true;
+}
+
+/* Determines whether prefcore related attributes should be visible */
+static bool prefcore_visibility(void)
+{
+ return amd_pstate_prefcore;
+}
+
+/* Determines whether energy performance preference should be visible */
+static bool epp_visibility(void)
+{
+ return cppc_state == AMD_PSTATE_ACTIVE;
+}
+
+static struct freq_attr_visibility amd_pstate_attr_visibility[] = {
+ {&amd_pstate_max_freq, always_visible},
+ {&amd_pstate_lowest_nonlinear_freq, always_visible},
+ {&amd_pstate_highest_perf, always_visible},
+ {&amd_pstate_prefcore_ranking, prefcore_visibility},
+ {&amd_pstate_hw_prefcore, prefcore_visibility},
+ {&energy_performance_preference, epp_visibility},
+ {&energy_performance_available_preferences, epp_visibility},
+};
+
+static struct freq_attr **get_freq_attrs(void)
+{
+ bool attr_visible[ARRAY_SIZE(amd_pstate_attr_visibility)];
+ struct freq_attr **attrs;
+ int i, j, count;
+
+ for (i = 0, count = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) {
+ struct freq_attr_visibility *v = &amd_pstate_attr_visibility[i];
+
+ attr_visible[i] = v->visibility_fn();
+ if (attr_visible[i])
+ count++;
+ }
+
+ /* amd_pstate_{max_freq, lowest_nonlinear_freq, highest_perf} should always be visible */
+ BUG_ON(!count);
+
+ attrs = kcalloc(count + 1, sizeof(struct freq_attr *), GFP_KERNEL);
+ if (!attrs)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(amd_pstate_attr_visibility); i++) {
+ if (!attr_visible[i])
+ continue;
+
+ attrs[j++] = amd_pstate_attr_visibility[i].attr;
+ }
+
+ return attrs;
+}
+
static void amd_pstate_driver_cleanup(void)
{
if (amd_pstate_prefcore)
sched_clear_itmt_support();
cppc_state = AMD_PSTATE_DISABLE;
+ kfree(current_pstate_driver->attr);
+ current_pstate_driver->attr = NULL;
current_pstate_driver = NULL;
}
@@ -1250,6 +1325,7 @@ static int amd_pstate_set_driver(int mode_idx)
static int amd_pstate_register_driver(int mode)
{
+ struct freq_attr **attr = NULL;
int ret;
ret = amd_pstate_set_driver(mode);
@@ -1258,6 +1334,22 @@ static int amd_pstate_register_driver(int mode)
cppc_state = mode;
+ /*
+ * Note: It is important to compute the attrs _after_
+ * re-initializing the cppc_state. Some attributes become
+ * visible only when cppc_state is AMD_PSTATE_ACTIVE.
+ */
+ attr = get_freq_attrs();
+ if (IS_ERR(attr)) {
+ ret = (int) PTR_ERR(attr);
+ pr_err("Couldn't compute freq_attrs for current mode %s [%d]\n",
+ amd_pstate_get_mode_string(cppc_state), ret);
+ amd_pstate_driver_cleanup();
+ return ret;
+ }
+
+ current_pstate_driver->attr = attr;
+
/* at least one CPU supports CPB */
current_pstate_driver->boost_enabled = cpu_feature_enabled(X86_FEATURE_CPB);
@@ -1399,37 +1491,9 @@ static ssize_t prefcore_show(struct device *dev,
return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore));
}
-cpufreq_freq_attr_ro(amd_pstate_max_freq);
-cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
-
-cpufreq_freq_attr_ro(amd_pstate_highest_perf);
-cpufreq_freq_attr_ro(amd_pstate_prefcore_ranking);
-cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
-cpufreq_freq_attr_rw(energy_performance_preference);
-cpufreq_freq_attr_ro(energy_performance_available_preferences);
static DEVICE_ATTR_RW(status);
static DEVICE_ATTR_RO(prefcore);
-static struct freq_attr *amd_pstate_attr[] = {
- &amd_pstate_max_freq,
- &amd_pstate_lowest_nonlinear_freq,
- &amd_pstate_highest_perf,
- &amd_pstate_prefcore_ranking,
- &amd_pstate_hw_prefcore,
- NULL,
-};
-
-static struct freq_attr *amd_pstate_epp_attr[] = {
- &amd_pstate_max_freq,
- &amd_pstate_lowest_nonlinear_freq,
- &amd_pstate_highest_perf,
- &amd_pstate_prefcore_ranking,
- &amd_pstate_hw_prefcore,
- &energy_performance_preference,
- &energy_performance_available_preferences,
- NULL,
-};
-
static struct attribute *pstate_global_attributes[] = {
&dev_attr_status.attr,
&dev_attr_prefcore.attr,
@@ -1696,7 +1760,6 @@ static struct cpufreq_driver amd_pstate_driver = {
.set_boost = amd_pstate_set_boost,
.update_limits = amd_pstate_update_limits,
.name = "amd-pstate",
- .attr = amd_pstate_attr,
};
static struct cpufreq_driver amd_pstate_epp_driver = {
@@ -1712,7 +1775,6 @@ static struct cpufreq_driver amd_pstate_epp_driver = {
.update_limits = amd_pstate_update_limits,
.set_boost = amd_pstate_set_boost,
.name = "amd-pstate-epp",
- .attr = amd_pstate_epp_attr,
};
/*
@@ -1858,7 +1920,7 @@ static int __init amd_pstate_init(void)
return ret;
global_attr_free:
- cpufreq_unregister_driver(current_pstate_driver);
+ amd_pstate_unregister_driver(0);
return ret;
}
device_initcall(amd_pstate_init);
--
2.34.1
next prev parent reply other threads:[~2026-03-26 11:48 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-26 11:47 [PATCH v4 00/12] amd-pstate: Introduce AMD CPPC Performance Priority Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 01/12] amd-pstate: Fix memory leak in amd_pstate_epp_cpu_init() Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 02/12] amd-pstate: Update cppc_req_cached in fast_switch case Gautham R. Shenoy
2026-03-26 11:47 ` Gautham R. Shenoy [this message]
2026-03-26 11:47 ` [PATCH v4 04/12] x86/cpufeatures: Add AMD CPPC Performance Priority feature Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 05/12] amd-pstate: Add support for CPPC_REQ2 and FLOOR_PERF Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 06/12] amd-pstate: Add sysfs support for floor_freq and floor_count Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 07/12] amd-pstate: Introduce a tracepoint trace_amd_pstate_cppc_req2() Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 08/12] amd-pstate-ut: Add module parameter to select testcases Gautham R. Shenoy
2026-03-26 18:46 ` Mario Limonciello
2026-03-26 11:47 ` [PATCH v4 09/12] amd-pstate-ut: Add a testcase to validate the visibility of driver attributes Gautham R. Shenoy
2026-03-26 19:34 ` Mario Limonciello
2026-03-26 11:47 ` [PATCH v4 10/12] Documentation/amd-pstate: List amd_pstate_hw_prefcore sysfs file Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 11/12] Documentation/amd-pstate: List amd_pstate_prefcore_ranking " Gautham R. Shenoy
2026-03-26 11:47 ` [PATCH v4 12/12] Documentation/amd-pstate: Add documentation for amd_pstate_floor_{freq,count} Gautham R. Shenoy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260326114756.20374-4-gautham.shenoy@amd.com \
--to=gautham.shenoy@amd.com \
--cc=kprateek.nayak@amd.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=rafael@kernel.org \
--cc=superm1@kernel.org \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox