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/helpers.h | 180 +++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 tools/power/cpupower/utils/helpers/helpers.h (limited to 'tools/power/cpupower/utils/helpers/helpers.h') diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h new file mode 100644 index 00000000000..a487dadb4cf --- /dev/null +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -0,0 +1,180 @@ +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Licensed under the terms of the GNU GPL License version 2. + * + * Miscellaneous helpers which do not fit or are worth + * to put into separate headers + */ + +#ifndef __CPUPOWERUTILS_HELPERS__ +#define __CPUPOWERUTILS_HELPERS__ + +#include +#include + +#include "helpers/bitmask.h" + +/* Internationalization ****************************/ +#define _(String) gettext(String) +#ifndef gettext_noop +#define gettext_noop(String) String +#endif +#define N_(String) gettext_noop (String) +/* Internationalization ****************************/ + +extern int run_as_root; +extern struct bitmask *cpus_chosen; + +/* Global verbose (-d) stuff *********************************/ +/* + * define DEBUG via global Makefile variable + * Debug output is sent to stderr, do: + * cpupower monitor 2>/tmp/debug + * to split debug output away from normal output +*/ +#ifdef DEBUG +extern int be_verbose; + +#define dprint(fmt, ...) { \ + if (be_verbose) { \ + fprintf(stderr, "%s: " fmt, \ + __FUNCTION__, ##__VA_ARGS__); \ + } \ + } +#else +static inline void dprint(const char *fmt, ...) { } +#endif +extern int be_verbose; +/* Global verbose (-v) stuff *********************************/ + +/* cpuid and cpuinfo helpers **************************/ +enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, + X86_VENDOR_AMD, X86_VENDOR_MAX}; + +#define CPUPOWER_CAP_INV_TSC 0x00000001 +#define CPUPOWER_CAP_APERF 0x00000002 +#define CPUPOWER_CAP_AMD_CBP 0x00000004 +#define CPUPOWER_CAP_PERF_BIAS 0x00000008 + +#define MAX_HW_PSTATES 10 + +struct cpupower_cpu_info { + enum cpupower_cpu_vendor vendor; + unsigned int family; + unsigned int model; + unsigned int stepping; + /* CPU capabilities read out from cpuid */ + unsigned long long caps; +}; + +/* get_cpu_info + * + * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo + * + * Returns 0 on success or a negativ error code + * Only used on x86, below global's struct values are zero/unknown on + * other archs + */ +extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info); +extern struct cpupower_cpu_info cpupower_cpu_info; +/* cpuid and cpuinfo helpers **************************/ + + +/* CPU topology/hierarchy parsing ******************/ +struct cpupower_topology { + /* Amount of CPU cores, packages and threads per core in the system */ + unsigned int cores; + unsigned int pkgs; + unsigned int threads; /* per core */ + + /* Array gets mallocated with cores entries, holding per core info */ + struct { + int pkg; + int core; + int cpu; + } *core_info; +}; + +extern int get_cpu_topology(struct cpupower_topology *cpu_top); +extern void cpu_topology_release(struct cpupower_topology cpu_top); +/* CPU topology/hierarchy parsing ******************/ + +/* X86 ONLY ****************************************/ +#if defined(__i386__) || defined(__x86_64__) + +#include + +/* Read/Write msr ****************************/ +extern int read_msr(int cpu, unsigned int idx, unsigned long long *val); +extern int write_msr(int cpu, unsigned int idx, unsigned long long val); + +extern int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val); +extern int msr_intel_get_perf_bias(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 ****************************/ +extern int amd_pci_get_num_boost_states(int *active, int *states); +extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, + int *dev_ids); + +/* PCI stuff ****************************/ + +/* AMD HW pstate decoding **************************/ + +extern int decode_pstates(unsigned int cpu, unsigned int cpu_family, + int boost_states, unsigned long *pstates, int *no); + +/* AMD HW pstate decoding **************************/ + +extern int cpufreq_has_boost_support(unsigned int cpu, int *support, + int *active, int * states); +/* + * CPUID functions returning a single datum + */ +unsigned int cpuid_eax(unsigned int op); +unsigned int cpuid_ebx(unsigned int op); +unsigned int cpuid_ecx(unsigned int op); +unsigned int cpuid_edx(unsigned int op); + +/* cpuid and cpuinfo helpers **************************/ +/* X86 ONLY ********************************************/ +#else +static inline int decode_pstates(unsigned int cpu, unsigned int cpu_family, + int boost_states, unsigned long *pstates, + int *no) +{ return -1; }; + +static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val) +{ return -1; }; +static inline int write_msr(int cpu, unsigned int idx, unsigned long long val) +{ return -1; }; +static inline int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val) +{ return -1; }; +static inline int msr_intel_get_perf_bias(unsigned int cpu) +{ return -1; }; + +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, + int *active, int * states) +{ return -1; } + +/* cpuid and cpuinfo helpers **************************/ + +static inline unsigned int cpuid_eax(unsigned int op) { return 0; }; +static inline unsigned int cpuid_ebx(unsigned int op) { return 0; }; +static inline unsigned int cpuid_ecx(unsigned int op) { return 0; }; +static inline unsigned int cpuid_edx(unsigned int op) { return 0; }; +#endif /* defined(__i386__) || defined(__x86_64__) */ + +#endif /* __CPUPOWERUTILS_HELPERS__ */ -- cgit v1.2.3-70-g09d2 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/helpers.h') diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 5e44e31fc7f..87d5605bdda 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 60f4d69bb20..5c074c60f90 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 71021f3bb69..944b2c1659d 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 a487dadb4cf..048f065925c 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 c1566e93e0e..e8b3140cc6b 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 8dcc9381371..cd2eb6fe41c 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 0c534e79652..55e2466674c 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 5d02d2fc70e..f9373e09063 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 5ad842b956b..385ee5c7570 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-70-g09d2 From 8fb2e440b223b966f74a04a48f6f71f288fa671b Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 21 Jul 2011 11:54:53 +0200 Subject: cpupower: Show Intel turbo ratio support via ./cpupower frequency-info This adds the last piece missing from turbostat (if called with -v). It shows on Intel machines supporting Turbo Boost how many cores have to be active/idle to enter which boost mode (frequency). Whether the HW really enters these boost modes can be verified via ./cpupower monitor. 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/cpufreq-info.c | 54 +++++++++++++++++++++------- tools/power/cpupower/utils/helpers/cpuid.c | 29 ++++++++++++++- tools/power/cpupower/utils/helpers/helpers.h | 13 ++++--- tools/power/cpupower/utils/helpers/msr.c | 16 +++++++++ 4 files changed, 95 insertions(+), 17 deletions(-) (limited to 'tools/power/cpupower/utils/helpers/helpers.h') diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index 8628644188c..5a1d25f056b 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -165,26 +165,56 @@ static int get_boost_mode(unsigned int cpu) printf(_(" Supported: %s\n"), support ? _("yes") : _("no")); printf(_(" Active: %s\n"), active ? _("yes") : _("no")); - /* ToDo: Only works for AMD for now... */ - if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && cpupower_cpu_info.family >= 0x10) { ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states, pstates, &pstate_no); if (ret) return ret; - } else - return 0; - printf(_(" Boost States: %d\n"), b_states); - printf(_(" Total States: %d\n"), pstate_no); - for (i = 0; i < pstate_no; i++) { - if (i < b_states) - printf(_(" Pstate-Pb%d: %luMHz (boost state)\n"), - i, pstates[i]); + printf(_(" Boost States: %d\n"), b_states); + printf(_(" Total States: %d\n"), pstate_no); + for (i = 0; i < pstate_no; i++) { + if (i < b_states) + printf(_(" Pstate-Pb%d: %luMHz (boost state)" + "\n"), i, pstates[i]); + else + printf(_(" Pstate-P%d: %luMHz\n"), + i - b_states, pstates[i]); + } + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) { + double bclk; + unsigned long long intel_turbo_ratio = 0; + unsigned int ratio; + + /* Any way to autodetect this ? */ + if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB) + bclk = 100.00; else - printf(_(" Pstate-P%d: %luMHz\n"), - i - b_states, pstates[i]); + bclk = 133.33; + intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu); + dprint (" Ratio: 0x%llx - bclk: %f\n", + intel_turbo_ratio, bclk); + + ratio = (intel_turbo_ratio >> 24) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 4 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 16) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 3 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 8) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 2 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 0) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 1 active cores\n"), + ratio * bclk); } return 0; } diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index 944b2c1659d..a97f091fcf2 100644 --- a/tools/power/cpupower/utils/helpers/cpuid.c +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -130,10 +130,37 @@ out: cpu_info->caps |= CPUPOWER_CAP_AMD_CBP; } - /* Intel's perf-bias MSR support */ if (cpu_info->vendor == X86_VENDOR_INTEL) { + /* Intel's perf-bias MSR support */ if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3))) cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS; + + /* Intel's Turbo Ratio Limit support */ + if (cpu_info->family == 6) { + switch (cpu_info->model) { + case 0x1A: /* Core i7, Xeon 5500 series + * Bloomfield, Gainstown NHM-EP + */ + case 0x1E: /* Core i7 and i5 Processor + * Clarksfield, Lynnfield, Jasper Forest + */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case 0x25: /* Westmere Client + * Clarkdale, Arrandale + */ + case 0x2C: /* Westmere EP - Gulftown */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; + cpu_info->caps |= CPUPOWER_CAP_IS_SNB; + break; + case 0x2E: /* Nehalem-EX Xeon - Beckton */ + case 0x2F: /* Westmere-EX Xeon - Eagleton */ + default: + break; + } + } } /* printf("ID: %u - Extid: 0x%x - Caps: 0x%llx\n", diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 048f065925c..9125a551ac1 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -52,10 +52,12 @@ extern int be_verbose; enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, X86_VENDOR_AMD, X86_VENDOR_MAX}; -#define CPUPOWER_CAP_INV_TSC 0x00000001 -#define CPUPOWER_CAP_APERF 0x00000002 -#define CPUPOWER_CAP_AMD_CBP 0x00000004 -#define CPUPOWER_CAP_PERF_BIAS 0x00000008 +#define CPUPOWER_CAP_INV_TSC 0x00000001 +#define CPUPOWER_CAP_APERF 0x00000002 +#define CPUPOWER_CAP_AMD_CBP 0x00000004 +#define CPUPOWER_CAP_PERF_BIAS 0x00000008 +#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 +#define CPUPOWER_CAP_IS_SNB 0x00000011 #define MAX_HW_PSTATES 10 @@ -111,6 +113,7 @@ extern int write_msr(int cpu, unsigned int idx, unsigned long long val); 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); @@ -157,6 +160,8 @@ static inline int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val) { return -1; }; static inline int msr_intel_get_perf_bias(unsigned int cpu) { return -1; }; +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; }; diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c index 93d48bd56e5..7869ca64dfd 100644 --- a/tools/power/cpupower/utils/helpers/msr.c +++ b/tools/power/cpupower/utils/helpers/msr.c @@ -11,6 +11,7 @@ #define MSR_IA32_PERF_STATUS 0x198 #define MSR_IA32_MISC_ENABLES 0x1a0 #define MSR_IA32_ENERGY_PERF_BIAS 0x1b0 +#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1ad /* * read_msr @@ -79,6 +80,7 @@ int msr_intel_has_boost_support(unsigned int cpu) ret = read_msr(cpu, MSR_IA32_MISC_ENABLES, &misc_enables); if (ret) return ret; + return (misc_enables >> 38) & 0x1; } @@ -119,4 +121,18 @@ int msr_intel_set_perf_bias(unsigned int cpu, unsigned int val) return ret; return 0; } + +unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu) +{ + unsigned long long val; + int ret; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO)) + return -1; + + ret = read_msr(cpu, MSR_NEHALEM_TURBO_RATIO_LIMIT, &val); + if (ret) + return ret; + return val; +} #endif -- cgit v1.2.3-70-g09d2 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/helpers.h') diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c index a97f091fcf2..906895d21cc 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 9125a551ac1..592ee362b87 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 e8b3140cc6b..1609243f5c6 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 7869ca64dfd..31a4b24a8bc 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-70-g09d2 From 7c74d2bc5a9d43d33d6f16c1e706147162e2bc52 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 12 Aug 2011 01:11:37 +0200 Subject: cpupower: Better detect offlined CPUs Before, checking for offlined CPUs was done dirty and it was checked whether topology parsing returned -1 values. But this is a valid case on a Xen (and possibly other) kernels. Do proper online/offline checking, also take CONFIG_HOTPLUG_CPU option into account (no /sys/devices/../cpuX/online file). Signed-off-by: Thomas Renninger Signed-off-by: Dominik Brodowski --- tools/power/cpupower/utils/helpers/helpers.h | 3 ++ tools/power/cpupower/utils/helpers/sysfs.c | 50 ++++++++++++++++++++++ tools/power/cpupower/utils/helpers/sysfs.h | 2 + tools/power/cpupower/utils/helpers/topology.c | 5 ++- .../cpupower/utils/idle_monitor/cpupower-monitor.c | 10 +++-- 5 files changed, 66 insertions(+), 4 deletions(-) (limited to 'tools/power/cpupower/utils/helpers/helpers.h') diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 592ee362b87..7a83022733b 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -96,6 +96,9 @@ struct cpupower_topology { int pkg; int core; int cpu; + + /* flags */ + unsigned int is_online:1; } *core_info; }; diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c index 55e2466674c..c6343024a61 100644 --- a/tools/power/cpupower/utils/helpers/sysfs.c +++ b/tools/power/cpupower/utils/helpers/sysfs.c @@ -56,6 +56,56 @@ static unsigned int sysfs_write_file(const char *path, return (unsigned int) numwrite; } +/* + * Detect whether a CPU is online + * + * Returns: + * 1 -> if CPU is online + * 0 -> if CPU is offline + * negative errno values in error case + */ +int sysfs_is_cpu_online(unsigned int cpu) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numread; + unsigned long long value; + char linebuf[MAX_LINE_LEN]; + char *endp; + struct stat statbuf; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu); + + if (stat(path, &statbuf) != 0) + return 0; + + /* + * kernel without CONFIG_HOTPLUG_CPU + * -> cpuX directory exists, but not cpuX/online file + */ + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu); + if (stat(path, &statbuf) != 0) + return 1; + + fd = open(path, O_RDONLY); + if (fd == -1) + return -errno; + + numread = read(fd, linebuf, MAX_LINE_LEN - 1); + if (numread < 1) { + close(fd); + return -EIO; + } + linebuf[numread] = '\0'; + close(fd); + + value = strtoull(linebuf, &endp, 0); + if (value > 1 || value < 0) + return -EINVAL; + + return value; +} + /* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ /* diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h index f9373e09063..8cb797bbceb 100644 --- a/tools/power/cpupower/utils/helpers/sysfs.h +++ b/tools/power/cpupower/utils/helpers/sysfs.h @@ -7,6 +7,8 @@ extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); +extern int sysfs_is_cpu_online(unsigned int cpu); + extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, unsigned int idlestate); extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c index 385ee5c7570..4eae2c47ba4 100644 --- a/tools/power/cpupower/utils/helpers/topology.c +++ b/tools/power/cpupower/utils/helpers/topology.c @@ -41,6 +41,8 @@ struct cpuid_core_info { unsigned int pkg; unsigned int thread; unsigned int cpu; + /* flags */ + unsigned int is_online:1; }; static int __compare(const void *t1, const void *t2) @@ -78,6 +80,8 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) return -ENOMEM; cpu_top->pkgs = cpu_top->cores = 0; for (cpu = 0; cpu < cpus; cpu++) { + cpu_top->core_info[cpu].cpu = cpu; + cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu); cpu_top->core_info[cpu].pkg = sysfs_topology_read_file(cpu, "physical_package_id"); if ((int)cpu_top->core_info[cpu].pkg != -1 && @@ -85,7 +89,6 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) cpu_top->pkgs = cpu_top->core_info[cpu].pkg; cpu_top->core_info[cpu].core = sysfs_topology_read_file(cpu, "core_id"); - cpu_top->core_info[cpu].cpu = cpu; } cpu_top->pkgs++; diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c index ba4bf068380..dd8e1ea6e6f 100644 --- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c @@ -190,9 +190,13 @@ void print_results(int topology_depth, int cpu) } } } - /* cpu offline */ - if (cpu_top.core_info[cpu].pkg == -1 || - cpu_top.core_info[cpu].core == -1) { + /* + * The monitor could still provide useful data, for example + * AMD HW counters partly sit in PCI config space. + * It's up to the monitor plug-in to check .is_online, this one + * is just for additional info. + */ + if (!cpu_top.core_info[cpu].is_online) { printf(_(" *is offline\n")); return; } else -- cgit v1.2.3-70-g09d2 From 47c336307a3680cfdf4adbe718d79f3fe66702ea Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Fri, 19 Aug 2011 17:00:02 +0200 Subject: cpupower: make NLS truly optional Loosely based on a patch for cpufrequtils, submittted by Sergey Dryabzhinsky and signed-off-by: Matt Turner Signed-off-by: Dominik Brodowski --- tools/power/cpupower/Makefile | 1 + tools/power/cpupower/utils/helpers/helpers.h | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'tools/power/cpupower/utils/helpers/helpers.h') diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index edb021c5f8c..e8a03aceceb 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -137,6 +137,7 @@ CFLAGS += -pipe ifeq ($(strip $(NLS)),true) INSTALL_NLS += install-gmo COMPILE_NLS += create-gmo + CFLAGS += -DNLS endif ifeq ($(strip $(CPUFREQ_BENCH)),true) diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 7a83022733b..2747e738efb 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -16,11 +16,20 @@ #include "helpers/bitmask.h" /* Internationalization ****************************/ +#ifdef NLS + #define _(String) gettext(String) #ifndef gettext_noop #define gettext_noop(String) String #endif #define N_(String) gettext_noop(String) + +#else /* !NLS */ + +#define _(String) String +#define N_(String) String + +#endif /* Internationalization ****************************/ extern int run_as_root; -- cgit v1.2.3-70-g09d2