X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=lib%2Flibrte_power%2Fpower_pstate_cpufreq.c;h=e3126d3754ea720a630b7705cea345201c910334;hb=0f9ac2afa62ebacd24f36a3b98272b7146be3edd;hp=ecbcb3ac99528409a7cf23c4adea7ed24a2aeb3f;hpb=7727ad9107137ee3f4dea212ad77e35cd4f3e6bc;p=dpdk.git diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c index ecbcb3ac99..e3126d3754 100644 --- a/lib/librte_power/power_pstate_cpufreq.c +++ b/lib/librte_power/power_pstate_cpufreq.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -33,7 +32,7 @@ #define FOPEN_OR_ERR_RET(f, retval) do { \ if ((f) == NULL) { \ - RTE_LOG(ERR, POWER, "File not openned\n"); \ + RTE_LOG(ERR, POWER, "File not opened\n"); \ return retval; \ } \ } while (0) @@ -71,6 +70,7 @@ "/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_min_freq" #define POWER_SYSFILE_BASE_FREQ \ "/sys/devices/system/cpu/cpu%u/cpufreq/base_frequency" +#define POWER_PSTATE_DRIVER "intel_pstate" #define POWER_MSR_PATH "/dev/cpu/%u/msr" /* @@ -99,7 +99,7 @@ struct pstate_power_info { uint32_t non_turbo_max_ratio; /**< Non Turbo Max ratio */ uint32_t sys_max_freq; /**< system wide max freq */ uint32_t core_base_freq; /**< core base freq */ - volatile uint32_t state; /**< Power in use state */ + uint32_t state; /**< Power in use state */ uint16_t turbo_available; /**< Turbo Boost available */ uint16_t turbo_enable; /**< Turbo Boost enable/disable */ uint16_t priority_core; /**< High Performance core */ @@ -287,7 +287,7 @@ set_freq_internal(struct pstate_power_info *pi, uint32_t idx) return -1; } - POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n", + POWER_DEBUG_TRACE("Frequency '%u' to be set for lcore %u\n", target_freq, pi->lcore_id); fflush(pi->f_cur_min); @@ -310,7 +310,7 @@ set_freq_internal(struct pstate_power_info *pi, uint32_t idx) return -1; } - POWER_DEBUG_TRACE("Freqency '%u' to be set for lcore %u\n", + POWER_DEBUG_TRACE("Frequency '%u' to be set for lcore %u\n", target_freq, pi->lcore_id); fflush(pi->f_cur_max); @@ -531,10 +531,17 @@ out: return ret; } +int +power_pstate_cpufreq_check_supported(void) +{ + return cpufreq_check_scaling_driver(POWER_PSTATE_DRIVER); +} + int power_pstate_cpufreq_init(unsigned int lcore_id) { struct pstate_power_info *pi; + uint32_t exp_state; if (lcore_id >= RTE_MAX_LCORE) { RTE_LOG(ERR, POWER, "Lcore id %u can not exceed %u\n", @@ -543,8 +550,16 @@ power_pstate_cpufreq_init(unsigned int lcore_id) } pi = &lcore_power_info[lcore_id]; - if (rte_atomic32_cmpset(&(pi->state), POWER_IDLE, POWER_ONGOING) - == 0) { + exp_state = POWER_IDLE; + /* The power in use state works as a guard variable between + * the CPU frequency control initialization and exit process. + * The ACQUIRE memory ordering here pairs with the RELEASE + * ordering below as lock to make sure the frequency operations + * in the critical section are done under the correct state. + */ + if (!__atomic_compare_exchange_n(&(pi->state), &exp_state, + POWER_ONGOING, 0, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { RTE_LOG(INFO, POWER, "Power management of lcore %u is " "in use\n", lcore_id); return -1; @@ -581,12 +596,16 @@ power_pstate_cpufreq_init(unsigned int lcore_id) RTE_LOG(INFO, POWER, "Initialized successfully for lcore %u " "power management\n", lcore_id); - rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_USED); + exp_state = POWER_ONGOING; + __atomic_compare_exchange_n(&(pi->state), &exp_state, POWER_USED, + 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED); return 0; fail: - rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN); + exp_state = POWER_ONGOING; + __atomic_compare_exchange_n(&(pi->state), &exp_state, POWER_UNKNOWN, + 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED); return -1; } @@ -595,6 +614,7 @@ int power_pstate_cpufreq_exit(unsigned int lcore_id) { struct pstate_power_info *pi; + uint32_t exp_state; if (lcore_id >= RTE_MAX_LCORE) { RTE_LOG(ERR, POWER, "Lcore id %u can not exceeds %u\n", @@ -603,8 +623,16 @@ power_pstate_cpufreq_exit(unsigned int lcore_id) } pi = &lcore_power_info[lcore_id]; - if (rte_atomic32_cmpset(&(pi->state), POWER_USED, POWER_ONGOING) - == 0) { + exp_state = POWER_USED; + /* The power in use state works as a guard variable between + * the CPU frequency control initialization and exit process. + * The ACQUIRE memory ordering here pairs with the RELEASE + * ordering below as lock to make sure the frequency operations + * in the critical section are under done the correct state. + */ + if (!__atomic_compare_exchange_n(&(pi->state), &exp_state, + POWER_ONGOING, 0, + __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { RTE_LOG(INFO, POWER, "Power management of lcore %u is " "not used\n", lcore_id); return -1; @@ -626,12 +654,16 @@ power_pstate_cpufreq_exit(unsigned int lcore_id) RTE_LOG(INFO, POWER, "Power management of lcore %u has exited from " "'performance' mode and been set back to the " "original\n", lcore_id); - rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_IDLE); + exp_state = POWER_ONGOING; + __atomic_compare_exchange_n(&(pi->state), &exp_state, POWER_IDLE, + 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED); return 0; fail: - rte_atomic32_cmpset(&(pi->state), POWER_ONGOING, POWER_UNKNOWN); + exp_state = POWER_ONGOING; + __atomic_compare_exchange_n(&(pi->state), &exp_state, POWER_UNKNOWN, + 0, __ATOMIC_RELEASE, __ATOMIC_RELAXED); return -1; } @@ -696,7 +728,8 @@ power_pstate_cpufreq_freq_up(unsigned int lcore_id) } pi = &lcore_power_info[lcore_id]; - if (pi->curr_idx == 0) + if (pi->curr_idx == 0 || + (pi->curr_idx == 1 && pi->turbo_available && !pi->turbo_enable)) return 0; /* Frequencies in the array are from high to low. */