* [PATCH v4 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
@ 2026-07-29 2:51 ` Huisong Li
2026-07-29 2:51 ` [PATCH v4 2/6] examples/l3fwd-power: enable power QoS for all modes Huisong Li
` (6 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Huisong Li @ 2026-07-29 2:51 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Uncore resources were not being deinitialized in non-legacy modes (such
as pmd-mgmt), causing the uncore frequency not to return to its original
value after the application exited.
The root cause is that uncore initialization can be performed for all
modes, whereas the deinitialization logic is incorrectly restricted
to legacy mode only. So do the deinitialization of uncore on all app
modes.
Fixes: 10db2a5b8724 ("examples/l3fwd-power: add options for uncore frequency")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
examples/l3fwd-power/main.c | 66 ++++++++++++++++++++-----------------
1 file changed, 35 insertions(+), 31 deletions(-)
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 705cab8f2d..4b0128eeaa 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -2270,28 +2270,31 @@ init_power_library(void)
unsigned int lcore_id;
int ret = 0;
- RTE_LCORE_FOREACH(lcore_id) {
- /* init power management library */
- ret = rte_power_init(lcore_id);
- if (ret) {
- RTE_LOG(ERR, L3FWD_POWER,
- "Library initialization failed on core %u\n",
- lcore_id);
- return ret;
- }
- /* we're not supporting the VM channel mode */
- env = rte_power_get_env();
- if (env != PM_ENV_ACPI_CPUFREQ &&
- env != PM_ENV_PSTATE_CPUFREQ &&
- env != PM_ENV_AMD_PSTATE_CPUFREQ &&
- env != PM_ENV_CPPC_CPUFREQ) {
- RTE_LOG(ERR, L3FWD_POWER,
- "Only ACPI and PSTATE mode are supported\n");
- return -1;
+ /* only legacy mode relies on the initialization of cpufreq library */
+ if (app_mode == APP_MODE_LEGACY) {
+ RTE_LCORE_FOREACH(lcore_id) {
+ /* init power management library */
+ ret = rte_power_init(lcore_id);
+ if (ret) {
+ RTE_LOG(ERR, L3FWD_POWER,
+ "Library initialization failed on core %u\n",
+ lcore_id);
+ return ret;
+ }
+ /* we're not supporting the VM channel mode */
+ env = rte_power_get_env();
+ if (env != PM_ENV_ACPI_CPUFREQ &&
+ env != PM_ENV_PSTATE_CPUFREQ &&
+ env != PM_ENV_AMD_PSTATE_CPUFREQ &&
+ env != PM_ENV_CPPC_CPUFREQ) {
+ RTE_LOG(ERR, L3FWD_POWER,
+ "Only ACPI and PSTATE mode are supported\n");
+ return -1;
+ }
}
}
- if (cpu_resume_latency != -1) {
+ if (app_mode == APP_MODE_LEGACY && cpu_resume_latency != -1) {
RTE_LCORE_FOREACH(lcore_id) {
/* Back old CPU resume latency. */
ret = rte_power_qos_get_cpu_resume_latency(lcore_id);
@@ -2329,14 +2332,16 @@ deinit_power_library(void)
unsigned int lcore_id, max_pkg, max_die, die, pkg;
int ret = 0;
- RTE_LCORE_FOREACH(lcore_id) {
- /* deinit power management library */
- ret = rte_power_exit(lcore_id);
- if (ret) {
- RTE_LOG(ERR, L3FWD_POWER,
- "Library deinitialization failed on core %u\n",
- lcore_id);
- return ret;
+ if (app_mode == APP_MODE_LEGACY) {
+ RTE_LCORE_FOREACH(lcore_id) {
+ /* deinit power management library */
+ ret = rte_power_exit(lcore_id);
+ if (ret) {
+ RTE_LOG(ERR, L3FWD_POWER,
+ "Library deinitialization failed on core %u\n",
+ lcore_id);
+ return ret;
+ }
}
}
@@ -2360,7 +2365,7 @@ deinit_power_library(void)
}
}
- if (cpu_resume_latency != -1) {
+ if (app_mode == APP_MODE_LEGACY && cpu_resume_latency != -1) {
RTE_LCORE_FOREACH(lcore_id) {
/* Restore the original value. */
rte_power_qos_set_cpu_resume_latency(lcore_id,
@@ -2602,8 +2607,7 @@ main(int argc, char **argv)
RTE_LOG(INFO, L3FWD_POWER, "Selected operation mode: %s\n",
mode_to_str(app_mode));
- /* only legacy mode relies on power library */
- if ((app_mode == APP_MODE_LEGACY) && init_power_library())
+ if (init_power_library())
rte_exit(EXIT_FAILURE, "init_power_library failed\n");
if (update_lcore_params() < 0)
@@ -2975,7 +2979,7 @@ main(int argc, char **argv)
rte_eth_dev_close(portid);
}
- if ((app_mode == APP_MODE_LEGACY) && deinit_power_library())
+ if (deinit_power_library())
rte_exit(EXIT_FAILURE, "deinit_power_library failed\n");
if (rte_eal_cleanup() < 0)
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 2/6] examples/l3fwd-power: enable power QoS for all modes
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
2026-07-29 2:51 ` [PATCH v4 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
@ 2026-07-29 2:51 ` Huisong Li
2026-07-29 2:51 ` [PATCH v4 3/6] examples/l3fwd-power: fix uncore help and log info Huisong Li
` (5 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Huisong Li @ 2026-07-29 2:51 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Power QoS feature doesn't depend on app mode, here open it for all.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
examples/l3fwd-power/main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 4b0128eeaa..3af10c629a 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -2294,7 +2294,7 @@ init_power_library(void)
}
}
- if (app_mode == APP_MODE_LEGACY && cpu_resume_latency != -1) {
+ if (cpu_resume_latency != -1) {
RTE_LCORE_FOREACH(lcore_id) {
/* Back old CPU resume latency. */
ret = rte_power_qos_get_cpu_resume_latency(lcore_id);
@@ -2365,7 +2365,7 @@ deinit_power_library(void)
}
}
- if (app_mode == APP_MODE_LEGACY && cpu_resume_latency != -1) {
+ if (cpu_resume_latency != -1) {
RTE_LCORE_FOREACH(lcore_id) {
/* Restore the original value. */
rte_power_qos_set_cpu_resume_latency(lcore_id,
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 3/6] examples/l3fwd-power: fix uncore help and log info
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
2026-07-29 2:51 ` [PATCH v4 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
2026-07-29 2:51 ` [PATCH v4 2/6] examples/l3fwd-power: enable power QoS for all modes Huisong Li
@ 2026-07-29 2:51 ` Huisong Li
2026-07-29 2:51 ` [PATCH v4 4/6] examples/l3fwd-power: relocate uncore initialization Huisong Li
` (4 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Huisong Li @ 2026-07-29 2:51 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
The '-i' parameter is to set any uncore frequency rather than
min/max value. And the error logs are not clear enough, fix it
by the way.
Fixes: 10db2a5b8724 ("examples/l3fwd-power: add options for uncore frequency")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
doc/guides/sample_app_ug/l3_forward_power_man.rst | 2 +-
examples/l3fwd-power/main.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/doc/guides/sample_app_ug/l3_forward_power_man.rst b/doc/guides/sample_app_ug/l3_forward_power_man.rst
index f33f3b2f94..ef3f1f1519 100644
--- a/doc/guides/sample_app_ug/l3_forward_power_man.rst
+++ b/doc/guides/sample_app_ug/l3_forward_power_man.rst
@@ -106,7 +106,7 @@ where,
* -U: optional, sets uncore min/max frequency to maximum value.
-* -i (frequency index): optional, sets uncore frequency to frequency index value, by setting min and max values to be the same.
+* -i (frequency index): set target frequency for uncore by specified frequency index.
* --config (port,queue,lcore)[,(port,queue,lcore)]: determines which queues from which ports are mapped to which cores.
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 3af10c629a..72d4642ea4 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1497,7 +1497,7 @@ print_usage(const char *prgname)
" -P: enable promiscuous mode\n"
" -u: set min/max frequency for uncore to minimum value\n"
" -U: set min/max frequency for uncore to maximum value\n"
- " -i (frequency index): set min/max frequency for uncore to specified frequency index\n"
+ " -i (frequency index): set target frequency for uncore by specified frequency index\n"
" --config (port,queue,lcore): rx queues configuration\n"
" --eth-link-speed: force link speed\n"
" --cpu-resume-latency LATENCY: set CPU resume latency to control C-state selection,"
@@ -1581,7 +1581,7 @@ parse_uncore_options(enum uncore_choice choice, const char *argument)
ret = rte_power_uncore_freq_min(pkg, die);
if (ret == -1) {
RTE_LOG(INFO, L3FWD_POWER,
- "Unable to set the uncore min/max to minimum uncore frequency value for pkg %02u die %02u\n"
+ "Unable to set the uncore frequency to minimum value for pkg %02u die %02u\n"
, pkg, die);
return ret;
}
@@ -1589,7 +1589,7 @@ parse_uncore_options(enum uncore_choice choice, const char *argument)
ret = rte_power_uncore_freq_max(pkg, die);
if (ret == -1) {
RTE_LOG(INFO, L3FWD_POWER,
- "Unable to set uncore min/max to maximum uncore frequency value for pkg %02u die %02u\n"
+ "Unable to set uncore frequency to maximum value for pkg %02u die %02u\n"
, pkg, die);
return ret;
}
@@ -1610,7 +1610,7 @@ parse_uncore_options(enum uncore_choice choice, const char *argument)
ret = rte_power_set_uncore_freq(pkg, die, frequency_index);
if (ret == -1) {
RTE_LOG(INFO, L3FWD_POWER,
- "Unable to set min/max uncore index value for pkg %02u die %02u\n",
+ "Unable to set specified frequency index for pkg %02u die %02u\n",
pkg, die);
return ret;
}
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 4/6] examples/l3fwd-power: relocate uncore initialization
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
` (2 preceding siblings ...)
2026-07-29 2:51 ` [PATCH v4 3/6] examples/l3fwd-power: fix uncore help and log info Huisong Li
@ 2026-07-29 2:51 ` Huisong Li
2026-07-29 2:51 ` [PATCH v4 5/6] power: support automatic detection of uncore driver Huisong Li
` (3 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Huisong Li @ 2026-07-29 2:51 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Currently, the deinitialization of uncore is in deinit_power_library().
But its initialization is located in the parameter parsing function,
which is not good to maintain.
So move this logic to init_power_library().
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
examples/l3fwd-power/main.c | 192 ++++++++++++++++++------------------
1 file changed, 97 insertions(+), 95 deletions(-)
diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
index 72d4642ea4..7de281808f 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -149,9 +149,6 @@ static struct rte_timer telemetry_timer;
/* stats index returned by metrics lib */
int telstats_index;
-/* flag to check if uncore option enabled */
-int enabled_uncore = -1;
-
struct telstats_name {
char name[RTE_ETH_XSTATS_NAME_SIZE];
};
@@ -170,12 +167,6 @@ enum busy_rate {
FULL = 100
};
-enum uncore_choice {
- UNCORE_MIN = 0,
- UNCORE_MAX = 1,
- UNCORE_IDX = 2
-};
-
/* reference poll count to measure core busyness */
#define DEFAULT_COUNT 10000
/*
@@ -212,6 +203,19 @@ enum freq_scale_hint_t
FREQ_HIGHEST = 2
};
+enum uncore_choice {
+ UNCORE_MIN = 0,
+ UNCORE_MAX = 1,
+ UNCORE_IDX = 2
+};
+
+/* flag to check if uncore option enabled */
+int enabled_uncore = -1;
+struct uncore_cfg {
+ enum uncore_choice uncore_choice;
+ uint32_t freq_idx;
+} g_uncore_cfg;
+
struct __rte_cache_aligned lcore_rx_queue {
uint16_t port_id;
uint16_t queue_id;
@@ -1551,80 +1555,6 @@ parse_uint(const char *opt, uint32_t max, uint32_t *res)
return 0;
}
-static int
-parse_uncore_options(enum uncore_choice choice, const char *argument)
-{
- unsigned int die, pkg, max_pkg, max_die;
- int ret = 0;
- ret = rte_power_set_uncore_env(RTE_UNCORE_PM_ENV_AUTO_DETECT);
- if (ret < 0) {
- RTE_LOG(INFO, L3FWD_POWER, "Failed to set uncore env\n");
- return ret;
- }
-
- max_pkg = rte_power_uncore_get_num_pkgs();
- if (max_pkg == 0)
- return -1;
-
- for (pkg = 0; pkg < max_pkg; pkg++) {
- max_die = rte_power_uncore_get_num_dies(pkg);
- if (max_die == 0)
- return -1;
- for (die = 0; die < max_die; die++) {
- ret = rte_power_uncore_init(pkg, die);
- if (ret == -1) {
- RTE_LOG(INFO, L3FWD_POWER, "Unable to initialize uncore for pkg %02u die %02u\n"
- , pkg, die);
- return ret;
- }
- if (choice == UNCORE_MIN) {
- ret = rte_power_uncore_freq_min(pkg, die);
- if (ret == -1) {
- RTE_LOG(INFO, L3FWD_POWER,
- "Unable to set the uncore frequency to minimum value for pkg %02u die %02u\n"
- , pkg, die);
- return ret;
- }
- } else if (choice == UNCORE_MAX) {
- ret = rte_power_uncore_freq_max(pkg, die);
- if (ret == -1) {
- RTE_LOG(INFO, L3FWD_POWER,
- "Unable to set uncore frequency to maximum value for pkg %02u die %02u\n"
- , pkg, die);
- return ret;
- }
- } else if (choice == UNCORE_IDX) {
- char *ptr = NULL;
- int frequency_index = strtol(argument, &ptr, 10);
- if (argument == ptr) {
- RTE_LOG(INFO, L3FWD_POWER, "Index given is not a valid number.");
- return -1;
- }
- int freq_array_len = rte_power_uncore_get_num_freqs(pkg, die);
- if (frequency_index > freq_array_len - 1) {
- RTE_LOG(INFO, L3FWD_POWER,
- "Frequency index given out of range, please choose a value from 0 to %d.\n",
- freq_array_len);
- return -1;
- }
- ret = rte_power_set_uncore_freq(pkg, die, frequency_index);
- if (ret == -1) {
- RTE_LOG(INFO, L3FWD_POWER,
- "Unable to set specified frequency index for pkg %02u die %02u\n",
- pkg, die);
- return ret;
- }
- } else {
- RTE_LOG(INFO, L3FWD_POWER, "Uncore choice provided invalid\n");
- return -1;
- }
- }
- }
-
- RTE_LOG(INFO, L3FWD_POWER, "Successfully set max/min/index uncore frequency.\n");
- return ret;
-}
-
static int
parse_portmask(const char *portmask)
{
@@ -1792,25 +1722,21 @@ parse_args(int argc, char **argv)
promiscuous_on = 1;
break;
case 'u':
- enabled_uncore = parse_uncore_options(UNCORE_MIN, NULL);
- if (enabled_uncore < 0) {
- print_usage(prgname);
- return -1;
- }
+ enabled_uncore = 0;
+ g_uncore_cfg.uncore_choice = UNCORE_MIN;
break;
case 'U':
- enabled_uncore = parse_uncore_options(UNCORE_MAX, NULL);
- if (enabled_uncore < 0) {
- print_usage(prgname);
- return -1;
- }
+ enabled_uncore = 0;
+ g_uncore_cfg.uncore_choice = UNCORE_MAX;
break;
case 'i':
- enabled_uncore = parse_uncore_options(UNCORE_IDX, optarg);
- if (enabled_uncore < 0) {
+ enabled_uncore = 0;
+ if (parse_uint(optarg, UINT32_MAX, &g_uncore_cfg.freq_idx) != 0) {
+ RTE_LOG(INFO, L3FWD_POWER, "Index given is not a valid number.");
print_usage(prgname);
return -1;
}
+ g_uncore_cfg.uncore_choice = UNCORE_IDX;
break;
/* long options */
case 0:
@@ -2263,6 +2189,78 @@ static int check_ptype(uint16_t portid)
}
+static int
+power_uncore_init(void)
+{
+ unsigned int die, pkg, max_pkg, max_die;
+ int ret;
+
+ if (enabled_uncore == -1)
+ return 0;
+
+ ret = rte_power_set_uncore_env(RTE_UNCORE_PM_ENV_AUTO_DETECT);
+ if (ret < 0) {
+ RTE_LOG(INFO, L3FWD_POWER, "Failed to set uncore env\n");
+ return ret;
+ }
+
+ max_pkg = rte_power_uncore_get_num_pkgs();
+ if (max_pkg == 0)
+ return -1;
+
+ for (pkg = 0; pkg < max_pkg; pkg++) {
+ max_die = rte_power_uncore_get_num_dies(pkg);
+ if (max_die == 0)
+ return -1;
+ for (die = 0; die < max_die; die++) {
+ ret = rte_power_uncore_init(pkg, die);
+ if (ret == -1) {
+ RTE_LOG(INFO, L3FWD_POWER, "Unable to initialize uncore for pkg %02u die %02u\n"
+ , pkg, die);
+ return ret;
+ }
+ if (g_uncore_cfg.uncore_choice == UNCORE_MIN) {
+ ret = rte_power_uncore_freq_min(pkg, die);
+ if (ret == -1) {
+ RTE_LOG(INFO, L3FWD_POWER,
+ "Unable to set the uncore frequency to minimum value for pkg %02u die %02u\n"
+ , pkg, die);
+ return ret;
+ }
+ } else if (g_uncore_cfg.uncore_choice == UNCORE_MAX) {
+ ret = rte_power_uncore_freq_max(pkg, die);
+ if (ret == -1) {
+ RTE_LOG(INFO, L3FWD_POWER,
+ "Unable to set uncore frequency to maximum value for pkg %02u die %02u\n"
+ , pkg, die);
+ return ret;
+ }
+ } else if (g_uncore_cfg.uncore_choice == UNCORE_IDX) {
+ int freq_array_len = rte_power_uncore_get_num_freqs(pkg, die);
+ if (freq_array_len <= 0) {
+ RTE_LOG(INFO, L3FWD_POWER, "Get uncore frequency number failed.\n");
+ return -1;
+ }
+ if (g_uncore_cfg.freq_idx > (uint32_t)(freq_array_len - 1)) {
+ RTE_LOG(INFO, L3FWD_POWER,
+ "Frequency index given out of range, please choose a value from 0 to %d.\n",
+ freq_array_len);
+ return -1;
+ }
+ ret = rte_power_set_uncore_freq(pkg, die, g_uncore_cfg.freq_idx);
+ if (ret == -1) {
+ RTE_LOG(INFO, L3FWD_POWER,
+ "Unable to set specified frequency index for pkg %02u die %02u\n",
+ pkg, die);
+ return ret;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
static int
init_power_library(void)
{
@@ -2294,6 +2292,10 @@ init_power_library(void)
}
}
+ ret = power_uncore_init();
+ if (ret != 0)
+ return ret;
+
if (cpu_resume_latency != -1) {
RTE_LCORE_FOREACH(lcore_id) {
/* Back old CPU resume latency. */
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 5/6] power: support automatic detection of uncore driver
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
` (3 preceding siblings ...)
2026-07-29 2:51 ` [PATCH v4 4/6] examples/l3fwd-power: relocate uncore initialization Huisong Li
@ 2026-07-29 2:51 ` Huisong Li
2026-07-29 2:51 ` [PATCH v4 6/6] power: remove unused auto-detection uncore Huisong Li
` (2 subsequent siblings)
7 siblings, 0 replies; 10+ messages in thread
From: Huisong Li @ 2026-07-29 2:51 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Currently, uncore driver library just supports intel_uncore
driver as default driver when user use AUTO_DETECT, please see
the commit 3b3af56d3c9c ("power: fix uncore configuration").
This is not good to use for application. So this patch support
probing for uncore drivers.
Fixes: 3b3af56d3c9c ("power: fix uncore configuration")
Cc: stable@dpdk.org
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
doc/guides/rel_notes/release_26_11.rst | 6 ++++
lib/power/rte_power_uncore.c | 46 ++++++++++++++++++++++----
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc86295d..65438e8e3a 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -55,6 +55,12 @@ New Features
Also, make sure to start the actual text at the margin.
=======================================================
+* **Support auto-detection of uncore power driver.**
+
+ The uncore power library now supports automatic probing of multiple
+ uncore drivers when using ``RTE_UNCORE_PM_ENV_AUTO_DETECT``,
+ instead of defaulting only to the Intel uncore driver.
+
Removed Items
-------------
diff --git a/lib/power/rte_power_uncore.c b/lib/power/rte_power_uncore.c
index b50e09a2ad..64a8c2648d 100644
--- a/lib/power/rte_power_uncore.c
+++ b/lib/power/rte_power_uncore.c
@@ -2,6 +2,7 @@
* Copyright(c) 2010-2014 Intel Corporation
* Copyright(c) 2023 AMD Corporation
*/
+#include <errno.h>
#include <eal_export.h>
#include <rte_spinlock.h>
@@ -46,6 +47,39 @@ rte_power_register_uncore_ops(struct rte_power_uncore_ops *driver_ops)
return 0;
}
+static uint32_t power_uncore_driver_name2env(char *name)
+{
+ for (uint32_t i = 0; i < RTE_DIM(uncore_env_str); i++) {
+ if (!strcmp(name, uncore_env_str[i]))
+ return i;
+ }
+
+ return UINT32_MAX;
+}
+
+static int power_uncore_probe_driver(void)
+{
+ struct rte_power_uncore_ops *ops;
+ int ret;
+
+ global_uncore_ops = NULL;
+ /* Use package-0 and die-0 to probe uncore driver. */
+ RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next) {
+ ret = ops->init(0, 0);
+ if (ret == 0) {
+ uint32_t env = power_uncore_driver_name2env(ops->name);
+ if (env == UINT32_MAX)
+ continue;
+ global_uncore_env = env;
+ global_uncore_ops = ops;
+ ops->exit(0, 0);
+ break;
+ }
+ }
+
+ return global_uncore_ops ? 0 : -ENODEV;
+}
+
RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_power_set_uncore_env, 23.11)
int
rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
@@ -60,12 +94,12 @@ rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
goto out;
}
- if (env == RTE_UNCORE_PM_ENV_AUTO_DETECT)
- /* Currently only intel_uncore is supported.
- * This will be extended with auto-detection support
- * for multiple uncore implementations.
- */
- env = RTE_UNCORE_PM_ENV_INTEL_UNCORE;
+ if (env == RTE_UNCORE_PM_ENV_AUTO_DETECT) {
+ ret = power_uncore_probe_driver();
+ if (ret != 0)
+ POWER_LOG(ERR, "Probe uncore driver failed, ret = %d", ret);
+ goto out;
+ }
if (env < RTE_DIM(uncore_env_str)) {
RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next)
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH v4 6/6] power: remove unused auto-detection uncore
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
` (4 preceding siblings ...)
2026-07-29 2:51 ` [PATCH v4 5/6] power: support automatic detection of uncore driver Huisong Li
@ 2026-07-29 2:51 ` Huisong Li
2026-08-10 11:12 ` [PATCH v4 0/6] power: uncore power improvements and auto-detection lihuisong (C)
2026-08-10 16:21 ` Stephen Hemminger
7 siblings, 0 replies; 10+ messages in thread
From: Huisong Li @ 2026-07-29 2:51 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Applications need to set uncore environment first by calling the API
rte_power_set_uncore_env, please see the commit 3b3af56d3c9c ("power:
fix uncore configuration").
Now, rte_power_set_uncore_env() supports automatic detection of uncore
drivers, the automatic detection environment code can be deleted.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
lib/power/rte_power_uncore.c | 32 +++++++-------------------------
1 file changed, 7 insertions(+), 25 deletions(-)
diff --git a/lib/power/rte_power_uncore.c b/lib/power/rte_power_uncore.c
index 64a8c2648d..8b61b073e0 100644
--- a/lib/power/rte_power_uncore.c
+++ b/lib/power/rte_power_uncore.c
@@ -140,32 +140,14 @@ RTE_EXPORT_SYMBOL(rte_power_uncore_init)
int
rte_power_uncore_init(unsigned int pkg, unsigned int die)
{
- int ret = -1;
- struct rte_power_uncore_ops *ops;
- uint8_t env;
+ if (global_uncore_env == RTE_UNCORE_PM_ENV_NOT_SET ||
+ global_uncore_env == RTE_UNCORE_PM_ENV_AUTO_DETECT ||
+ global_uncore_ops == NULL) {
+ POWER_LOG(ERR, "Please set uncore environment first.");
+ return -1;
+ }
- if ((global_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) &&
- (global_uncore_env != RTE_UNCORE_PM_ENV_AUTO_DETECT))
- return global_uncore_ops->init(pkg, die);
-
- /* Auto Detect Environment */
- RTE_TAILQ_FOREACH(ops, &uncore_ops_list, next)
- if (ops) {
- POWER_LOG(INFO,
- "Attempting to initialise %s power management...",
- ops->name);
- ret = ops->init(pkg, die);
- if (ret == 0) {
- for (env = 0; env < RTE_DIM(uncore_env_str); env++)
- if (strncmp(ops->name, uncore_env_str[env],
- RTE_POWER_UNCORE_DRIVER_NAMESZ) == 0) {
- rte_power_set_uncore_env(env);
- goto out;
- }
- }
- }
-out:
- return ret;
+ return global_uncore_ops->init(pkg, die);
}
RTE_EXPORT_SYMBOL(rte_power_uncore_exit)
--
2.33.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH v4 0/6] power: uncore power improvements and auto-detection
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
` (5 preceding siblings ...)
2026-07-29 2:51 ` [PATCH v4 6/6] power: remove unused auto-detection uncore Huisong Li
@ 2026-08-10 11:12 ` lihuisong (C)
2026-08-10 16:21 ` Stephen Hemminger
7 siblings, 0 replies; 10+ messages in thread
From: lihuisong (C) @ 2026-08-10 11:12 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Kindly ping for review.
On 7/29/2026 10:51 AM, Huisong Li wrote:
> This series improves the uncore power management in l3fwd-power
> and adds automatic detection of uncore drivers in the power library.
>
> - Fix uncore deinitialization for non-legacy modes.
> - Enable power QoS for all modes (not just legacy).
> - Fix uncore help text and log messages.
> - Relocate uncore initialization from arg parsing to init_power_library().
> - Support automatic probing of uncore drivers in AUTO_DETECT and delete
> useless code for auto-detection uncore environment.
>
> ---
> v4:
> - Fix '!global_uncore_ops' to 'global_uncore_ops == NULL' from AI review.
> v3 link:
> https://inbox.dpdk.org/dev/20260728120208.1858832-1-lihuisong@huawei.com/
>
> v3:
> - update feature to release_26_11.rst.
> - add a new patch to delte useless for automatic detection environment.
> v2 link:
> https://inbox.dpdk.org/dev/20260526081138.1434947-1-lihuisong@huawei.com/
>
> v2:
> - Remove the patch which add global uncore init and deinit interface.
> - Remove the last patch in l3fwd-power about these new interface.
> Will send them after this series.
> v1 link:
> https://inbox.dpdk.org/dev/20260512023513.460169-1-lihuisong@huawei.com/
>
> Huisong Li (6):
> examples/l3fwd-power: fix uncore deinit for non-legacy
> examples/l3fwd-power: enable power QoS for all modes
> examples/l3fwd-power: fix uncore help and log info
> examples/l3fwd-power: relocate uncore initialization
> power: support automatic detection of uncore driver
> power: remove unused auto-detection uncore
>
> doc/guides/rel_notes/release_26_11.rst | 6 +
> .../sample_app_ug/l3_forward_power_man.rst | 2 +-
> examples/l3fwd-power/main.c | 256 +++++++++---------
> lib/power/rte_power_uncore.c | 78 +++---
> 4 files changed, 185 insertions(+), 157 deletions(-)
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v4 0/6] power: uncore power improvements and auto-detection
2026-07-29 2:51 [PATCH v4 0/6] power: uncore power improvements and auto-detection Huisong Li
` (6 preceding siblings ...)
2026-08-10 11:12 ` [PATCH v4 0/6] power: uncore power improvements and auto-detection lihuisong (C)
@ 2026-08-10 16:21 ` Stephen Hemminger
2026-08-11 12:33 ` lihuisong (C)
7 siblings, 1 reply; 10+ messages in thread
From: Stephen Hemminger @ 2026-08-10 16:21 UTC (permalink / raw)
To: Huisong Li
Cc: anatoly.burakov, sivaprasad.tummala, dev, thomas, fengchengwen,
yangxingui, zhanjie9
On Wed, 29 Jul 2026 10:51:43 +0800
Huisong Li <lihuisong@huawei.com> wrote:
> This series improves the uncore power management in l3fwd-power
> and adds automatic detection of uncore drivers in the power library.
>
> - Fix uncore deinitialization for non-legacy modes.
> - Enable power QoS for all modes (not just legacy).
> - Fix uncore help text and log messages.
> - Relocate uncore initialization from arg parsing to init_power_library().
> - Support automatic probing of uncore drivers in AUTO_DETECT and delete
> useless code for auto-detection uncore environment.
>
> ---
> v4:
> - Fix '!global_uncore_ops' to 'global_uncore_ops == NULL' from AI review.
> v3 link:
> https://inbox.dpdk.org/dev/20260728120208.1858832-1-lihuisong@huawei.com/
>
> v3:
> - update feature to release_26_11.rst.
> - add a new patch to delte useless for automatic detection environment.
> v2 link:
> https://inbox.dpdk.org/dev/20260526081138.1434947-1-lihuisong@huawei.com/
>
> v2:
> - Remove the patch which add global uncore init and deinit interface.
> - Remove the last patch in l3fwd-power about these new interface.
> Will send them after this series.
> v1 link:
> https://inbox.dpdk.org/dev/20260512023513.460169-1-lihuisong@huawei.com/
>
> Huisong Li (6):
> examples/l3fwd-power: fix uncore deinit for non-legacy
> examples/l3fwd-power: enable power QoS for all modes
> examples/l3fwd-power: fix uncore help and log info
> examples/l3fwd-power: relocate uncore initialization
> power: support automatic detection of uncore driver
> power: remove unused auto-detection uncore
>
> doc/guides/rel_notes/release_26_11.rst | 6 +
> .../sample_app_ug/l3_forward_power_man.rst | 2 +-
> examples/l3fwd-power/main.c | 256 +++++++++---------
> lib/power/rte_power_uncore.c | 78 +++---
> 4 files changed, 185 insertions(+), 157 deletions(-)
>
Most of the developers are off enjoying summer vacation.
But AI is still around and finds some things here:
Note: some of what it complains about is noise.
Applied to main (26.11-rc0) and reviewed against source. Applies cleanly.
Note on check-git-log: it reports "Wrong 'Fixes' reference" for both
tags. That is a shallow-clone artifact. Both references are correct
against full history:
10db2a5b8724 ("examples/l3fwd-power: add options for uncore frequency")
3b3af56d3c9c ("power: fix uncore configuration")
Patch 4/6 examples/l3fwd-power: relocate uncore initialization
Warning: new file-scope variable g_uncore_cfg is neither static nor
prefixed. It is used only in main.c. Make it static and drop the g_
prefix, which is not DPDK style.
static struct uncore_cfg {
enum uncore_choice uncore_choice;
uint32_t freq_idx;
} uncore_cfg;
Info: the out-of-range message carries over an off-by-one. The test
rejects freq_idx > freq_array_len - 1 but the message says "choose a
value from 0 to %d" with freq_array_len. Since the line is being
rewritten anyway, print freq_array_len - 1.
Patch 5/6 power: support automatic detection of uncore driver
Error: resource leak in power_uncore_probe_driver().
ret = ops->init(0, 0);
if (ret == 0) {
uint32_t env = power_uncore_driver_name2env(ops->name);
if (env == UINT32_MAX)
continue;
...
ops->exit(0, 0);
On the env == UINT32_MAX path the driver has already been initialized
successfully but ops->exit(0, 0) is never called before moving to the
next driver. For intel_uncore that leaves f_cur_min and f_cur_max open
and the original min/max frequencies never written back. Restructure so
exit() runs on every successful init:
ret = ops->init(0, 0);
if (ret != 0)
continue;
env = power_uncore_driver_name2env(ops->name);
ops->exit(0, 0);
if (env == UINT32_MAX)
continue;
global_uncore_env = env;
global_uncore_ops = ops;
break;
Not reachable with the two in-tree drivers, since both "intel-uncore"
and "amd-hsmp" are in uncore_env_str, but the branch is deliberate and
is wrong as written.
Error: function return type must be on its own line.
static uint32_t power_uncore_driver_name2env(char *name)
static int power_uncore_probe_driver(void)
should be
static uint32_t
power_uncore_driver_name2env(const char *name)
static int
power_uncore_probe_driver(void)
The parameter should also be const char *; ops->name is only read.
Warning: the release note is filed under "New Features" but the commit
carries Fixes: and Cc: stable@dpdk.org. Pick one. Either this is a
backportable fix, in which case drop the New Features entry, or it is a
feature, in which case drop Fixes and Cc: stable. As written the stable
maintainers receive a patch that advertises itself as a new feature.
Info: the AUTO_DETECT path now returns -ENODEV while every other error
path in rte_power_set_uncore_env() returns -1. Not wrong, but the error
convention is now inconsistent within one function.
Patch 6/6 power: remove unused auto-detection uncore
Warning: behaviour change to an exported stable symbol with no release
note. Previously rte_power_uncore_init() fell back to auto-detection
when no environment had been set; it now returns -1 with "Please set
uncore environment first." Applications relying on the implicit
fallback break at runtime with no build-time signal. Add a release note
describing the new requirement.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v4 0/6] power: uncore power improvements and auto-detection
2026-08-10 16:21 ` Stephen Hemminger
@ 2026-08-11 12:33 ` lihuisong (C)
0 siblings, 0 replies; 10+ messages in thread
From: lihuisong (C) @ 2026-08-11 12:33 UTC (permalink / raw)
To: Stephen Hemminger
Cc: anatoly.burakov, sivaprasad.tummala, dev, thomas, fengchengwen,
yangxingui, zhanjie9
On 8/11/2026 12:21 AM, Stephen Hemminger wrote:
> On Wed, 29 Jul 2026 10:51:43 +0800
> Huisong Li <lihuisong@huawei.com> wrote:
>
>> This series improves the uncore power management in l3fwd-power
>> and adds automatic detection of uncore drivers in the power library.
>>
>> - Fix uncore deinitialization for non-legacy modes.
>> - Enable power QoS for all modes (not just legacy).
>> - Fix uncore help text and log messages.
>> - Relocate uncore initialization from arg parsing to init_power_library().
>> - Support automatic probing of uncore drivers in AUTO_DETECT and delete
>> useless code for auto-detection uncore environment.
>>
>> ---
>> v4:
>> - Fix '!global_uncore_ops' to 'global_uncore_ops == NULL' from AI review.
>> v3 link:
>> https://inbox.dpdk.org/dev/20260728120208.1858832-1-lihuisong@huawei.com/
>>
>> v3:
>> - update feature to release_26_11.rst.
>> - add a new patch to delte useless for automatic detection environment.
>> v2 link:
>> https://inbox.dpdk.org/dev/20260526081138.1434947-1-lihuisong@huawei.com/
>>
>> v2:
>> - Remove the patch which add global uncore init and deinit interface.
>> - Remove the last patch in l3fwd-power about these new interface.
>> Will send them after this series.
>> v1 link:
>> https://inbox.dpdk.org/dev/20260512023513.460169-1-lihuisong@huawei.com/
>>
>> Huisong Li (6):
>> examples/l3fwd-power: fix uncore deinit for non-legacy
>> examples/l3fwd-power: enable power QoS for all modes
>> examples/l3fwd-power: fix uncore help and log info
>> examples/l3fwd-power: relocate uncore initialization
>> power: support automatic detection of uncore driver
>> power: remove unused auto-detection uncore
>>
>> doc/guides/rel_notes/release_26_11.rst | 6 +
>> .../sample_app_ug/l3_forward_power_man.rst | 2 +-
>> examples/l3fwd-power/main.c | 256 +++++++++---------
>> lib/power/rte_power_uncore.c | 78 +++---
>> 4 files changed, 185 insertions(+), 157 deletions(-)
>>
> Most of the developers are off enjoying summer vacation.
> But AI is still around and finds some things here:
> Note: some of what it complains about is noise.
Understand.
Thanks for AI review.
Will pick up some to fix.
>
> Applied to main (26.11-rc0) and reviewed against source. Applies cleanly.
>
> Note on check-git-log: it reports "Wrong 'Fixes' reference" for both
> tags. That is a shallow-clone artifact. Both references are correct
> against full history:
> 10db2a5b8724 ("examples/l3fwd-power: add options for uncore frequency")
> 3b3af56d3c9c ("power: fix uncore configuration")
>
>
> Patch 4/6 examples/l3fwd-power: relocate uncore initialization
>
> Warning: new file-scope variable g_uncore_cfg is neither static nor
> prefixed. It is used only in main.c. Make it static and drop the g_
> prefix, which is not DPDK style.
>
> static struct uncore_cfg {
> enum uncore_choice uncore_choice;
> uint32_t freq_idx;
> } uncore_cfg;
>
> Info: the out-of-range message carries over an off-by-one. The test
> rejects freq_idx > freq_array_len - 1 but the message says "choose a
> value from 0 to %d" with freq_array_len. Since the line is being
> rewritten anyway, print freq_array_len - 1.
>
>
> Patch 5/6 power: support automatic detection of uncore driver
>
> Error: resource leak in power_uncore_probe_driver().
>
> ret = ops->init(0, 0);
> if (ret == 0) {
> uint32_t env = power_uncore_driver_name2env(ops->name);
> if (env == UINT32_MAX)
> continue;
> ...
> ops->exit(0, 0);
>
> On the env == UINT32_MAX path the driver has already been initialized
> successfully but ops->exit(0, 0) is never called before moving to the
> next driver. For intel_uncore that leaves f_cur_min and f_cur_max open
> and the original min/max frequencies never written back. Restructure so
> exit() runs on every successful init:
>
> ret = ops->init(0, 0);
> if (ret != 0)
> continue;
> env = power_uncore_driver_name2env(ops->name);
> ops->exit(0, 0);
> if (env == UINT32_MAX)
> continue;
> global_uncore_env = env;
> global_uncore_ops = ops;
> break;
>
> Not reachable with the two in-tree drivers, since both "intel-uncore"
> and "amd-hsmp" are in uncore_env_str, but the branch is deliberate and
> is wrong as written.
>
> Error: function return type must be on its own line.
>
> static uint32_t power_uncore_driver_name2env(char *name)
> static int power_uncore_probe_driver(void)
>
> should be
>
> static uint32_t
> power_uncore_driver_name2env(const char *name)
>
> static int
> power_uncore_probe_driver(void)
>
> The parameter should also be const char *; ops->name is only read.
>
> Warning: the release note is filed under "New Features" but the commit
> carries Fixes: and Cc: stable@dpdk.org. Pick one. Either this is a
> backportable fix, in which case drop the New Features entry, or it is a
> feature, in which case drop Fixes and Cc: stable. As written the stable
> maintainers receive a patch that advertises itself as a new feature.
>
> Info: the AUTO_DETECT path now returns -ENODEV while every other error
> path in rte_power_set_uncore_env() returns -1. Not wrong, but the error
> convention is now inconsistent within one function.
>
>
> Patch 6/6 power: remove unused auto-detection uncore
>
> Warning: behaviour change to an exported stable symbol with no release
> note. Previously rte_power_uncore_init() fell back to auto-detection
> when no environment had been set; it now returns -1 with "Please set
> uncore environment first." Applications relying on the implicit
> fallback break at runtime with no build-time signal. Add a release note
> describing the new requirement.
^ permalink raw reply [flat|nested] 10+ messages in thread