diff options
Diffstat (limited to 'examples/vm_power_manager/power_manager.c')
-rw-r--r-- | examples/vm_power_manager/power_manager.c | 139 |
1 files changed, 86 insertions, 53 deletions
diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c index 35db2559..b7769c3c 100644 --- a/examples/vm_power_manager/power_manager.c +++ b/examples/vm_power_manager/power_manager.c @@ -12,20 +12,21 @@ #include <dirent.h> #include <errno.h> +#include <sys/sysinfo.h> #include <sys/types.h> #include <rte_log.h> #include <rte_power.h> #include <rte_spinlock.h> +#include "channel_manager.h" #include "power_manager.h" - -#define RTE_LOGTYPE_POWER_MANAGER RTE_LOGTYPE_USER1 +#include "oob_monitor.h" #define POWER_SCALE_CORE(DIRECTION, core_num , ret) do { \ - if (core_num >= POWER_MGR_MAX_CPUS) \ + if (core_num >= ci.core_count) \ return -1; \ - if (!(global_enabled_cpus & (1ULL << core_num))) \ + if (!(ci.cd[core_num].global_enabled_cpus)) \ return -1; \ rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); \ ret = rte_power_freq_##DIRECTION(core_num); \ @@ -36,7 +37,7 @@ int i; \ for (i = 0; core_mask; core_mask &= ~(1 << i++)) { \ if ((core_mask >> i) & 1) { \ - if (!(global_enabled_cpus & (1ULL << i))) \ + if (!(ci.cd[i].global_enabled_cpus)) \ continue; \ rte_spinlock_lock(&global_core_freq_info[i].power_sl); \ if (rte_power_freq_##DIRECTION(i) != 1) \ @@ -54,63 +55,82 @@ struct freq_info { static struct freq_info global_core_freq_info[POWER_MGR_MAX_CPUS]; -static uint64_t global_enabled_cpus; +struct core_info ci; #define SYSFS_CPU_PATH "/sys/devices/system/cpu/cpu%u/topology/core_id" -static unsigned -set_host_cpus_mask(void) +struct core_info * +get_core_info(void) { - char path[PATH_MAX]; - unsigned i; - unsigned num_cpus = 0; - - for (i = 0; i < POWER_MGR_MAX_CPUS; i++) { - snprintf(path, sizeof(path), SYSFS_CPU_PATH, i); - if (access(path, F_OK) == 0) { - global_enabled_cpus |= 1ULL << i; - num_cpus++; - } else - return num_cpus; + return &ci; +} + +int +core_info_init(void) +{ + struct core_info *ci; + int i; + + ci = get_core_info(); + + ci->core_count = get_nprocs_conf(); + ci->branch_ratio_threshold = BRANCH_RATIO_THRESHOLD; + ci->cd = malloc(ci->core_count * sizeof(struct core_details)); + if (!ci->cd) { + RTE_LOG(ERR, POWER_MANAGER, "Failed to allocate memory for core info."); + return -1; } - return num_cpus; + for (i = 0; i < ci->core_count; i++) { + ci->cd[i].global_enabled_cpus = 1; + ci->cd[i].oob_enabled = 0; + ci->cd[i].msr_fd = 0; + } + printf("%d cores in system\n", ci->core_count); + return 0; } int power_manager_init(void) { - unsigned int i, num_cpus, num_freqs; - uint64_t cpu_mask; + unsigned int i, num_cpus = 0, num_freqs = 0; int ret = 0; + struct core_info *ci; + + rte_power_set_env(PM_ENV_ACPI_CPUFREQ); - num_cpus = set_host_cpus_mask(); - if (num_cpus == 0) { - RTE_LOG(ERR, POWER_MANAGER, "Unable to detected host CPUs, please " - "ensure that sufficient privileges exist to inspect sysfs\n"); + ci = get_core_info(); + if (!ci) { + RTE_LOG(ERR, POWER_MANAGER, + "Failed to get core info!\n"); return -1; } - rte_power_set_env(PM_ENV_ACPI_CPUFREQ); - cpu_mask = global_enabled_cpus; - for (i = 0; cpu_mask; cpu_mask &= ~(1 << i++)) { - if (rte_power_init(i) < 0) - RTE_LOG(ERR, POWER_MANAGER, - "Unable to initialize power manager " - "for core %u\n", i); - num_freqs = rte_power_freqs(i, global_core_freq_info[i].freqs, + + for (i = 0; i < ci->core_count; i++) { + if (ci->cd[i].global_enabled_cpus) { + if (rte_power_init(i) < 0) + RTE_LOG(ERR, POWER_MANAGER, + "Unable to initialize power manager " + "for core %u\n", i); + num_cpus++; + num_freqs = rte_power_freqs(i, + global_core_freq_info[i].freqs, RTE_MAX_LCORE_FREQS); - if (num_freqs == 0) { - RTE_LOG(ERR, POWER_MANAGER, - "Unable to get frequency list for core %u\n", - i); - global_enabled_cpus &= ~(1 << i); - num_cpus--; - ret = -1; + if (num_freqs == 0) { + RTE_LOG(ERR, POWER_MANAGER, + "Unable to get frequency list for core %u\n", + i); + ci->cd[i].oob_enabled = 0; + ret = -1; + } + global_core_freq_info[i].num_freqs = num_freqs; + + rte_spinlock_init(&global_core_freq_info[i].power_sl); } - global_core_freq_info[i].num_freqs = num_freqs; - rte_spinlock_init(&global_core_freq_info[i].power_sl); + if (ci->cd[i].oob_enabled) + add_core_to_monitor(i); } - RTE_LOG(INFO, POWER_MANAGER, "Detected %u host CPUs , enabled core mask:" - " 0x%"PRIx64"\n", num_cpus, global_enabled_cpus); + RTE_LOG(INFO, POWER_MANAGER, "Managing %u cores out of %u available host cores\n", + num_cpus, ci->core_count); return ret; } @@ -125,7 +145,7 @@ power_manager_get_current_frequency(unsigned core_num) core_num, POWER_MGR_MAX_CPUS-1); return -1; } - if (!(global_enabled_cpus & (1ULL << core_num))) + if (!(ci.cd[core_num].global_enabled_cpus)) return 0; rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); @@ -144,15 +164,26 @@ power_manager_exit(void) { unsigned int i; int ret = 0; + struct core_info *ci; + + ci = get_core_info(); + if (!ci) { + RTE_LOG(ERR, POWER_MANAGER, + "Failed to get core info!\n"); + return -1; + } - for (i = 0; global_enabled_cpus; global_enabled_cpus &= ~(1 << i++)) { - if (rte_power_exit(i) < 0) { - RTE_LOG(ERR, POWER_MANAGER, "Unable to shutdown power manager " - "for core %u\n", i); - ret = -1; + for (i = 0; i < ci->core_count; i++) { + if (ci->cd[i].global_enabled_cpus) { + if (rte_power_exit(i) < 0) { + RTE_LOG(ERR, POWER_MANAGER, "Unable to shutdown power manager " + "for core %u\n", i); + ret = -1; + } + ci->cd[i].global_enabled_cpus = 0; } + remove_core_from_monitor(i); } - global_enabled_cpus = 0; return ret; } @@ -268,10 +299,12 @@ int power_manager_scale_core_med(unsigned int core_num) { int ret = 0; + struct core_info *ci; + ci = get_core_info(); if (core_num >= POWER_MGR_MAX_CPUS) return -1; - if (!(global_enabled_cpus & (1ULL << core_num))) + if (!(ci->cd[core_num].global_enabled_cpus)) return -1; rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); ret = rte_power_set_freq(core_num, |