|SUCCESS| [v2, 5/5] power: support automatic detection of uncore driver

dpdklab at iol.unh.edu dpdklab at iol.unh.edu
Tue May 26 11:44:45 CEST 2026


Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/164397

_AI Code Review_

=== Patch Review: series.patch (via Claude) ===
Review date: 2026-05-26

commit 1122aeb930 (from series.patch)
Author: Huisong Li <lihuisong at huawei.com>
Subject: [PATCH v2 1/5] examples/l3fwd-power: fix uncore deinit for non-legacy

The commit addresses missing uncore frequency deinitialization in
non-legacy modes by relocating the deinitialization logic outside
the legacy mode conditional block.

> 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;
> +			}
>  		}
>  	}

Does init_power_library() properly clean up the initialized lcore resources
when rte_power_init() fails partway through in app_mode APP_MODE_LEGACY?

If rte_power_init() fails on lcore N after successfully initializing lcores
0 through N-1, does this code return immediately without calling
rte_power_exit() on the successfully initialized lcores?

[ ... ]

> @@ -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;
> +			}
>  		}
>  	}

Does deinit_power_library() still leak uncore resources when
rte_power_exit() fails on an early lcore in APP_MODE_LEGACY?

When rte_power_exit() returns an error for lcore N, does the function
return early and skip uncore cleanup for all packages and dies?

[ ... ]

commit ba2be5bf32
Author: Huisong Li <lihuisong at huawei.com>
Subject: [PATCH v2 2/5] examples/l3fwd-power: enable power QoS for all modes

The commit enables power QoS feature for all application modes by
removing the app_mode conditional check.

[ ... ]

commit 45b6697c85
Author: Huisong Li <lihuisong at huawei.com>
Subject: [PATCH v2 3/5] examples/l3fwd-power: fix uncore help and log info

The commit corrects the help text and error messages for uncore
frequency options.

[ ... ]

commit a22634a04e
Author: Huisong Li <lihuisong at huawei.com>
Subject: [PATCH v2 4/5] examples/l3fwd-power: relocate uncore initialization

The commit moves uncore initialization from parse_args() to
init_power_library() to improve code organization.

> 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];
>  };

[ ... ]

> @@ -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;

Does this code initialize g_uncore_cfg.freq_idx anywhere before it is used
in power_uncore_init() when g_uncore_cfg.uncore_choice equals UNCORE_MIN or
UNCORE_MAX?

Does this global variable g_uncore_cfg require static initialization or is
zero-initialization sufficient to prevent use of uninitialized freq_idx?

[ ... ]

> @@ -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;
> +			}

Does power_uncore_init() leak uncore resources for previously initialized
pkg/die pairs when rte_power_uncore_init() fails on a later iteration?

In the nested loops over pkg and die, when rte_power_uncore_init() returns
an error for some die D in package P, does this code return immediately
without calling rte_power_uncore_exit() on earlier successfully initialized
pkg/die combinations?

[ ... ]

commit ff11f0105c
Author: Huisong Li <lihuisong at huawei.com>
Subject: [PATCH v2 5/5] power: support automatic detection of uncore driver

The commit adds support for automatic probing of multiple uncore drivers
when using RTE_UNCORE_PM_ENV_AUTO_DETECT.

> 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;
> +}

Does power_uncore_driver_name2env() properly handle a NULL name parameter
passed from power_uncore_probe_driver()->power_uncore_driver_name2env()?

Does this function check whether ops->name is NULL before calling strcmp()?

> +
> +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;
> +}

Does power_uncore_probe_driver() leak resources when ops->init(0, 0)
succeeds but power_uncore_driver_name2env() returns UINT32_MAX?

When env equals UINT32_MAX, does the code continue to the next ops without
calling ops->exit(0, 0) to clean up the successfully initialized driver?

[ ... ]

> @@ -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;
> +	}

Does rte_power_set_uncore_env() change behavior when
power_uncore_probe_driver() returns an error?

When power_uncore_probe_driver() fails, does this code log an error but
still proceed with ret being non-zero, potentially causing incorrect
behavior in callers expecting success?


More information about the test-report mailing list