DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/6] power: uncore power improvements and auto-detection
@ 2026-08-12  9:49 Huisong Li
  2026-08-12  9:49 ` [PATCH v5 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 UTC (permalink / raw)
  To: anatoly.burakov, sivaprasad.tummala
  Cc: dev, thomas, stephen, fengchengwen, yangxingui, zhanjie9,
	lihuisong

- 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.

Note:
There are still some power state rollback issues that haven't been
addressed, but they were originally present and are relatively trivial to
implement. These rollbacks will be handled after this patchset.

---
 v5:
 - Fix some comments from AI in patch 4/6 and 5/6.
 v4 link:
  https://inbox.dpdk.org/dev/20260729025149.2158868-1-lihuisong@huawei.com/

 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                  |  81 +++---
 4 files changed, 188 insertions(+), 157 deletions(-)

-- 
2.33.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v5 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
@ 2026-08-12  9:49 ` Huisong Li
  2026-08-12  9:49 ` [PATCH v5 2/6] examples/l3fwd-power: enable power QoS for all modes Huisong Li
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 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] 8+ messages in thread

* [PATCH v5 2/6] examples/l3fwd-power: enable power QoS for all modes
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
  2026-08-12  9:49 ` [PATCH v5 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
@ 2026-08-12  9:49 ` Huisong Li
  2026-08-12  9:49 ` [PATCH v5 3/6] examples/l3fwd-power: fix uncore help and log info Huisong Li
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 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] 8+ messages in thread

* [PATCH v5 3/6] examples/l3fwd-power: fix uncore help and log info
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
  2026-08-12  9:49 ` [PATCH v5 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
  2026-08-12  9:49 ` [PATCH v5 2/6] examples/l3fwd-power: enable power QoS for all modes Huisong Li
@ 2026-08-12  9:49 ` Huisong Li
  2026-08-12  9:49 ` [PATCH v5 4/6] examples/l3fwd-power: relocate uncore initialization Huisong Li
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 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] 8+ messages in thread

* [PATCH v5 4/6] examples/l3fwd-power: relocate uncore initialization
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
                   ` (2 preceding siblings ...)
  2026-08-12  9:49 ` [PATCH v5 3/6] examples/l3fwd-power: fix uncore help and log info Huisong Li
@ 2026-08-12  9:49 ` Huisong Li
  2026-08-12  9:49 ` [PATCH v5 5/6] power: support automatic detection of uncore driver Huisong Li
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 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..5b4cb9f210 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;
+static struct uncore_cfg {
+	enum uncore_choice uncore_choice;
+	uint32_t freq_idx;
+} 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;
+			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;
+			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, &uncore_cfg.freq_idx) != 0) {
+				RTE_LOG(INFO, L3FWD_POWER, "Index given is not a valid number.");
 				print_usage(prgname);
 				return -1;
 			}
+			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 (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 (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 (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 (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 - 1);
+					return -1;
+				}
+				ret = rte_power_set_uncore_freq(pkg, die, 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] 8+ messages in thread

* [PATCH v5 5/6] power: support automatic detection of uncore driver
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
                   ` (3 preceding siblings ...)
  2026-08-12  9:49 ` [PATCH v5 4/6] examples/l3fwd-power: relocate uncore initialization Huisong Li
@ 2026-08-12  9:49 ` Huisong Li
  2026-08-12  9:49 ` [PATCH v5 6/6] power: remove unused auto-detection uncore Huisong Li
  2026-10-13 12:16 ` [PATCH v5 0/6] power: uncore power improvements and auto-detection Thomas Monjalon
  6 siblings, 0 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 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.

Signed-off-by: Huisong Li <lihuisong@huawei.com>
---
 doc/guides/rel_notes/release_26_11.rst |  6 ++++
 lib/power/rte_power_uncore.c           | 49 ++++++++++++++++++++++----
 2 files changed, 49 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..c50ff8d199 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,42 @@ rte_power_register_uncore_ops(struct rte_power_uncore_ops *driver_ops)
 	return 0;
 }
 
+static uint32_t
+power_uncore_driver_name2env(const 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;
+	uint32_t env;
+	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) {
+			ops->exit(0, 0);
+			env = power_uncore_driver_name2env(ops->name);
+			if (env == UINT32_MAX)
+				continue;
+			global_uncore_env = env;
+			global_uncore_ops = ops;
+			break;
+		}
+	}
+
+	return global_uncore_ops != NULL ? 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 +97,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] 8+ messages in thread

* [PATCH v5 6/6] power: remove unused auto-detection uncore
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
                   ` (4 preceding siblings ...)
  2026-08-12  9:49 ` [PATCH v5 5/6] power: support automatic detection of uncore driver Huisong Li
@ 2026-08-12  9:49 ` Huisong Li
  2026-10-13 12:16 ` [PATCH v5 0/6] power: uncore power improvements and auto-detection Thomas Monjalon
  6 siblings, 0 replies; 8+ messages in thread
From: Huisong Li @ 2026-08-12  9:49 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 c50ff8d199..cd2b2a51d5 100644
--- a/lib/power/rte_power_uncore.c
+++ b/lib/power/rte_power_uncore.c
@@ -143,32 +143,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] 8+ messages in thread

* Re: [PATCH v5 0/6] power: uncore power improvements and auto-detection
  2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
                   ` (5 preceding siblings ...)
  2026-08-12  9:49 ` [PATCH v5 6/6] power: remove unused auto-detection uncore Huisong Li
@ 2026-10-13 12:16 ` Thomas Monjalon
  6 siblings, 0 replies; 8+ messages in thread
From: Thomas Monjalon @ 2026-10-13 12:16 UTC (permalink / raw)
  To: Huisong Li
  Cc: anatoly.burakov, sivaprasad.tummala, dev, stephen, fengchengwen,
	yangxingui, zhanjie9

> 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

Applied, thanks.



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-10-13 12:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-12  9:49 [PATCH v5 0/6] power: uncore power improvements and auto-detection Huisong Li
2026-08-12  9:49 ` [PATCH v5 1/6] examples/l3fwd-power: fix uncore deinit for non-legacy Huisong Li
2026-08-12  9:49 ` [PATCH v5 2/6] examples/l3fwd-power: enable power QoS for all modes Huisong Li
2026-08-12  9:49 ` [PATCH v5 3/6] examples/l3fwd-power: fix uncore help and log info Huisong Li
2026-08-12  9:49 ` [PATCH v5 4/6] examples/l3fwd-power: relocate uncore initialization Huisong Li
2026-08-12  9:49 ` [PATCH v5 5/6] power: support automatic detection of uncore driver Huisong Li
2026-08-12  9:49 ` [PATCH v5 6/6] power: remove unused auto-detection uncore Huisong Li
2026-10-13 12:16 ` [PATCH v5 0/6] power: uncore power improvements and auto-detection Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox