* [PATCH v2 1/5] examples/l3fwd-power: fix uncore deinit for non-legacy
2026-05-26 8:11 [PATCH v2 0/5] uncore power improvements and auto-detection Huisong Li
@ 2026-05-26 8:11 ` Huisong Li
2026-05-26 8:11 ` [PATCH v2 2/5] examples/l3fwd-power: enable power QoS for all modes Huisong Li
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Huisong Li @ 2026-05-26 8:11 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 02ec17d799..1122aeb930 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -2271,28 +2271,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] 7+ messages in thread* [PATCH v2 2/5] examples/l3fwd-power: enable power QoS for all modes
2026-05-26 8:11 [PATCH v2 0/5] uncore power improvements and auto-detection Huisong Li
2026-05-26 8:11 ` [PATCH v2 1/5] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
@ 2026-05-26 8:11 ` Huisong Li
2026-05-26 8:11 ` [PATCH v2 3/5] examples/l3fwd-power: fix uncore help and log info Huisong Li
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Huisong Li @ 2026-05-26 8:11 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 1122aeb930..ba2be5bf32 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -2295,7 +2295,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] 7+ messages in thread* [PATCH v2 3/5] examples/l3fwd-power: fix uncore help and log info
2026-05-26 8:11 [PATCH v2 0/5] uncore power improvements and auto-detection Huisong Li
2026-05-26 8:11 ` [PATCH v2 1/5] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
2026-05-26 8:11 ` [PATCH v2 2/5] examples/l3fwd-power: enable power QoS for all modes Huisong Li
@ 2026-05-26 8:11 ` Huisong Li
2026-05-26 8:11 ` [PATCH v2 4/5] examples/l3fwd-power: relocate uncore initialization Huisong Li
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Huisong Li @ 2026-05-26 8:11 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 3271bc2154..dc882c5d77 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 ba2be5bf32..45b6697c85 100644
--- a/examples/l3fwd-power/main.c
+++ b/examples/l3fwd-power/main.c
@@ -1498,7 +1498,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,"
@@ -1582,7 +1582,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;
}
@@ -1590,7 +1590,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;
}
@@ -1611,7 +1611,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] 7+ messages in thread* [PATCH v2 4/5] examples/l3fwd-power: relocate uncore initialization
2026-05-26 8:11 [PATCH v2 0/5] uncore power improvements and auto-detection Huisong Li
` (2 preceding siblings ...)
2026-05-26 8:11 ` [PATCH v2 3/5] examples/l3fwd-power: fix uncore help and log info Huisong Li
@ 2026-05-26 8:11 ` Huisong Li
2026-05-26 8:11 ` [PATCH v2 5/5] power: support automatic detection of uncore driver Huisong Li
2026-06-10 1:33 ` [PATCH v2 0/5] uncore power improvements and auto-detection lihuisong (C)
5 siblings, 0 replies; 7+ messages in thread
From: Huisong Li @ 2026-05-26 8:11 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 45b6697c85..a22634a04e 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;
@@ -1552,80 +1556,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)
{
@@ -1793,25 +1723,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:
@@ -2264,6 +2190,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)
{
@@ -2295,6 +2293,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] 7+ messages in thread* [PATCH v2 5/5] power: support automatic detection of uncore driver
2026-05-26 8:11 [PATCH v2 0/5] uncore power improvements and auto-detection Huisong Li
` (3 preceding siblings ...)
2026-05-26 8:11 ` [PATCH v2 4/5] examples/l3fwd-power: relocate uncore initialization Huisong Li
@ 2026-05-26 8:11 ` Huisong Li
2026-06-10 1:33 ` [PATCH v2 0/5] uncore power improvements and auto-detection lihuisong (C)
5 siblings, 0 replies; 7+ messages in thread
From: Huisong Li @ 2026-05-26 8:11 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, which is not good to
application. So it is necessary to support probing for multi-uncore
drivers.
Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
doc/guides/rel_notes/release_26_07.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_07.rst b/doc/guides/rel_notes/release_26_07.rst
index f012d47a4b..14436f9d7f 100644
--- a/doc/guides/rel_notes/release_26_07.rst
+++ b/doc/guides/rel_notes/release_26_07.rst
@@ -63,6 +63,12 @@ New Features
``rte_eal_init`` and the application is responsible for probing each device,
* ``--auto-probing`` enables the initial bus probing, which is the current default behavior.
+* **Supported 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 25bdb113c5..ff11f0105c 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] 7+ messages in thread* Re: [PATCH v2 0/5] uncore power improvements and auto-detection
2026-05-26 8:11 [PATCH v2 0/5] uncore power improvements and auto-detection Huisong Li
` (4 preceding siblings ...)
2026-05-26 8:11 ` [PATCH v2 5/5] power: support automatic detection of uncore driver Huisong Li
@ 2026-06-10 1:33 ` lihuisong (C)
5 siblings, 0 replies; 7+ messages in thread
From: lihuisong (C) @ 2026-06-10 1:33 UTC (permalink / raw)
To: anatoly.burakov, sivaprasad.tummala
Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
lihuisong
Hi Sivaprasad,
Can you take a look at this series?
Currently, uncore core use intel_uncore driver by default on using
AUTO_DETECT.
This series can support automatic detection of uncore driver.
After this, user don't need modify l3fwd-power to run amd_uncore driver
on AMD platform.
/Huisong
On 5/26/2026 4:11 PM, 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 multiple uncore drivers in AUTO_DETECT
>
> ---
> 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 (5):
> 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
>
> doc/guides/rel_notes/release_26_07.rst | 6 +
> .../sample_app_ug/l3_forward_power_man.rst | 2 +-
> examples/l3fwd-power/main.c | 256 +++++++++---------
> lib/power/rte_power_uncore.c | 46 +++-
> 4 files changed, 178 insertions(+), 132 deletions(-)
>
^ permalink raw reply [flat|nested] 7+ messages in thread