From 7fe2f6399a84760a9af8896ac152728250f82adb Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Wed, 30 Mar 2011 16:30:11 +0200 Subject: cpupowerutils - cpufrequtils extended with quite some features CPU power consumption vs performance tuning is no longer limited to CPU frequency switching anymore: deep sleep states, traditional dynamic frequency scaling and hidden turbo/boost frequencies are tied close together and depend on each other. The first two exist on different architectures like PPC, Itanium and ARM, the latter (so far) only on X86. On X86 the APU (CPU+GPU) will only run most efficiently if CPU and GPU has proper power management in place. Users and Developers want to have *one* tool to get an overview what their system supports and to monitor and debug CPU power management in detail. The tool should compile and work on as many architectures as possible. Once this tool stabilizes a bit, it is intended to replace the Intel-specific tools in tools/power/x86 Signed-off-by: Dominik Brodowski --- tools/power/cpupower/utils/helpers/misc.c | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tools/power/cpupower/utils/helpers/misc.c (limited to 'tools/power/cpupower/utils/helpers/misc.c') diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c new file mode 100644 index 000000000000..c1566e93e0ec --- /dev/null +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -0,0 +1,34 @@ +#if defined(__i386__) || defined(__x86_64__) + +#include "helpers/helpers.h" + +int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, int * states) +{ + struct cpupower_cpu_info cpu_info; + int ret; + + *support = *active = *states = 0; + + ret = get_cpu_info(0, &cpu_info); + if (ret) + return ret; + + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CBP) { + *support = 1; + amd_pci_get_num_boost_states(active, states); + if (ret <= 0) + return ret; + *support = 1; + } else if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) { + ret = msr_intel_has_boost_support(cpu); + if (ret <= 0) + return ret; + *support = ret; + ret = msr_intel_boost_is_active(cpu); + if (ret <= 0) + return ret; + *active = ret; + } + return 0; +} +#endif /* #if defined(__i386__) || defined(__x86_64__) */ -- cgit v1.2.3 From 2cd005cac6d586b8ca324814a9c58ed0c08ffe40 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Tue, 19 Apr 2011 20:16:05 +0200 Subject: cpupowerutils: helpers - ConfigStyle bugfixes Signed-off-by: Dominik Brodowski --- tools/power/cpupower/utils/helpers/amd.c | 8 +- tools/power/cpupower/utils/helpers/bitmask.c | 12 +-- tools/power/cpupower/utils/helpers/cpuid.c | 14 ++-- tools/power/cpupower/utils/helpers/helpers.h | 6 +- tools/power/cpupower/utils/helpers/misc.c | 3 +- tools/power/cpupower/utils/helpers/pci.c | 2 +- tools/power/cpupower/utils/helpers/sysfs.c | 112 ++++++++++++++------------ tools/power/cpupower/utils/helpers/sysfs.h | 23 +++--- tools/power/cpupower/utils/helpers/topology.c | 6 +- 9 files changed, 100 insertions(+), 86 deletions(-) (limited to 'tools/power/cpupower/utils/helpers/misc.c') diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 5e44e31fc7f9..87d5605bdda8 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -53,8 +53,8 @@ static int get_cof(int family, union msr_pstate pstate) if (family == 0x11) t = 0x8; - return ((100 * (fid + t)) >> did); - } + return (100 * (fid + t)) >> did; +} /* Needs: * cpu -> the cpu that gets evaluated @@ -74,7 +74,7 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, { int i, psmax, pscur; union msr_pstate pstate; - unsigned long long val; + unsigned long long val; /* Only read out frequencies from HW when CPU might be boostable to keep the code as short and clean as possible. @@ -95,7 +95,7 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, pscur += boost_states; psmax += boost_states; - for (i=0; i<=psmax; i++) { + for (i = 0; i <= psmax; i++) { if (i >= MAX_HW_PSTATES) { fprintf(stderr, "HW pstates [%d] exceeding max [%d]\n", psmax, MAX_HW_PSTATES); diff --git a/tools/power/cpupower/utils/helpers/bitmask.c b/tools/power/cpupower/utils/helpers/bitmask.c index 60f4d69bb20d..5c074c60f904 100644 --- a/tools/power/cpupower/utils/helpers/bitmask.c +++ b/tools/power/cpupower/utils/helpers/bitmask.c @@ -8,12 +8,12 @@ #define bitsperlong (8 * sizeof(unsigned long)) /* howmany(a,b) : how many elements of size b needed to hold all of a */ -#define howmany(x,y) (((x)+((y)-1))/(y)) +#define howmany(x, y) (((x)+((y)-1))/(y)) /* How many longs in mask of n bits */ #define longsperbits(n) howmany(n, bitsperlong) -#define max(a,b) ((a) > (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) /* * Allocate and free `struct bitmask *` @@ -73,7 +73,8 @@ static void _setbit(struct bitmask *bmp, unsigned int n, unsigned int v) if (v) bmp->maskp[n/bitsperlong] |= 1UL << (n % bitsperlong); else - bmp->maskp[n/bitsperlong] &= ~(1UL << (n % bitsperlong)); + bmp->maskp[n/bitsperlong] &= + ~(1UL << (n % bitsperlong)); } } @@ -185,7 +186,7 @@ unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i) * 0-3 0,1,2,3 * 0-7:2 0,2,4,6 * 1,3,5-7 1,3,5,6,7 - * 0-3:2,8-15:4 0,2,8,12 + * 0-3:2,8-15:4 0,2,8,12 */ int bitmask_parselist(const char *buf, struct bitmask *bmp) { @@ -251,7 +252,8 @@ static inline int emit(char *buf, int buflen, int rbot, int rtop, int len) if (rbot == rtop) len += snprintf(buf + len, max(buflen - len, 0), "%d", rbot); else - len += snprintf(buf + len, max(buflen - len, 0), "%d-%d", rbot, rtop); + len += snprintf(buf + len, max(buflen - len, 0), "%d-%d", + rbot, rtop); return len; } diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index 71021f3bb69d..944b2c1659d8 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -67,28 +67,26 @@ int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info) continue; value[63 - 1] = '\0'; - if (!strncmp(value, "processor\t: ", 12)) { + if (!strncmp(value, "processor\t: ", 12)) sscanf(value, "processor\t: %u", &proc); - } + if (proc != cpu) continue; /* Get CPU vendor */ - if (!strncmp(value, "vendor_id", 9)) + if (!strncmp(value, "vendor_id", 9)) { for (x = 1; x < X86_VENDOR_MAX; x++) { if (strstr(value, cpu_vendor_table[x])) cpu_info->vendor = x; } /* Get CPU family, etc. */ - else if (!strncmp(value, "cpu family\t: ", 13)) { + } else if (!strncmp(value, "cpu family\t: ", 13)) { sscanf(value, "cpu family\t: %u", &cpu_info->family); - } - else if (!strncmp(value, "model\t\t: ", 9)) { + } else if (!strncmp(value, "model\t\t: ", 9)) { sscanf(value, "model\t\t: %u", &cpu_info->model); - } - else if (!strncmp(value, "stepping\t: ", 10)) { + } else if (!strncmp(value, "stepping\t: ", 10)) { sscanf(value, "stepping\t: %u", &cpu_info->stepping); diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index a487dadb4cf0..048f065925c9 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -20,7 +20,7 @@ #ifndef gettext_noop #define gettext_noop(String) String #endif -#define N_(String) gettext_noop (String) +#define N_(String) gettext_noop(String) /* Internationalization ****************************/ extern int run_as_root; @@ -39,11 +39,11 @@ extern int be_verbose; #define dprint(fmt, ...) { \ if (be_verbose) { \ fprintf(stderr, "%s: " fmt, \ - __FUNCTION__, ##__VA_ARGS__); \ + __func__, ##__VA_ARGS__); \ } \ } #else -static inline void dprint(const char *fmt, ...) { } +static inline void dprint(const char *fmt, ...) { } #endif extern int be_verbose; /* Global verbose (-v) stuff *********************************/ diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index c1566e93e0ec..e8b3140cc6b8 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -2,7 +2,8 @@ #include "helpers/helpers.h" -int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, int * states) +int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, + int *states) { struct cpupower_cpu_info cpu_info; int ret; diff --git a/tools/power/cpupower/utils/helpers/pci.c b/tools/power/cpupower/utils/helpers/pci.c index 8dcc93813716..cd2eb6fe41c4 100644 --- a/tools/power/cpupower/utils/helpers/pci.c +++ b/tools/power/cpupower/utils/helpers/pci.c @@ -33,7 +33,7 @@ struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, for (i = 0; dev_ids[i] != 0; i++) { filter_nb_link.device = dev_ids[i]; - for (device=(*pacc)->devices; device; device = device->next) { + for (device = (*pacc)->devices; device; device = device->next) { if (pci_filter_match(&filter_nb_link, device)) return device; } diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c index 0c534e79652b..55e2466674c6 100644 --- a/tools/power/cpupower/utils/helpers/sysfs.c +++ b/tools/power/cpupower/utils/helpers/sysfs.c @@ -19,14 +19,14 @@ unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) { int fd; - size_t numread; + ssize_t numread; - if ( ( fd = open(path, O_RDONLY) ) == -1 ) + fd = open(path, O_RDONLY); + if (fd == -1) return 0; numread = read(fd, buf, buflen - 1); - if ( numread < 1 ) - { + if (numread < 1) { close(fd); return 0; } @@ -34,26 +34,26 @@ unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) buf[numread] = '\0'; close(fd); - return numread; + return (unsigned int) numread; } static unsigned int sysfs_write_file(const char *path, const char *value, size_t len) { int fd; - size_t numwrite; + ssize_t numwrite; - if ( ( fd = open(path, O_WRONLY) ) == -1 ) + fd = open(path, O_WRONLY); + if (fd == -1) return 0; numwrite = write(fd, value, len); - if ( numwrite < 1 ) - { + if (numwrite < 1) { close(fd); return 0; } close(fd); - return numwrite; + return (unsigned int) numwrite; } /* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ @@ -69,17 +69,17 @@ unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate, { char path[SYSFS_PATH_MAX]; int fd; - size_t numread; + ssize_t numread; snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", cpu, idlestate, fname); - if ( ( fd = open(path, O_RDONLY) ) == -1 ) + fd = open(path, O_RDONLY); + if (fd == -1) return 0; numread = read(fd, buf, buflen - 1); - if ( numread < 1 ) - { + if (numread < 1) { close(fd); return 0; } @@ -87,7 +87,7 @@ unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate, buf[numread] = '\0'; close(fd); - return numread; + return (unsigned int) numread; } /* read access to files which contain one numeric value */ @@ -116,19 +116,18 @@ static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu, char linebuf[MAX_LINE_LEN]; char *endp; - if ( which >= MAX_IDLESTATE_VALUE_FILES ) + if (which >= MAX_IDLESTATE_VALUE_FILES) return 0; - if ( ( len = sysfs_idlestate_read_file(cpu, idlestate, - idlestate_value_files[which], - linebuf, sizeof(linebuf))) == 0 ) - { + len = sysfs_idlestate_read_file(cpu, idlestate, + idlestate_value_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) return 0; - } value = strtoull(linebuf, &endp, 0); - if ( endp == linebuf || errno == ERANGE ) + if (endp == linebuf || errno == ERANGE) return 0; return value; @@ -148,9 +147,9 @@ static const char *idlestate_string_files[MAX_IDLESTATE_STRING_FILES] = { }; -static char * sysfs_idlestate_get_one_string(unsigned int cpu, - unsigned int idlestate, - enum idlestate_string which) +static char *sysfs_idlestate_get_one_string(unsigned int cpu, + unsigned int idlestate, + enum idlestate_string which) { char linebuf[MAX_LINE_LEN]; char *result; @@ -159,12 +158,14 @@ static char * sysfs_idlestate_get_one_string(unsigned int cpu, if (which >= MAX_IDLESTATE_STRING_FILES) return NULL; - if ( ( len = sysfs_idlestate_read_file(cpu, idlestate, - idlestate_string_files[which], - linebuf, sizeof(linebuf))) == 0 ) + len = sysfs_idlestate_read_file(cpu, idlestate, + idlestate_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) return NULL; - if ( ( result = strdup(linebuf) ) == NULL ) + result = strdup(linebuf); + if (result == NULL) return NULL; if (result[strlen(result) - 1] == '\n') @@ -173,27 +174,30 @@ static char * sysfs_idlestate_get_one_string(unsigned int cpu, return result; } -unsigned long sysfs_get_idlestate_latency(unsigned int cpu, unsigned int idlestate) +unsigned long sysfs_get_idlestate_latency(unsigned int cpu, + unsigned int idlestate) { return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); } -unsigned long sysfs_get_idlestate_usage(unsigned int cpu, unsigned int idlestate) +unsigned long sysfs_get_idlestate_usage(unsigned int cpu, + unsigned int idlestate) { return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_USAGE); } -unsigned long long sysfs_get_idlestate_time(unsigned int cpu, unsigned int idlestate) +unsigned long long sysfs_get_idlestate_time(unsigned int cpu, + unsigned int idlestate) { return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_TIME); } -char * sysfs_get_idlestate_name(unsigned int cpu, unsigned int idlestate) +char *sysfs_get_idlestate_name(unsigned int cpu, unsigned int idlestate) { return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_NAME); } -char * sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate) +char *sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate) { return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_DESC); } @@ -211,14 +215,14 @@ int sysfs_get_idlestate_count(unsigned int cpu) snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle"); - if ( stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) return -ENODEV; snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu); - if ( stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) return 0; - while(stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { + while (stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state%d", cpu, idlestates); idlestates++; @@ -261,7 +265,7 @@ static const char *cpuidle_string_files[MAX_CPUIDLE_STRING_FILES] = { }; -static char * sysfs_cpuidle_get_one_string(enum cpuidle_string which) +static char *sysfs_cpuidle_get_one_string(enum cpuidle_string which) { char linebuf[MAX_LINE_LEN]; char *result; @@ -270,11 +274,13 @@ static char * sysfs_cpuidle_get_one_string(enum cpuidle_string which) if (which >= MAX_CPUIDLE_STRING_FILES) return NULL; - if ( ( len = sysfs_cpuidle_read_file(cpuidle_string_files[which], - linebuf, sizeof(linebuf))) == 0 ) + len = sysfs_cpuidle_read_file(cpuidle_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) return NULL; - if ( ( result = strdup(linebuf) ) == NULL ) + result = strdup(linebuf); + if (result == NULL) return NULL; if (result[strlen(result) - 1] == '\n') @@ -283,7 +289,7 @@ static char * sysfs_cpuidle_get_one_string(enum cpuidle_string which) return result; } -char * sysfs_get_cpuidle_governor(void) +char *sysfs_get_cpuidle_governor(void) { char *tmp = sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR_RO); if (!tmp) @@ -292,7 +298,7 @@ char * sysfs_get_cpuidle_governor(void) return tmp; } -char * sysfs_get_cpuidle_driver(void) +char *sysfs_get_cpuidle_driver(void) { return sysfs_cpuidle_get_one_string(CPUIDLE_DRIVER); } @@ -304,9 +310,9 @@ char * sysfs_get_cpuidle_driver(void) * * Returns negative value on failure */ -int sysfs_get_sched(const char* smt_mc) +int sysfs_get_sched(const char *smt_mc) { - unsigned long value; + unsigned long value; char linebuf[MAX_LINE_LEN]; char *endp; char path[SYSFS_PATH_MAX]; @@ -314,11 +320,12 @@ int sysfs_get_sched(const char* smt_mc) if (strcmp("mc", smt_mc) && strcmp("smt", smt_mc)) return -EINVAL; - snprintf(path, sizeof(path), PATH_TO_CPU "sched_%s_power_savings", smt_mc); - if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0 ) + snprintf(path, sizeof(path), + PATH_TO_CPU "sched_%s_power_savings", smt_mc); + if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) return -1; value = strtoul(linebuf, &endp, 0); - if ( endp == linebuf || errno == ERANGE ) + if (endp == linebuf || errno == ERANGE) return -1; return value; } @@ -329,7 +336,7 @@ int sysfs_get_sched(const char* smt_mc) * * Returns negative value on failure */ -int sysfs_set_sched(const char* smt_mc, int val) +int sysfs_set_sched(const char *smt_mc, int val) { char linebuf[MAX_LINE_LEN]; char path[SYSFS_PATH_MAX]; @@ -338,13 +345,14 @@ int sysfs_set_sched(const char* smt_mc, int val) if (strcmp("mc", smt_mc) && strcmp("smt", smt_mc)) return -EINVAL; - snprintf(path, sizeof(path), PATH_TO_CPU "sched_%s_power_savings", smt_mc); + snprintf(path, sizeof(path), + PATH_TO_CPU "sched_%s_power_savings", smt_mc); sprintf(linebuf, "%d", val); - if ( stat(path, &statbuf) != 0 ) + if (stat(path, &statbuf) != 0) return -ENODEV; - if (sysfs_write_file(path, linebuf, MAX_LINE_LEN) == 0 ) + if (sysfs_write_file(path, linebuf, MAX_LINE_LEN) == 0) return -1; return 0; } diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h index 5d02d2fc70e1..f9373e090637 100644 --- a/tools/power/cpupower/utils/helpers/sysfs.h +++ b/tools/power/cpupower/utils/helpers/sysfs.h @@ -7,17 +7,22 @@ extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); -extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, unsigned int idlestate); -extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, unsigned int idlestate); -extern unsigned long long sysfs_get_idlestate_time(unsigned int cpu, unsigned int idlestate); -extern char * sysfs_get_idlestate_name(unsigned int cpu, unsigned int idlestate); -extern char * sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate); +extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, + unsigned int idlestate); +extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, + unsigned int idlestate); +extern unsigned long long sysfs_get_idlestate_time(unsigned int cpu, + unsigned int idlestate); +extern char *sysfs_get_idlestate_name(unsigned int cpu, + unsigned int idlestate); +extern char *sysfs_get_idlestate_desc(unsigned int cpu, + unsigned int idlestate); extern int sysfs_get_idlestate_count(unsigned int cpu); -extern char * sysfs_get_cpuidle_governor(void); -extern char * sysfs_get_cpuidle_driver(void); +extern char *sysfs_get_cpuidle_governor(void); +extern char *sysfs_get_cpuidle_driver(void); -extern int sysfs_get_sched(const char* smt_mc); -extern int sysfs_set_sched(const char* smt_mc, int val); +extern int sysfs_get_sched(const char *smt_mc); +extern int sysfs_set_sched(const char *smt_mc, int val); #endif /* __CPUPOWER_HELPERS_SYSFS_H__ */ diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c index 5ad842b956bb..385ee5c7570c 100644 --- a/tools/power/cpupower/utils/helpers/topology.c +++ b/tools/power/cpupower/utils/helpers/topology.c @@ -22,17 +22,17 @@ /* returns -1 on failure, 0 on success */ int sysfs_topology_read_file(unsigned int cpu, const char *fname) { - unsigned long value; + unsigned long value; char linebuf[MAX_LINE_LEN]; char *endp; char path[SYSFS_PATH_MAX]; snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", cpu, fname); - if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0 ) + if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) return -1; value = strtoul(linebuf, &endp, 0); - if ( endp == linebuf || errno == ERANGE ) + if (endp == linebuf || errno == ERANGE) return -1; return value; } -- cgit v1.2.3 From 029e9f73667f9b4661ac9886f706d75d26850260 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 21 Jul 2011 11:54:54 +0200 Subject: cpupower: Do detect IDA (opportunistic processor performance) via cpuid IA32-Intel Devel guide Volume 3A - 14.3.2.1 ------------------------------------------- ... Opportunistic processor performance operation can be disabled by setting bit 38 of IA32_MISC_ENABLES. This mechanism is intended for BIOS only. If IA32_MISC_ENABLES[38] is set, CPUID.06H:EAX[1] will return 0. Better detect things via cpuid, this cleans up the code a bit and the MSR parts were not working correctly anyway. Signed-off-by: Thomas Renninger CC: lenb@kernel.org CC: linux@dominikbrodowski.net CC: cpufreq@vger.kernel.org Signed-off-by: Dominik Brodowski --- tools/power/cpupower/utils/helpers/cpuid.c | 6 ++++++ tools/power/cpupower/utils/helpers/helpers.h | 9 +-------- tools/power/cpupower/utils/helpers/misc.c | 12 ++---------- tools/power/cpupower/utils/helpers/msr.c | 23 ----------------------- 4 files changed, 9 insertions(+), 41 deletions(-) (limited to 'tools/power/cpupower/utils/helpers/misc.c') diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index a97f091fcf2b..906895d21cce 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -130,6 +130,12 @@ out: cpu_info->caps |= CPUPOWER_CAP_AMD_CBP; } + if (cpu_info->vendor == X86_VENDOR_INTEL) { + if (cpuid_level >= 6 && + (cpuid_eax(6) & (1 << 1))) + cpu_info->caps |= CPUPOWER_CAP_INTEL_IDA; + } + if (cpu_info->vendor == X86_VENDOR_INTEL) { /* Intel's perf-bias MSR support */ if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3))) diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 9125a551ac1d..592ee362b877 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -58,6 +58,7 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, #define CPUPOWER_CAP_PERF_BIAS 0x00000008 #define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 #define CPUPOWER_CAP_IS_SNB 0x00000011 +#define CPUPOWER_CAP_INTEL_IDA 0x00000012 #define MAX_HW_PSTATES 10 @@ -115,9 +116,6 @@ extern int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val); extern int msr_intel_get_perf_bias(unsigned int cpu); extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu); -extern int msr_intel_has_boost_support(unsigned int cpu); -extern int msr_intel_boost_is_active(unsigned int cpu); - /* Read/Write msr ****************************/ /* PCI stuff ****************************/ @@ -163,11 +161,6 @@ static inline int msr_intel_get_perf_bias(unsigned int cpu) static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu) { return 0; }; -static inline int msr_intel_has_boost_support(unsigned int cpu) -{ return -1; }; -static inline int msr_intel_boost_is_active(unsigned int cpu) -{ return -1; }; - /* Read/Write msr ****************************/ static inline int cpufreq_has_boost_support(unsigned int cpu, int *support, diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index e8b3140cc6b8..1609243f5c64 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -20,16 +20,8 @@ int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, if (ret <= 0) return ret; *support = 1; - } else if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) { - ret = msr_intel_has_boost_support(cpu); - if (ret <= 0) - return ret; - *support = ret; - ret = msr_intel_boost_is_active(cpu); - if (ret <= 0) - return ret; - *active = ret; - } + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) + *support = *active = 1; return 0; } #endif /* #if defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c index 7869ca64dfd3..31a4b24a8bc6 100644 --- a/tools/power/cpupower/utils/helpers/msr.c +++ b/tools/power/cpupower/utils/helpers/msr.c @@ -72,29 +72,6 @@ int write_msr(int cpu, unsigned int idx, unsigned long long val) return -1; } -int msr_intel_has_boost_support(unsigned int cpu) -{ - unsigned long long misc_enables; - int ret; - - ret = read_msr(cpu, MSR_IA32_MISC_ENABLES, &misc_enables); - if (ret) - return ret; - - return (misc_enables >> 38) & 0x1; -} - -int msr_intel_boost_is_active(unsigned int cpu) -{ - unsigned long long perf_status; - int ret; - - ret = read_msr(cpu, MSR_IA32_PERF_STATUS, &perf_status); - if (ret) - return ret; - return (perf_status >> 32) & 0x1; -} - int msr_intel_get_perf_bias(unsigned int cpu) { unsigned long long val; -- cgit v1.2.3