From ff3018e2ffc9660ddd9770657dbf491442a34c7a Mon Sep 17 00:00:00 2001 From: Sivaprasad Tummala Date: Fri, 18 Oct 2024 03:34:34 +0000 Subject: [PATCH] power: fix mapped lcore ID [ upstream commit 5c9b07eeba55d527025f1f4945e2dbb366f21215 ] This commit fixes an issue in the power library related to using lcores mapped to different physical cores (--lcores option in EAL). Previously, the power library incorrectly accessed CPU sysfs attributes for power management, treating lcore IDs as CPU IDs. e.g. with --lcores '1@128', lcore_id '1' was interpreted as CPU_id instead of '128'. This patch corrects the cpu_id based on lcore and CPU mappings. It also constraints power management support for lcores mapped to multiple physical cores/threads. When multiple lcores are mapped to the same physical core, invoking frequency scaling APIs on any lcore will apply the changes effectively. Fixes: 53e54bf81700 ("eal: new option --lcores for cpu assignment") Signed-off-by: Sivaprasad Tummala Acked-by: Konstantin Ananyev Acked-by: Huisong Li --- app/test/test_power_cpufreq.c | 21 ++++++++++++++++++--- lib/power/power_acpi_cpufreq.c | 6 +++++- lib/power/power_amd_pstate_cpufreq.c | 6 +++++- lib/power/power_common.c | 22 ++++++++++++++++++++++ lib/power/power_common.h | 1 + lib/power/power_cppc_cpufreq.c | 6 +++++- lib/power/power_pstate_cpufreq.c | 6 +++++- 7 files changed, 61 insertions(+), 7 deletions(-) diff --git a/app/test/test_power_cpufreq.c b/app/test/test_power_cpufreq.c index 619b2811c6..edbd34424e 100644 --- a/app/test/test_power_cpufreq.c +++ b/app/test/test_power_cpufreq.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "test.h" @@ -46,9 +47,10 @@ test_power_caps(void) static uint32_t total_freq_num; static uint32_t freqs[TEST_POWER_FREQS_NUM_MAX]; +static uint32_t cpu_id; static int -check_cur_freq(unsigned int lcore_id, uint32_t idx, bool turbo) +check_cur_freq(__rte_unused unsigned int lcore_id, uint32_t idx, bool turbo) { #define TEST_POWER_CONVERT_TO_DECIMAL 10 #define MAX_LOOP 100 @@ -62,13 +64,13 @@ check_cur_freq(unsigned int lcore_id, uint32_t idx, bool turbo) int i; if (snprintf(fullpath, sizeof(fullpath), - TEST_POWER_SYSFILE_CPUINFO_FREQ, lcore_id) < 0) { + TEST_POWER_SYSFILE_CPUINFO_FREQ, cpu_id) < 0) { return 0; } f = fopen(fullpath, "r"); if (f == NULL) { if (snprintf(fullpath, sizeof(fullpath), - TEST_POWER_SYSFILE_SCALING_FREQ, lcore_id) < 0) { + TEST_POWER_SYSFILE_SCALING_FREQ, cpu_id) < 0) { return 0; } f = fopen(fullpath, "r"); @@ -497,6 +499,19 @@ test_power_cpufreq(void) { int ret = -1; enum power_management_env env; + rte_cpuset_t lcore_cpus; + + lcore_cpus = rte_lcore_cpuset(TEST_POWER_LCORE_ID); + if (CPU_COUNT(&lcore_cpus) != 1) { + printf("Power management doesn't support lcore %u mapping to %u CPUs\n", + TEST_POWER_LCORE_ID, + CPU_COUNT(&lcore_cpus)); + return TEST_SKIPPED; + } + for (cpu_id = 0; cpu_id < CPU_SETSIZE; cpu_id++) { + if (CPU_ISSET(cpu_id, &lcore_cpus)) + break; + } /* Test initialisation of a valid lcore */ ret = rte_power_init(TEST_POWER_LCORE_ID); diff --git a/lib/power/power_acpi_cpufreq.c b/lib/power/power_acpi_cpufreq.c index 8b55f19247..d860a12a8c 100644 --- a/lib/power/power_acpi_cpufreq.c +++ b/lib/power/power_acpi_cpufreq.c @@ -258,7 +258,11 @@ power_acpi_cpufreq_init(unsigned int lcore_id) return -1; } - pi->lcore_id = lcore_id; + if (power_get_lcore_mapped_cpu_id(lcore_id, &pi->lcore_id) < 0) { + RTE_LOG(ERR, POWER, "Cannot get CPU ID mapped for lcore %u\n", lcore_id); + return -1; + } + /* Check and set the governor */ if (power_set_governor_userspace(pi) < 0) { RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to " diff --git a/lib/power/power_amd_pstate_cpufreq.c b/lib/power/power_amd_pstate_cpufreq.c index dbd9d2b3ee..7b8e77003f 100644 --- a/lib/power/power_amd_pstate_cpufreq.c +++ b/lib/power/power_amd_pstate_cpufreq.c @@ -376,7 +376,11 @@ power_amd_pstate_cpufreq_init(unsigned int lcore_id) return -1; } - pi->lcore_id = lcore_id; + if (power_get_lcore_mapped_cpu_id(lcore_id, &pi->lcore_id) < 0) { + RTE_LOG(ERR, POWER, "Cannot get CPU ID mapped for lcore %u", lcore_id); + return -1; + } + /* Check and set the governor */ if (power_set_governor_userspace(pi) < 0) { RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to " diff --git a/lib/power/power_common.c b/lib/power/power_common.c index 1e09facb86..8ffb49ef8f 100644 --- a/lib/power/power_common.c +++ b/lib/power/power_common.c @@ -9,6 +9,7 @@ #include #include +#include #include "power_common.h" @@ -202,3 +203,24 @@ power_set_governor(unsigned int lcore_id, const char *new_governor, return ret; } + +int power_get_lcore_mapped_cpu_id(uint32_t lcore_id, uint32_t *cpu_id) +{ + rte_cpuset_t lcore_cpus; + uint32_t cpu; + + lcore_cpus = rte_lcore_cpuset(lcore_id); + if (CPU_COUNT(&lcore_cpus) != 1) { + RTE_LOG(ERR, POWER, "Power library does not support lcore %u mapping to %u CPUs", lcore_id, + CPU_COUNT(&lcore_cpus)); + return -1; + } + + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (CPU_ISSET(cpu, &lcore_cpus)) + break; + } + *cpu_id = cpu; + + return 0; +} diff --git a/lib/power/power_common.h b/lib/power/power_common.h index c1c7139276..b928df941f 100644 --- a/lib/power/power_common.h +++ b/lib/power/power_common.h @@ -27,5 +27,6 @@ int open_core_sysfs_file(FILE **f, const char *mode, const char *format, ...) int read_core_sysfs_u32(FILE *f, uint32_t *val); int read_core_sysfs_s(FILE *f, char *buf, unsigned int len); int write_core_sysfs_s(FILE *f, const char *str); +int power_get_lcore_mapped_cpu_id(uint32_t lcore_id, uint32_t *cpu_id); #endif /* _POWER_COMMON_H_ */ diff --git a/lib/power/power_cppc_cpufreq.c b/lib/power/power_cppc_cpufreq.c index f2ba684c83..add477c804 100644 --- a/lib/power/power_cppc_cpufreq.c +++ b/lib/power/power_cppc_cpufreq.c @@ -362,7 +362,11 @@ power_cppc_cpufreq_init(unsigned int lcore_id) return -1; } - pi->lcore_id = lcore_id; + if (power_get_lcore_mapped_cpu_id(lcore_id, &pi->lcore_id) < 0) { + RTE_LOG(ERR, POWER, "Cannot get CPU ID mapped for lcore %u\n", lcore_id); + return -1; + } + /* Check and set the governor */ if (power_set_governor_userspace(pi) < 0) { RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to " diff --git a/lib/power/power_pstate_cpufreq.c b/lib/power/power_pstate_cpufreq.c index 5ca5f60bcd..890875bd93 100644 --- a/lib/power/power_pstate_cpufreq.c +++ b/lib/power/power_pstate_cpufreq.c @@ -564,7 +564,11 @@ power_pstate_cpufreq_init(unsigned int lcore_id) return -1; } - pi->lcore_id = lcore_id; + if (power_get_lcore_mapped_cpu_id(lcore_id, &pi->lcore_id) < 0) { + RTE_LOG(ERR, POWER, "Cannot get CPU ID mapped for lcore %u", lcore_id); + return -1; + } + /* Check and set the governor */ if (power_set_governor_performance(pi) < 0) { RTE_LOG(ERR, POWER, "Cannot set governor of lcore %u to "