* [PATCH v4 0/9] power: centralize lcore ID validation
@ 2026-06-15 7:30 Huisong Li
2026-06-15 7:30 ` [PATCH v4 1/9] power: add a common macro to verify lcore ID Huisong Li
` (10 more replies)
0 siblings, 11 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="yes", Size: 3156 bytes --]
This series centralizes the lcore ID verification in the power cpufreq
framework, replacing the per-driver range checks with a common validation.
Background
----------
Currently, various cpufreq drivers implement their own lcore ID checks,
which are limited to simple range validation against RTE_MAX_LCORE and
involve significant code duplication across 12+ functions per driver.
The checks are duplicated across all drivers — any change requires
updating 5+ drivers identically. Moreover, these checks do not verify
whether the lcore is actually managed by the application. So it is better
to verify lcore ID in cpufreq core.
For cpufreq-related APIs, although service cores do not typically invoke
these APIs, they may operate in polling modes where power management is
required. To maintain compatibility with applications using service cores,
the validation logic now explicitly accepts both ROLE_RTE and ROLE_SERVICE.
The usage of power QoS APIs are similar to that of cpufreq. They also can
accepts ROLE_RTE and ROLE_SERVICE.
For PMD power management APIs, the lcore must be ROLE_RTE because these
are used together with the data plane of ethdev PMD. Hence,
rte_lcore_is_enabled() is used for validation.
Key Changes:
------------
Patch 1: Adds a common macro (RTE_POWER_VALID_LCOREID_OR_ERR_RET)
that accepts both roles.
Patch 2: Adds the validation to the cpufreq framework layer.
Patches 3-7: Remove the now-redundant per-driver RTE_MAX_LCORE checks.
Patch 8: Update power QoS to use the new validation, allowing
service cores to configure QoS parameters.
Patch 9: Add lcore validation to PMD management functions.
Changes:
--------
v4: remove the patch that add the helper function rte_lcore_is_eal_managed.
v3:
- update release note.
- add __rte_experimental for new helper function.
- restructure this patch set to facilitate review.
v2:
- allow the service cores to set power API.
----
Huisong Li (9):
power: add a common macro to verify lcore ID
power/cpufreq: add the lcore ID verification to framework
power/acpi: remove redundant lcore ID checks
power/amd_pstate: remove redundant lcore ID checks
power/cppc: remove redundant lcore ID checks
power/intel_pstate: remove redundant lcore ID checks
power/kvm_vm: remove redundant lcore ID checks
power: allow the service core to config power QoS
power: add lcore ID check for PMD mgmt
doc/guides/rel_notes/release_26_07.rst | 7 ++
drivers/power/acpi/acpi_cpufreq.c | 65 -------------------
drivers/power/amd_pstate/amd_pstate_cpufreq.c | 65 -------------------
drivers/power/cppc/cppc_cpufreq.c | 65 -------------------
.../power/intel_pstate/intel_pstate_cpufreq.c | 65 -------------------
drivers/power/kvm_vm/guest_channel.c | 22 -------
drivers/power/kvm_vm/kvm_vm.c | 10 ---
lib/power/power_common.h | 8 +++
lib/power/rte_power_cpufreq.c | 13 ++++
lib/power/rte_power_pmd_mgmt.c | 21 +++---
lib/power/rte_power_qos.c | 10 +--
11 files changed, 41 insertions(+), 310 deletions(-)
--
2.33.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v4 1/9] power: add a common macro to verify lcore ID
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 2/9] power/cpufreq: add the lcore ID verification to framework Huisong Li
` (9 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
There are many places to verify lcore ID in power. It is necessary
to add a common macro in power core.
According to the applicattion in l3fwd-power, the lcore must be at
least within the RTE_MAX_LCORE range and be a core of the ROLE_RTE
role. But the service on the ROLE_SERVICE core also can use and
require power management feature.
So this common macro restricts that the lcore ID must be ROLE_RTE
and ROLE_SERVICE.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
doc/guides/rel_notes/release_26_07.rst | 4 ++++
lib/power/power_common.h | 8 ++++++++
2 files changed, 12 insertions(+)
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index 5d7aa8d1bf..aeabb908ec 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -155,6 +155,10 @@ New Features
Added AGENTS.md file for AI review
and supporting scripts to review patches and documentation.
+* **Added a common macro to verify lcore ID in power core.**
+
+ Added the ``RTE_POWER_VALID_LCOREID_OR_ERR_RET`` macro to verify lcore ID
+ in power core.
Removed Items
-------------
diff --git a/lib/power/power_common.h b/lib/power/power_common.h
index e2d5b68a17..370c5246c6 100644
--- a/lib/power/power_common.h
+++ b/lib/power/power_common.h
@@ -25,6 +25,14 @@ extern int rte_power_logtype;
#define POWER_CONVERT_TO_DECIMAL 10
+#define RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, retval) do { \
+ if (rte_eal_lcore_role(lcore_id) != ROLE_RTE && \
+ rte_eal_lcore_role(lcore_id) != ROLE_SERVICE) { \
+ POWER_LOG(ERR, "lcore id %u is invalid", lcore_id); \
+ return retval; \
+ } \
+} while (0)
+
/* check if scaling driver matches one we want */
__rte_internal
int cpufreq_check_scaling_driver(const char *driver);
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 2/9] power/cpufreq: add the lcore ID verification to framework
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
2026-06-15 7:30 ` [PATCH v4 1/9] power: add a common macro to verify lcore ID Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 3/9] power/acpi: remove redundant lcore ID checks Huisong Li
` (8 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
Currently, many cpufreq drivers verify the lcore ID in their
own driver and just restrict it to the RTE_MAX_LCORE range.
Actually, the lcore ID verification is common for each cpufreq
driver. It is better to add this verification to framework.
In addition, the lcore ID for cpufreq library is used by the
application, which is missing in cpufreq library or driver.
So use RTE_POWER_VALID_LCOREID_OR_ERR_RET to verify it in
cpufreq framework.
Please note the lcore ID for cpufreq library must be ROLE_RTE
or ROLE_SERVICE after this patch.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
lib/power/rte_power_cpufreq.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/lib/power/rte_power_cpufreq.c b/lib/power/rte_power_cpufreq.c
index f63e976dc2..8394cbc77f 100644
--- a/lib/power/rte_power_cpufreq.c
+++ b/lib/power/rte_power_cpufreq.c
@@ -116,6 +116,7 @@ rte_power_init(unsigned int lcore_id)
struct rte_power_cpufreq_ops *ops;
uint8_t env;
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
if (global_default_env != PM_ENV_NOT_SET)
return global_cpufreq_ops->init(lcore_id);
@@ -147,6 +148,7 @@ RTE_EXPORT_SYMBOL(rte_power_exit)
int
rte_power_exit(unsigned int lcore_id)
{
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
if (global_default_env != PM_ENV_NOT_SET)
return global_cpufreq_ops->exit(lcore_id);
@@ -161,6 +163,7 @@ uint32_t
rte_power_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t n)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, 0);
return global_cpufreq_ops->get_avail_freqs(lcore_id, freqs, n);
}
@@ -169,6 +172,7 @@ uint32_t
rte_power_get_freq(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, RTE_POWER_INVALID_FREQ_INDEX);
return global_cpufreq_ops->get_freq(lcore_id);
}
@@ -177,6 +181,7 @@ uint32_t
rte_power_set_freq(unsigned int lcore_id, uint32_t index)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->set_freq(lcore_id, index);
}
@@ -185,6 +190,7 @@ int
rte_power_freq_up(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->freq_up(lcore_id);
}
@@ -193,6 +199,7 @@ int
rte_power_freq_down(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->freq_down(lcore_id);
}
@@ -201,6 +208,7 @@ int
rte_power_freq_max(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->freq_max(lcore_id);
}
@@ -209,6 +217,7 @@ int
rte_power_freq_min(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->freq_min(lcore_id);
}
@@ -217,6 +226,7 @@ int
rte_power_turbo_status(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->turbo_status(lcore_id);
}
@@ -225,6 +235,7 @@ int
rte_power_freq_enable_turbo(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->enable_turbo(lcore_id);
}
@@ -233,6 +244,7 @@ int
rte_power_freq_disable_turbo(unsigned int lcore_id)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->disable_turbo(lcore_id);
}
@@ -242,5 +254,6 @@ rte_power_get_capabilities(unsigned int lcore_id,
struct rte_power_core_capabilities *caps)
{
RTE_ASSERT(global_cpufreq_ops != NULL);
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -1);
return global_cpufreq_ops->get_caps(lcore_id, caps);
}
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 3/9] power/acpi: remove redundant lcore ID checks
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
2026-06-15 7:30 ` [PATCH v4 1/9] power: add a common macro to verify lcore ID Huisong Li
2026-06-15 7:30 ` [PATCH v4 2/9] power/cpufreq: add the lcore ID verification to framework Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 4/9] power/amd_pstate: " Huisong Li
` (7 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
Now that the cpufreq framework validates the lcore ID using
RTE_POWER_VALID_LCOREID_OR_ERR_RET() before dispatching to any driver,
each individual cpufreq driver no longer needs its own range
check against RTE_MAX_LCORE.
Remove the duplicated lcore ID checks from the acpi cpufreq
driver ops.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
drivers/power/acpi/acpi_cpufreq.c | 65 -------------------------------
1 file changed, 65 deletions(-)
diff --git a/drivers/power/acpi/acpi_cpufreq.c b/drivers/power/acpi/acpi_cpufreq.c
index 875c66336d..af85a8cdec 100644
--- a/drivers/power/acpi/acpi_cpufreq.c
+++ b/drivers/power/acpi/acpi_cpufreq.c
@@ -234,12 +234,6 @@ power_acpi_cpufreq_init(unsigned int lcore_id)
return -1;
}
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
exp_state = POWER_IDLE;
/* The power in use state works as a guard variable between
@@ -311,11 +305,6 @@ power_acpi_cpufreq_exit(unsigned int lcore_id)
struct acpi_power_info *pi;
uint32_t exp_state;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
pi = &lcore_power_info[lcore_id];
exp_state = POWER_USED;
/* The power in use state works as a guard variable between
@@ -365,11 +354,6 @@ power_acpi_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return 0;
- }
-
if (freqs == NULL) {
POWER_LOG(ERR, "NULL buffer supplied");
return 0;
@@ -388,22 +372,12 @@ power_acpi_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
uint32_t
power_acpi_cpufreq_get_freq(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return RTE_POWER_INVALID_FREQ_INDEX;
- }
-
return lcore_power_info[lcore_id].curr_idx;
}
int
power_acpi_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
return set_freq_internal(&(lcore_power_info[lcore_id]), index);
}
@@ -412,11 +386,6 @@ power_acpi_cpufreq_freq_down(unsigned int lcore_id)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx + 1 == pi->nb_freqs)
return 0;
@@ -430,11 +399,6 @@ power_acpi_cpufreq_freq_up(unsigned int lcore_id)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx == 0 ||
(pi->curr_idx == 1 && pi->turbo_available && !pi->turbo_enable))
@@ -447,11 +411,6 @@ power_acpi_cpufreq_freq_up(unsigned int lcore_id)
int
power_acpi_cpufreq_freq_max(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
/* Frequencies in the array are from high to low. */
if (lcore_power_info[lcore_id].turbo_available) {
if (lcore_power_info[lcore_id].turbo_enable)
@@ -471,11 +430,6 @@ power_acpi_cpufreq_freq_min(unsigned int lcore_id)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
/* Frequencies in the array are from high to low. */
@@ -488,11 +442,6 @@ power_acpi_turbo_status(unsigned int lcore_id)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
return pi->turbo_enable;
@@ -504,11 +453,6 @@ power_acpi_enable_turbo(unsigned int lcore_id)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->turbo_available)
@@ -537,11 +481,6 @@ power_acpi_disable_turbo(unsigned int lcore_id)
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
pi->turbo_enable = 0;
@@ -564,10 +503,6 @@ int power_acpi_get_capabilities(unsigned int lcore_id,
{
struct acpi_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
if (caps == NULL) {
POWER_LOG(ERR, "Invalid argument");
return -1;
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 4/9] power/amd_pstate: remove redundant lcore ID checks
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (2 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 3/9] power/acpi: remove redundant lcore ID checks Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 5/9] power/cppc: " Huisong Li
` (6 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
Now that the cpufreq framework validates the lcore ID using
RTE_POWER_VALID_LCOREID_OR_ERR_RET() before dispatching to any driver,
each individual cpufreq driver no longer needs its own range
check against RTE_MAX_LCORE.
Remove the duplicated lcore ID checks from the amd_pstate
cpufreq driver ops.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
drivers/power/amd_pstate/amd_pstate_cpufreq.c | 65 -------------------
1 file changed, 65 deletions(-)
diff --git a/drivers/power/amd_pstate/amd_pstate_cpufreq.c b/drivers/power/amd_pstate/amd_pstate_cpufreq.c
index bc67981d71..af9c1309f3 100644
--- a/drivers/power/amd_pstate/amd_pstate_cpufreq.c
+++ b/drivers/power/amd_pstate/amd_pstate_cpufreq.c
@@ -351,12 +351,6 @@ power_amd_pstate_cpufreq_init(unsigned int lcore_id)
return -1;
}
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
exp_state = POWER_IDLE;
/* The power in use state works as a guard variable between
@@ -434,11 +428,6 @@ power_amd_pstate_cpufreq_exit(unsigned int lcore_id)
struct amd_pstate_power_info *pi;
uint32_t exp_state;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
pi = &lcore_power_info[lcore_id];
exp_state = POWER_USED;
/* The power in use state works as a guard variable between
@@ -484,11 +473,6 @@ power_amd_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return 0;
- }
-
if (freqs == NULL) {
POWER_LOG(ERR, "NULL buffer supplied");
return 0;
@@ -507,22 +491,12 @@ power_amd_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t
uint32_t
power_amd_pstate_cpufreq_get_freq(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return RTE_POWER_INVALID_FREQ_INDEX;
- }
-
return lcore_power_info[lcore_id].curr_idx;
}
int
power_amd_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
return set_freq_internal(&(lcore_power_info[lcore_id]), index);
}
@@ -531,11 +505,6 @@ power_amd_pstate_cpufreq_freq_down(unsigned int lcore_id)
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx + 1 == pi->nb_freqs)
return 0;
@@ -549,11 +518,6 @@ power_amd_pstate_cpufreq_freq_up(unsigned int lcore_id)
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx == 0 || (pi->curr_idx == pi->nom_idx &&
pi->turbo_available && !pi->turbo_enable))
@@ -566,11 +530,6 @@ power_amd_pstate_cpufreq_freq_up(unsigned int lcore_id)
int
power_amd_pstate_cpufreq_freq_max(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
/* Frequencies in the array are from high to low. */
if (lcore_power_info[lcore_id].turbo_available) {
if (lcore_power_info[lcore_id].turbo_enable)
@@ -591,11 +550,6 @@ power_amd_pstate_cpufreq_freq_min(unsigned int lcore_id)
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
/* Frequencies in the array are from high to low. */
@@ -607,11 +561,6 @@ power_amd_pstate_turbo_status(unsigned int lcore_id)
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
return pi->turbo_enable;
@@ -622,11 +571,6 @@ power_amd_pstate_enable_turbo(unsigned int lcore_id)
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->turbo_available)
@@ -658,11 +602,6 @@ power_amd_pstate_disable_turbo(unsigned int lcore_id)
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
pi->turbo_enable = 0;
@@ -686,10 +625,6 @@ power_amd_pstate_get_capabilities(unsigned int lcore_id,
{
struct amd_pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
if (caps == NULL) {
POWER_LOG(ERR, "Invalid argument");
return -1;
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 5/9] power/cppc: remove redundant lcore ID checks
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (3 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 4/9] power/amd_pstate: " Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 6/9] power/intel_pstate: " Huisong Li
` (5 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
Now that the cpufreq framework validates the lcore ID using
RTE_POWER_VALID_LCOREID_OR_ERR_RET() before dispatching to any driver,
each individual cpufreq driver no longer needs its own range
check against RTE_MAX_LCORE.
Remove the duplicated lcore ID checks from the cppc cpufreq
driver ops.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
drivers/power/cppc/cppc_cpufreq.c | 65 -------------------------------
1 file changed, 65 deletions(-)
diff --git a/drivers/power/cppc/cppc_cpufreq.c b/drivers/power/cppc/cppc_cpufreq.c
index 9ae25bad27..aed44c1212 100644
--- a/drivers/power/cppc/cppc_cpufreq.c
+++ b/drivers/power/cppc/cppc_cpufreq.c
@@ -337,12 +337,6 @@ power_cppc_cpufreq_init(unsigned int lcore_id)
return -1;
}
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
exp_state = POWER_IDLE;
/* The power in use state works as a guard variable between
@@ -420,11 +414,6 @@ power_cppc_cpufreq_exit(unsigned int lcore_id)
struct cppc_power_info *pi;
uint32_t exp_state;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
pi = &lcore_power_info[lcore_id];
exp_state = POWER_USED;
/* The power in use state works as a guard variable between
@@ -470,11 +459,6 @@ power_cppc_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return 0;
- }
-
if (freqs == NULL) {
POWER_LOG(ERR, "NULL buffer supplied");
return 0;
@@ -493,22 +477,12 @@ power_cppc_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
uint32_t
power_cppc_cpufreq_get_freq(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return RTE_POWER_INVALID_FREQ_INDEX;
- }
-
return lcore_power_info[lcore_id].curr_idx;
}
int
power_cppc_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
return set_freq_internal(&(lcore_power_info[lcore_id]), index);
}
@@ -517,11 +491,6 @@ power_cppc_cpufreq_freq_down(unsigned int lcore_id)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx + 1 == pi->nb_freqs)
return 0;
@@ -535,11 +504,6 @@ power_cppc_cpufreq_freq_up(unsigned int lcore_id)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx == 0 || (pi->curr_idx == 1 &&
pi->turbo_available && !pi->turbo_enable))
@@ -552,11 +516,6 @@ power_cppc_cpufreq_freq_up(unsigned int lcore_id)
int
power_cppc_cpufreq_freq_max(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
/* Frequencies in the array are from high to low. */
if (lcore_power_info[lcore_id].turbo_available) {
if (lcore_power_info[lcore_id].turbo_enable)
@@ -576,11 +535,6 @@ power_cppc_cpufreq_freq_min(unsigned int lcore_id)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
/* Frequencies in the array are from high to low. */
@@ -592,11 +546,6 @@ power_cppc_turbo_status(unsigned int lcore_id)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
return pi->turbo_enable;
@@ -607,11 +556,6 @@ power_cppc_enable_turbo(unsigned int lcore_id)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->turbo_available)
@@ -643,11 +587,6 @@ power_cppc_disable_turbo(unsigned int lcore_id)
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
pi->turbo_enable = 0;
@@ -671,10 +610,6 @@ power_cppc_get_capabilities(unsigned int lcore_id,
{
struct cppc_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
if (caps == NULL) {
POWER_LOG(ERR, "Invalid argument");
return -1;
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 6/9] power/intel_pstate: remove redundant lcore ID checks
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (4 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 5/9] power/cppc: " Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 7/9] power/kvm_vm: " Huisong Li
` (4 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
Now that the cpufreq framework validates the lcore ID using
RTE_POWER_VALID_LCOREID_OR_ERR_RET() before dispatching to any driver,
each individual cpufreq driver no longer needs its own range
check against RTE_MAX_LCORE.
Remove the duplicated lcore ID checks from the intel_pstate
cpufreq driver ops.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
.../power/intel_pstate/intel_pstate_cpufreq.c | 65 -------------------
1 file changed, 65 deletions(-)
diff --git a/drivers/power/intel_pstate/intel_pstate_cpufreq.c b/drivers/power/intel_pstate/intel_pstate_cpufreq.c
index 22a1b4465a..dfbb5635a1 100644
--- a/drivers/power/intel_pstate/intel_pstate_cpufreq.c
+++ b/drivers/power/intel_pstate/intel_pstate_cpufreq.c
@@ -540,12 +540,6 @@ power_pstate_cpufreq_init(unsigned int lcore_id)
return -1;
}
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceed %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
exp_state = POWER_IDLE;
/* The power in use state works as a guard variable between
@@ -622,11 +616,6 @@ power_pstate_cpufreq_exit(unsigned int lcore_id)
struct pstate_power_info *pi;
uint32_t exp_state;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Lcore id %u can not exceeds %u",
- lcore_id, RTE_MAX_LCORE - 1U);
- return -1;
- }
pi = &lcore_power_info[lcore_id];
exp_state = POWER_USED;
@@ -680,11 +669,6 @@ power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return 0;
- }
-
if (freqs == NULL) {
POWER_LOG(ERR, "NULL buffer supplied");
return 0;
@@ -703,11 +687,6 @@ power_pstate_cpufreq_freqs(unsigned int lcore_id, uint32_t *freqs, uint32_t num)
uint32_t
power_pstate_cpufreq_get_freq(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return RTE_POWER_INVALID_FREQ_INDEX;
- }
-
return lcore_power_info[lcore_id].curr_idx;
}
@@ -715,11 +694,6 @@ power_pstate_cpufreq_get_freq(unsigned int lcore_id)
int
power_pstate_cpufreq_set_freq(unsigned int lcore_id, uint32_t index)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
return set_freq_internal(&(lcore_power_info[lcore_id]), index);
}
@@ -728,11 +702,6 @@ power_pstate_cpufreq_freq_up(unsigned int lcore_id)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx == 0 ||
(pi->curr_idx == 1 && pi->turbo_available && !pi->turbo_enable))
@@ -747,11 +716,6 @@ power_pstate_cpufreq_freq_down(unsigned int lcore_id)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->curr_idx + 1 == pi->nb_freqs)
return 0;
@@ -763,11 +727,6 @@ power_pstate_cpufreq_freq_down(unsigned int lcore_id)
int
power_pstate_cpufreq_freq_max(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
/* Frequencies in the array are from high to low. */
if (lcore_power_info[lcore_id].turbo_available) {
if (lcore_power_info[lcore_id].turbo_enable)
@@ -788,11 +747,6 @@ power_pstate_cpufreq_freq_min(unsigned int lcore_id)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
/* Frequencies in the array are from high to low. */
@@ -805,11 +759,6 @@ power_pstate_turbo_status(unsigned int lcore_id)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
return pi->turbo_enable;
@@ -820,11 +769,6 @@ power_pstate_enable_turbo(unsigned int lcore_id)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
if (pi->turbo_available)
@@ -846,11 +790,6 @@ power_pstate_disable_turbo(unsigned int lcore_id)
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
-
pi = &lcore_power_info[lcore_id];
pi->turbo_enable = 0;
@@ -874,10 +813,6 @@ int power_pstate_get_capabilities(unsigned int lcore_id,
{
struct pstate_power_info *pi;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID");
- return -1;
- }
if (caps == NULL) {
POWER_LOG(ERR, "Invalid argument");
return -1;
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 7/9] power/kvm_vm: remove redundant lcore ID checks
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (5 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 6/9] power/intel_pstate: " Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 8/9] power: allow the service core to config power QoS Huisong Li
` (3 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
Now that the cpufreq framework validates the lcore ID using
RTE_POWER_VALID_LCOREID_OR_ERR_RET() before dispatching to any driver,
each individual cpufreq driver no longer needs its own range
check against RTE_MAX_LCORE.
Remove the duplicated lcore ID checks from the kvm_vm cpufreq
driver and its guest_channel helper.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
drivers/power/kvm_vm/guest_channel.c | 22 ----------------------
drivers/power/kvm_vm/kvm_vm.c | 10 ----------
2 files changed, 32 deletions(-)
diff --git a/drivers/power/kvm_vm/guest_channel.c b/drivers/power/kvm_vm/guest_channel.c
index 42bfcedb56..dc8fe05fef 100644
--- a/drivers/power/kvm_vm/guest_channel.c
+++ b/drivers/power/kvm_vm/guest_channel.c
@@ -61,11 +61,6 @@ guest_channel_host_connect(const char *path, unsigned int lcore_id)
char fd_path[PATH_MAX];
int fd = -1;
- if (lcore_id >= RTE_MAX_LCORE) {
- GUEST_CHANNEL_LOG(ERR, "Channel(%u) is out of range 0...%d",
- lcore_id, RTE_MAX_LCORE-1);
- return -1;
- }
/* check if path is already open */
if (global_fds[lcore_id] != -1) {
GUEST_CHANNEL_LOG(ERR, "Channel(%u) is already open with fd %d",
@@ -127,12 +122,6 @@ guest_channel_send_msg(struct rte_power_channel_packet *pkt,
int ret, buffer_len = sizeof(*pkt);
void *buffer = pkt;
- if (lcore_id >= RTE_MAX_LCORE) {
- GUEST_CHANNEL_LOG(ERR, "Channel(%u) is out of range 0...%d",
- lcore_id, RTE_MAX_LCORE-1);
- return -1;
- }
-
if (global_fds[lcore_id] < 0) {
GUEST_CHANNEL_LOG(ERR, "Channel is not connected");
return -1;
@@ -169,12 +158,6 @@ int power_guest_channel_read_msg(void *pkt,
if (pkt_len == 0 || pkt == NULL)
return -1;
- if (lcore_id >= RTE_MAX_LCORE) {
- GUEST_CHANNEL_LOG(ERR, "Channel(%u) is out of range 0...%d",
- lcore_id, RTE_MAX_LCORE-1);
- return -1;
- }
-
if (global_fds[lcore_id] < 0) {
GUEST_CHANNEL_LOG(ERR, "Channel is not connected");
return -1;
@@ -225,11 +208,6 @@ int rte_power_guest_channel_receive_msg(void *pkt,
void
guest_channel_host_disconnect(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- GUEST_CHANNEL_LOG(ERR, "Channel(%u) is out of range 0...%d",
- lcore_id, RTE_MAX_LCORE-1);
- return;
- }
if (global_fds[lcore_id] < 0)
return;
close(global_fds[lcore_id]);
diff --git a/drivers/power/kvm_vm/kvm_vm.c b/drivers/power/kvm_vm/kvm_vm.c
index 5754a441cd..e8b454bb55 100644
--- a/drivers/power/kvm_vm/kvm_vm.c
+++ b/drivers/power/kvm_vm/kvm_vm.c
@@ -24,11 +24,6 @@ power_kvm_vm_check_supported(void)
int
power_kvm_vm_init(unsigned int lcore_id)
{
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Core(%u) is out of range 0...%d",
- lcore_id, RTE_MAX_LCORE-1);
- return -1;
- }
pkt[lcore_id].command = RTE_POWER_CPU_POWER;
pkt[lcore_id].resource_id = lcore_id;
return guest_channel_host_connect(FD_PATH, lcore_id);
@@ -73,11 +68,6 @@ send_msg(unsigned int lcore_id, uint32_t scale_direction)
{
int ret;
- if (lcore_id >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Core(%u) is out of range 0...%d",
- lcore_id, RTE_MAX_LCORE-1);
- return -1;
- }
pkt[lcore_id].unit = scale_direction;
ret = guest_channel_send_msg(&pkt[lcore_id], lcore_id);
if (ret == 0)
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 8/9] power: allow the service core to config power QoS
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (6 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 7/9] power/kvm_vm: " Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 7:30 ` [PATCH v4 9/9] power: add lcore ID check for PMD mgmt Huisong Li
` (2 subsequent siblings)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
The lcore ID verification in power QoS API used to use
rte_lcore_is_enabled(), which only accepts the lcore with
ROLE_RTE role. But service core thread (ROLE_SERVICE) can
also use power QoS API.
So use RTE_POWER_VALID_LCOREID_OR_ERR_RET to verify the
lcore ID. This change makes the power QoS API accept both
ROLE_RTE and ROLE_SERVICE lcores.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
doc/guides/rel_notes/release_26_07.rst | 5 ++++-
lib/power/rte_power_qos.c | 10 ++--------
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
index aeabb908ec..5eb3974ddb 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -158,7 +158,10 @@ New Features
* **Added a common macro to verify lcore ID in power core.**
Added the ``RTE_POWER_VALID_LCOREID_OR_ERR_RET`` macro to verify lcore ID
- in power core.
+ in power core. The power QoS library also updated its lcore validation to
+ use this macro, so service cores (``ROLE_SERVICE``) are now permitted.
+
+
Removed Items
-------------
diff --git a/lib/power/rte_power_qos.c b/lib/power/rte_power_qos.c
index f991230532..d8d8d36a76 100644
--- a/lib/power/rte_power_qos.c
+++ b/lib/power/rte_power_qos.c
@@ -27,10 +27,7 @@ rte_power_qos_set_cpu_resume_latency(uint16_t lcore_id, int latency)
FILE *f;
int ret;
- if (!rte_lcore_is_enabled(lcore_id)) {
- POWER_LOG(ERR, "lcore id %u is not enabled", lcore_id);
- return -EINVAL;
- }
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -EINVAL);
ret = power_get_lcore_mapped_cpu_id(lcore_id, &cpu_id);
if (ret != 0)
return ret;
@@ -82,10 +79,7 @@ rte_power_qos_get_cpu_resume_latency(uint16_t lcore_id)
FILE *f;
int ret;
- if (!rte_lcore_is_enabled(lcore_id)) {
- POWER_LOG(ERR, "lcore id %u is not enabled", lcore_id);
- return -EINVAL;
- }
+ RTE_POWER_VALID_LCOREID_OR_ERR_RET(lcore_id, -EINVAL);
ret = power_get_lcore_mapped_cpu_id(lcore_id, &cpu_id);
if (ret != 0)
return ret;
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v4 9/9] power: add lcore ID check for PMD mgmt
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (7 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 8/9] power: allow the service core to config power QoS Huisong Li
@ 2026-06-15 7:30 ` Huisong Li
2026-06-15 9:22 ` [PATCH v4 0/9] power: centralize lcore ID validation fengchengwen
2026-06-29 6:22 ` lihuisong (C)
10 siblings, 0 replies; 12+ messages in thread
From: Huisong Li @ 2026-06-15 7:30 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9, lihuisong
The pmd_mgmt lib is mainly used together with the data plane of ethdev
PMD. The core in data plane is ROLE_RTE. So use rte_lcore_is_enabled
to verify it.
Fixes: 426511683762 ("power: add get/set min/max scaling frequencies API")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
lib/power/rte_power_pmd_mgmt.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lib/power/rte_power_pmd_mgmt.c b/lib/power/rte_power_pmd_mgmt.c
index a4d53aac2a..a5fc1c3a94 100644
--- a/lib/power/rte_power_pmd_mgmt.c
+++ b/lib/power/rte_power_pmd_mgmt.c
@@ -511,7 +511,8 @@ rte_power_ethdev_pmgmt_queue_enable(unsigned int lcore_id, uint16_t port_id,
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
- if (queue_id >= RTE_MAX_QUEUES_PER_PORT || lcore_id >= RTE_MAX_LCORE) {
+ if (queue_id >= RTE_MAX_QUEUES_PER_PORT ||
+ !rte_lcore_is_enabled(lcore_id)) {
ret = -EINVAL;
goto end;
}
@@ -627,7 +628,7 @@ rte_power_ethdev_pmgmt_queue_disable(unsigned int lcore_id,
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
- if (lcore_id >= RTE_MAX_LCORE || queue_id >= RTE_MAX_QUEUES_PER_PORT)
+ if (!rte_lcore_is_enabled(lcore_id) || queue_id >= RTE_MAX_QUEUES_PER_PORT)
return -EINVAL;
/* check if the queue is stopped */
@@ -729,8 +730,8 @@ RTE_EXPORT_SYMBOL(rte_power_pmd_mgmt_set_scaling_freq_min)
int
rte_power_pmd_mgmt_set_scaling_freq_min(unsigned int lcore, unsigned int min)
{
- if (lcore >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID: %u", lcore);
+ if (!rte_lcore_is_enabled(lcore)) {
+ POWER_LOG(ERR, "lcore id %u is not enabled", lcore);
return -EINVAL;
}
@@ -747,8 +748,8 @@ RTE_EXPORT_SYMBOL(rte_power_pmd_mgmt_set_scaling_freq_max)
int
rte_power_pmd_mgmt_set_scaling_freq_max(unsigned int lcore, unsigned int max)
{
- if (lcore >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID: %u", lcore);
+ if (!rte_lcore_is_enabled(lcore)) {
+ POWER_LOG(ERR, "lcore id %u is not enabled", lcore);
return -EINVAL;
}
@@ -769,8 +770,8 @@ RTE_EXPORT_SYMBOL(rte_power_pmd_mgmt_get_scaling_freq_min)
int
rte_power_pmd_mgmt_get_scaling_freq_min(unsigned int lcore)
{
- if (lcore >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID: %u", lcore);
+ if (!rte_lcore_is_enabled(lcore)) {
+ POWER_LOG(ERR, "lcore id %u is not enabled", lcore);
return -EINVAL;
}
@@ -784,8 +785,8 @@ RTE_EXPORT_SYMBOL(rte_power_pmd_mgmt_get_scaling_freq_max)
int
rte_power_pmd_mgmt_get_scaling_freq_max(unsigned int lcore)
{
- if (lcore >= RTE_MAX_LCORE) {
- POWER_LOG(ERR, "Invalid lcore ID: %u", lcore);
+ if (!rte_lcore_is_enabled(lcore)) {
+ POWER_LOG(ERR, "lcore id %u is not enabled", lcore);
return -EINVAL;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v4 0/9] power: centralize lcore ID validation
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (8 preceding siblings ...)
2026-06-15 7:30 ` [PATCH v4 9/9] power: add lcore ID check for PMD mgmt Huisong Li
@ 2026-06-15 9:22 ` fengchengwen
2026-06-29 6:22 ` lihuisong (C)
10 siblings, 0 replies; 12+ messages in thread
From: fengchengwen @ 2026-06-15 9:22 UTC (permalink / raw)
To: Huisong Li, thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, yangxingui, zhanjie9
LGTM
Series-acked-by: Chengwen Feng <fengchengwen@huawei.com>
On 6/15/2026 3:30 PM, Huisong Li wrote:
> This series centralizes the lcore ID verification in the power cpufreq
> framework, replacing the per-driver range checks with a common validation.
>
> Background
> ----------
> Currently, various cpufreq drivers implement their own lcore ID checks,
> which are limited to simple range validation against RTE_MAX_LCORE and
> involve significant code duplication across 12+ functions per driver.
> The checks are duplicated across all drivers — any change requires
> updating 5+ drivers identically. Moreover, these checks do not verify
> whether the lcore is actually managed by the application. So it is better
> to verify lcore ID in cpufreq core.
>
> For cpufreq-related APIs, although service cores do not typically invoke
> these APIs, they may operate in polling modes where power management is
> required. To maintain compatibility with applications using service cores,
> the validation logic now explicitly accepts both ROLE_RTE and ROLE_SERVICE.
>
> The usage of power QoS APIs are similar to that of cpufreq. They also can
> accepts ROLE_RTE and ROLE_SERVICE.
>
> For PMD power management APIs, the lcore must be ROLE_RTE because these
> are used together with the data plane of ethdev PMD. Hence,
> rte_lcore_is_enabled() is used for validation.
>
> Key Changes:
> ------------
> Patch 1: Adds a common macro (RTE_POWER_VALID_LCOREID_OR_ERR_RET)
> that accepts both roles.
> Patch 2: Adds the validation to the cpufreq framework layer.
> Patches 3-7: Remove the now-redundant per-driver RTE_MAX_LCORE checks.
> Patch 8: Update power QoS to use the new validation, allowing
> service cores to configure QoS parameters.
> Patch 9: Add lcore validation to PMD management functions.
>
> Changes:
> --------
> v4: remove the patch that add the helper function rte_lcore_is_eal_managed.
>
> v3:
> - update release note.
> - add __rte_experimental for new helper function.
> - restructure this patch set to facilitate review.
>
> v2:
> - allow the service cores to set power API.
>
> ----
>
> Huisong Li (9):
> power: add a common macro to verify lcore ID
> power/cpufreq: add the lcore ID verification to framework
> power/acpi: remove redundant lcore ID checks
> power/amd_pstate: remove redundant lcore ID checks
> power/cppc: remove redundant lcore ID checks
> power/intel_pstate: remove redundant lcore ID checks
> power/kvm_vm: remove redundant lcore ID checks
> power: allow the service core to config power QoS
> power: add lcore ID check for PMD mgmt
>
> doc/guides/rel_notes/release_26_07.rst | 7 ++
> drivers/power/acpi/acpi_cpufreq.c | 65 -------------------
> drivers/power/amd_pstate/amd_pstate_cpufreq.c | 65 -------------------
> drivers/power/cppc/cppc_cpufreq.c | 65 -------------------
> .../power/intel_pstate/intel_pstate_cpufreq.c | 65 -------------------
> drivers/power/kvm_vm/guest_channel.c | 22 -------
> drivers/power/kvm_vm/kvm_vm.c | 10 ---
> lib/power/power_common.h | 8 +++
> lib/power/rte_power_cpufreq.c | 13 ++++
> lib/power/rte_power_pmd_mgmt.c | 21 +++---
> lib/power/rte_power_qos.c | 10 +--
> 11 files changed, 41 insertions(+), 310 deletions(-)
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v4 0/9] power: centralize lcore ID validation
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
` (9 preceding siblings ...)
2026-06-15 9:22 ` [PATCH v4 0/9] power: centralize lcore ID validation fengchengwen
@ 2026-06-29 6:22 ` lihuisong (C)
10 siblings, 0 replies; 12+ messages in thread
From: lihuisong (C) @ 2026-06-29 6:22 UTC (permalink / raw)
To: thomas, anatoly.burakov, sivaprasad.tummala
Cc: dev, stephen, fengchengwen, yangxingui, zhanjie9
Kindly ping for review.
On 6/15/2026 3:30 PM, Huisong Li wrote:
> This series centralizes the lcore ID verification in the power cpufreq
> framework, replacing the per-driver range checks with a common validation.
>
> Background
> ----------
> Currently, various cpufreq drivers implement their own lcore ID checks,
> which are limited to simple range validation against RTE_MAX_LCORE and
> involve significant code duplication across 12+ functions per driver.
> The checks are duplicated across all drivers — any change requires
> updating 5+ drivers identically. Moreover, these checks do not verify
> whether the lcore is actually managed by the application. So it is better
> to verify lcore ID in cpufreq core.
>
> For cpufreq-related APIs, although service cores do not typically invoke
> these APIs, they may operate in polling modes where power management is
> required. To maintain compatibility with applications using service cores,
> the validation logic now explicitly accepts both ROLE_RTE and ROLE_SERVICE.
>
> The usage of power QoS APIs are similar to that of cpufreq. They also can
> accepts ROLE_RTE and ROLE_SERVICE.
>
> For PMD power management APIs, the lcore must be ROLE_RTE because these
> are used together with the data plane of ethdev PMD. Hence,
> rte_lcore_is_enabled() is used for validation.
>
> Key Changes:
> ------------
> Patch 1: Adds a common macro (RTE_POWER_VALID_LCOREID_OR_ERR_RET)
> that accepts both roles.
> Patch 2: Adds the validation to the cpufreq framework layer.
> Patches 3-7: Remove the now-redundant per-driver RTE_MAX_LCORE checks.
> Patch 8: Update power QoS to use the new validation, allowing
> service cores to configure QoS parameters.
> Patch 9: Add lcore validation to PMD management functions.
>
> Changes:
> --------
> v4: remove the patch that add the helper function rte_lcore_is_eal_managed.
>
> v3:
> - update release note.
> - add __rte_experimental for new helper function.
> - restructure this patch set to facilitate review.
>
> v2:
> - allow the service cores to set power API.
>
> ----
>
> Huisong Li (9):
> power: add a common macro to verify lcore ID
> power/cpufreq: add the lcore ID verification to framework
> power/acpi: remove redundant lcore ID checks
> power/amd_pstate: remove redundant lcore ID checks
> power/cppc: remove redundant lcore ID checks
> power/intel_pstate: remove redundant lcore ID checks
> power/kvm_vm: remove redundant lcore ID checks
> power: allow the service core to config power QoS
> power: add lcore ID check for PMD mgmt
>
> doc/guides/rel_notes/release_26_07.rst | 7 ++
> drivers/power/acpi/acpi_cpufreq.c | 65 -------------------
> drivers/power/amd_pstate/amd_pstate_cpufreq.c | 65 -------------------
> drivers/power/cppc/cppc_cpufreq.c | 65 -------------------
> .../power/intel_pstate/intel_pstate_cpufreq.c | 65 -------------------
> drivers/power/kvm_vm/guest_channel.c | 22 -------
> drivers/power/kvm_vm/kvm_vm.c | 10 ---
> lib/power/power_common.h | 8 +++
> lib/power/rte_power_cpufreq.c | 13 ++++
> lib/power/rte_power_pmd_mgmt.c | 21 +++---
> lib/power/rte_power_qos.c | 10 +--
> 11 files changed, 41 insertions(+), 310 deletions(-)
>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-06-29 6:22 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-15 7:30 [PATCH v4 0/9] power: centralize lcore ID validation Huisong Li
2026-06-15 7:30 ` [PATCH v4 1/9] power: add a common macro to verify lcore ID Huisong Li
2026-06-15 7:30 ` [PATCH v4 2/9] power/cpufreq: add the lcore ID verification to framework Huisong Li
2026-06-15 7:30 ` [PATCH v4 3/9] power/acpi: remove redundant lcore ID checks Huisong Li
2026-06-15 7:30 ` [PATCH v4 4/9] power/amd_pstate: " Huisong Li
2026-06-15 7:30 ` [PATCH v4 5/9] power/cppc: " Huisong Li
2026-06-15 7:30 ` [PATCH v4 6/9] power/intel_pstate: " Huisong Li
2026-06-15 7:30 ` [PATCH v4 7/9] power/kvm_vm: " Huisong Li
2026-06-15 7:30 ` [PATCH v4 8/9] power: allow the service core to config power QoS Huisong Li
2026-06-15 7:30 ` [PATCH v4 9/9] power: add lcore ID check for PMD mgmt Huisong Li
2026-06-15 9:22 ` [PATCH v4 0/9] power: centralize lcore ID validation fengchengwen
2026-06-29 6:22 ` lihuisong (C)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox