Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cpupower: Add cpuidle parts into library

This more or less is a renaming and moving of functions and should not
introduce any functional change.

cpupower was built from cpufrequtils (which had a C library providing easy
access to cpu frequency platform info). In the meantime it got enhanced
by quite some neat cpuidle userspace tools.

Now the cpu idle functions have been separated and added to the cpupower.so
library.
So beside an already existing public header file:
cpufreq.h
cpupower now also exports these cpu idle functions in:
cpuidle.h

Here again pasted for better review of the interfaces:

======================================
int cpuidle_is_state_disabled(unsigned int cpu,
unsigned int idlestate);
int cpuidle_state_disable(unsigned int cpu, unsigned int idlestate,
unsigned int disable);
unsigned long cpuidle_state_latency(unsigned int cpu,
unsigned int idlestate);
unsigned long cpuidle_state_usage(unsigned int cpu,
unsigned int idlestate);
unsigned long long cpuidle_state_time(unsigned int cpu,
unsigned int idlestate);
char *cpuidle_state_name(unsigned int cpu,
unsigned int idlestate);
char *cpuidle_state_desc(unsigned int cpu,
unsigned int idlestate);
unsigned int cpuidle_state_count(unsigned int cpu);

char *cpuidle_get_governor(void);
char *cpuidle_get_driver(void);

======================================

Signed-off-by: Thomas Renninger <trenn@suse.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Thomas Renninger and committed by
Rafael J. Wysocki
ac5a181d fe7656a8

+1242 -931
+7 -5
tools/power/cpupower/Makefile
··· 63 63 # and _should_ modify the PACKAGE_BUGREPORT definition 64 64 65 65 VERSION= $(shell ./utils/version-gen.sh) 66 - LIB_MAJ= 0.0.0 66 + LIB_MAJ= 0.0.1 67 67 LIB_MIN= 0 68 68 69 69 PACKAGE = cpupower ··· 129 129 CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \ 130 130 -DPACKAGE_BUGREPORT=\"$(PACKAGE_BUGREPORT)\" -D_GNU_SOURCE 131 131 132 - UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \ 132 + UTIL_OBJS = utils/helpers/amd.o utils/helpers/msr.o \ 133 133 utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \ 134 134 utils/helpers/pci.o utils/helpers/bitmask.o \ 135 135 utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \ ··· 148 148 utils/helpers/bitmask.h \ 149 149 utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def 150 150 151 - LIB_HEADERS = lib/cpufreq.h lib/sysfs.h 152 - LIB_SRC = lib/cpufreq.c lib/sysfs.c 153 - LIB_OBJS = lib/cpufreq.o lib/sysfs.o 151 + LIB_HEADERS = lib/cpufreq.h lib/cpupower.h lib/cpuidle.h 152 + LIB_SRC = lib/cpufreq.c lib/cpupower.c lib/cpuidle.c 153 + LIB_OBJS = lib/cpufreq.o lib/cpupower.o lib/cpuidle.o 154 154 LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS)) 155 155 156 156 CFLAGS += -pipe ··· 280 280 $(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/ 281 281 $(INSTALL) -d $(DESTDIR)${includedir} 282 282 $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h 283 + $(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h 283 284 284 285 install-tools: 285 286 $(INSTALL) -d $(DESTDIR)${bindir} ··· 316 315 uninstall: 317 316 - rm -f $(DESTDIR)${libdir}/libcpupower.* 318 317 - rm -f $(DESTDIR)${includedir}/cpufreq.h 318 + - rm -f $(DESTDIR)${includedir}/cpuidle.h 319 319 - rm -f $(DESTDIR)${bindir}/utils/cpupower 320 320 - rm -f $(DESTDIR)${mandir}/man1/cpupower.1 321 321 - rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1
+2 -1
tools/power/cpupower/bench/system.c
··· 26 26 #include <sched.h> 27 27 28 28 #include <cpufreq.h> 29 + #include <cpupower.h> 29 30 30 31 #include "config.h" 31 32 #include "system.h" ··· 61 60 62 61 dprintf("set %s as cpufreq governor\n", governor); 63 62 64 - if (cpufreq_cpu_exists(cpu) != 0) { 63 + if (cpupower_is_cpu_online(cpu) != 0) { 65 64 perror("cpufreq_cpu_exists"); 66 65 fprintf(stderr, "error: cpu %u does not exist\n", cpu); 67 66 return -1;
+529 -21
tools/power/cpupower/lib/cpufreq.c
··· 9 9 #include <errno.h> 10 10 #include <stdlib.h> 11 11 #include <string.h> 12 + #include <sys/types.h> 13 + #include <sys/stat.h> 14 + #include <fcntl.h> 15 + #include <unistd.h> 12 16 13 17 #include "cpufreq.h" 14 - #include "sysfs.h" 18 + #include "cpupower_intern.h" 15 19 16 - int cpufreq_cpu_exists(unsigned int cpu) 20 + /* CPUFREQ sysfs access **************************************************/ 21 + 22 + /* helper function to read file from /sys into given buffer */ 23 + /* fname is a relative path under "cpuX/cpufreq" dir */ 24 + static unsigned int sysfs_cpufreq_read_file(unsigned int cpu, const char *fname, 25 + char *buf, size_t buflen) 17 26 { 18 - return sysfs_cpu_exists(cpu); 27 + char path[SYSFS_PATH_MAX]; 28 + 29 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", 30 + cpu, fname); 31 + return sysfs_read_file(path, buf, buflen); 19 32 } 33 + 34 + /* helper function to write a new value to a /sys file */ 35 + /* fname is a relative path under "cpuX/cpufreq" dir */ 36 + static unsigned int sysfs_cpufreq_write_file(unsigned int cpu, 37 + const char *fname, 38 + const char *value, size_t len) 39 + { 40 + char path[SYSFS_PATH_MAX]; 41 + int fd; 42 + ssize_t numwrite; 43 + 44 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", 45 + cpu, fname); 46 + 47 + fd = open(path, O_WRONLY); 48 + if (fd == -1) 49 + return 0; 50 + 51 + numwrite = write(fd, value, len); 52 + if (numwrite < 1) { 53 + close(fd); 54 + return 0; 55 + } 56 + 57 + close(fd); 58 + 59 + return (unsigned int) numwrite; 60 + } 61 + 62 + /* read access to files which contain one numeric value */ 63 + 64 + enum cpufreq_value { 65 + CPUINFO_CUR_FREQ, 66 + CPUINFO_MIN_FREQ, 67 + CPUINFO_MAX_FREQ, 68 + CPUINFO_LATENCY, 69 + SCALING_CUR_FREQ, 70 + SCALING_MIN_FREQ, 71 + SCALING_MAX_FREQ, 72 + STATS_NUM_TRANSITIONS, 73 + MAX_CPUFREQ_VALUE_READ_FILES 74 + }; 75 + 76 + static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = { 77 + [CPUINFO_CUR_FREQ] = "cpuinfo_cur_freq", 78 + [CPUINFO_MIN_FREQ] = "cpuinfo_min_freq", 79 + [CPUINFO_MAX_FREQ] = "cpuinfo_max_freq", 80 + [CPUINFO_LATENCY] = "cpuinfo_transition_latency", 81 + [SCALING_CUR_FREQ] = "scaling_cur_freq", 82 + [SCALING_MIN_FREQ] = "scaling_min_freq", 83 + [SCALING_MAX_FREQ] = "scaling_max_freq", 84 + [STATS_NUM_TRANSITIONS] = "stats/total_trans" 85 + }; 86 + 87 + 88 + static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, 89 + enum cpufreq_value which) 90 + { 91 + unsigned long value; 92 + unsigned int len; 93 + char linebuf[MAX_LINE_LEN]; 94 + char *endp; 95 + 96 + if (which >= MAX_CPUFREQ_VALUE_READ_FILES) 97 + return 0; 98 + 99 + len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which], 100 + linebuf, sizeof(linebuf)); 101 + 102 + if (len == 0) 103 + return 0; 104 + 105 + value = strtoul(linebuf, &endp, 0); 106 + 107 + if (endp == linebuf || errno == ERANGE) 108 + return 0; 109 + 110 + return value; 111 + } 112 + 113 + /* read access to files which contain one string */ 114 + 115 + enum cpufreq_string { 116 + SCALING_DRIVER, 117 + SCALING_GOVERNOR, 118 + MAX_CPUFREQ_STRING_FILES 119 + }; 120 + 121 + static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES] = { 122 + [SCALING_DRIVER] = "scaling_driver", 123 + [SCALING_GOVERNOR] = "scaling_governor", 124 + }; 125 + 126 + 127 + static char *sysfs_cpufreq_get_one_string(unsigned int cpu, 128 + enum cpufreq_string which) 129 + { 130 + char linebuf[MAX_LINE_LEN]; 131 + char *result; 132 + unsigned int len; 133 + 134 + if (which >= MAX_CPUFREQ_STRING_FILES) 135 + return NULL; 136 + 137 + len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which], 138 + linebuf, sizeof(linebuf)); 139 + if (len == 0) 140 + return NULL; 141 + 142 + result = strdup(linebuf); 143 + if (result == NULL) 144 + return NULL; 145 + 146 + if (result[strlen(result) - 1] == '\n') 147 + result[strlen(result) - 1] = '\0'; 148 + 149 + return result; 150 + } 151 + 152 + /* write access */ 153 + 154 + enum cpufreq_write { 155 + WRITE_SCALING_MIN_FREQ, 156 + WRITE_SCALING_MAX_FREQ, 157 + WRITE_SCALING_GOVERNOR, 158 + WRITE_SCALING_SET_SPEED, 159 + MAX_CPUFREQ_WRITE_FILES 160 + }; 161 + 162 + static const char *cpufreq_write_files[MAX_CPUFREQ_WRITE_FILES] = { 163 + [WRITE_SCALING_MIN_FREQ] = "scaling_min_freq", 164 + [WRITE_SCALING_MAX_FREQ] = "scaling_max_freq", 165 + [WRITE_SCALING_GOVERNOR] = "scaling_governor", 166 + [WRITE_SCALING_SET_SPEED] = "scaling_setspeed", 167 + }; 168 + 169 + static int sysfs_cpufreq_write_one_value(unsigned int cpu, 170 + enum cpufreq_write which, 171 + const char *new_value, size_t len) 172 + { 173 + if (which >= MAX_CPUFREQ_WRITE_FILES) 174 + return 0; 175 + 176 + if (sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which], 177 + new_value, len) != len) 178 + return -ENODEV; 179 + 180 + return 0; 181 + }; 20 182 21 183 unsigned long cpufreq_get_freq_kernel(unsigned int cpu) 22 184 { 23 - return sysfs_get_freq_kernel(cpu); 185 + return sysfs_cpufreq_get_one_value(cpu, SCALING_CUR_FREQ); 24 186 } 25 187 26 188 unsigned long cpufreq_get_freq_hardware(unsigned int cpu) 27 189 { 28 - return sysfs_get_freq_hardware(cpu); 190 + return sysfs_cpufreq_get_one_value(cpu, CPUINFO_CUR_FREQ); 29 191 } 30 192 31 193 unsigned long cpufreq_get_transition_latency(unsigned int cpu) 32 194 { 33 - return sysfs_get_freq_transition_latency(cpu); 195 + return sysfs_cpufreq_get_one_value(cpu, CPUINFO_LATENCY); 34 196 } 35 197 36 198 int cpufreq_get_hardware_limits(unsigned int cpu, ··· 201 39 { 202 40 if ((!min) || (!max)) 203 41 return -EINVAL; 204 - return sysfs_get_freq_hardware_limits(cpu, min, max); 42 + 43 + *min = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MIN_FREQ); 44 + if (!*min) 45 + return -ENODEV; 46 + 47 + *max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ); 48 + if (!*max) 49 + return -ENODEV; 50 + 51 + return 0; 205 52 } 206 53 207 54 char *cpufreq_get_driver(unsigned int cpu) 208 55 { 209 - return sysfs_get_freq_driver(cpu); 56 + return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER); 210 57 } 211 58 212 59 void cpufreq_put_driver(char *ptr) ··· 227 56 228 57 struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu) 229 58 { 230 - return sysfs_get_freq_policy(cpu); 59 + struct cpufreq_policy *policy; 60 + 61 + policy = malloc(sizeof(struct cpufreq_policy)); 62 + if (!policy) 63 + return NULL; 64 + 65 + policy->governor = sysfs_cpufreq_get_one_string(cpu, SCALING_GOVERNOR); 66 + if (!policy->governor) { 67 + free(policy); 68 + return NULL; 69 + } 70 + policy->min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ); 71 + policy->max = sysfs_cpufreq_get_one_value(cpu, SCALING_MAX_FREQ); 72 + if ((!policy->min) || (!policy->max)) { 73 + free(policy->governor); 74 + free(policy); 75 + return NULL; 76 + } 77 + 78 + return policy; 231 79 } 232 80 233 81 void cpufreq_put_policy(struct cpufreq_policy *policy) ··· 262 72 struct cpufreq_available_governors *cpufreq_get_available_governors(unsigned 263 73 int cpu) 264 74 { 265 - return sysfs_get_freq_available_governors(cpu); 75 + struct cpufreq_available_governors *first = NULL; 76 + struct cpufreq_available_governors *current = NULL; 77 + char linebuf[MAX_LINE_LEN]; 78 + unsigned int pos, i; 79 + unsigned int len; 80 + 81 + len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors", 82 + linebuf, sizeof(linebuf)); 83 + if (len == 0) 84 + return NULL; 85 + 86 + pos = 0; 87 + for (i = 0; i < len; i++) { 88 + if (linebuf[i] == ' ' || linebuf[i] == '\n') { 89 + if (i - pos < 2) 90 + continue; 91 + if (current) { 92 + current->next = malloc(sizeof(*current)); 93 + if (!current->next) 94 + goto error_out; 95 + current = current->next; 96 + } else { 97 + first = malloc(sizeof(*first)); 98 + if (!first) 99 + goto error_out; 100 + current = first; 101 + } 102 + current->first = first; 103 + current->next = NULL; 104 + 105 + current->governor = malloc(i - pos + 1); 106 + if (!current->governor) 107 + goto error_out; 108 + 109 + memcpy(current->governor, linebuf + pos, i - pos); 110 + current->governor[i - pos] = '\0'; 111 + pos = i + 1; 112 + } 113 + } 114 + 115 + return first; 116 + 117 + error_out: 118 + while (first) { 119 + current = first->next; 120 + if (first->governor) 121 + free(first->governor); 122 + free(first); 123 + first = current; 124 + } 125 + return NULL; 266 126 } 267 127 268 128 void cpufreq_put_available_governors(struct cpufreq_available_governors *any) ··· 336 96 struct cpufreq_available_frequencies 337 97 *cpufreq_get_available_frequencies(unsigned int cpu) 338 98 { 339 - return sysfs_get_available_frequencies(cpu); 99 + struct cpufreq_available_frequencies *first = NULL; 100 + struct cpufreq_available_frequencies *current = NULL; 101 + char one_value[SYSFS_PATH_MAX]; 102 + char linebuf[MAX_LINE_LEN]; 103 + unsigned int pos, i; 104 + unsigned int len; 105 + 106 + len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies", 107 + linebuf, sizeof(linebuf)); 108 + if (len == 0) 109 + return NULL; 110 + 111 + pos = 0; 112 + for (i = 0; i < len; i++) { 113 + if (linebuf[i] == ' ' || linebuf[i] == '\n') { 114 + if (i - pos < 2) 115 + continue; 116 + if (i - pos >= SYSFS_PATH_MAX) 117 + goto error_out; 118 + if (current) { 119 + current->next = malloc(sizeof(*current)); 120 + if (!current->next) 121 + goto error_out; 122 + current = current->next; 123 + } else { 124 + first = malloc(sizeof(*first)); 125 + if (!first) 126 + goto error_out; 127 + current = first; 128 + } 129 + current->first = first; 130 + current->next = NULL; 131 + 132 + memcpy(one_value, linebuf + pos, i - pos); 133 + one_value[i - pos] = '\0'; 134 + if (sscanf(one_value, "%lu", &current->frequency) != 1) 135 + goto error_out; 136 + 137 + pos = i + 1; 138 + } 139 + } 140 + 141 + return first; 142 + 143 + error_out: 144 + while (first) { 145 + current = first->next; 146 + free(first); 147 + first = current; 148 + } 149 + return NULL; 340 150 } 341 151 342 152 void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies ··· 404 114 } 405 115 } 406 116 117 + static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu, 118 + const char *file) 119 + { 120 + struct cpufreq_affected_cpus *first = NULL; 121 + struct cpufreq_affected_cpus *current = NULL; 122 + char one_value[SYSFS_PATH_MAX]; 123 + char linebuf[MAX_LINE_LEN]; 124 + unsigned int pos, i; 125 + unsigned int len; 126 + 127 + len = sysfs_cpufreq_read_file(cpu, file, linebuf, sizeof(linebuf)); 128 + if (len == 0) 129 + return NULL; 130 + 131 + pos = 0; 132 + for (i = 0; i < len; i++) { 133 + if (i == len || linebuf[i] == ' ' || linebuf[i] == '\n') { 134 + if (i - pos < 1) 135 + continue; 136 + if (i - pos >= SYSFS_PATH_MAX) 137 + goto error_out; 138 + if (current) { 139 + current->next = malloc(sizeof(*current)); 140 + if (!current->next) 141 + goto error_out; 142 + current = current->next; 143 + } else { 144 + first = malloc(sizeof(*first)); 145 + if (!first) 146 + goto error_out; 147 + current = first; 148 + } 149 + current->first = first; 150 + current->next = NULL; 151 + 152 + memcpy(one_value, linebuf + pos, i - pos); 153 + one_value[i - pos] = '\0'; 154 + 155 + if (sscanf(one_value, "%u", &current->cpu) != 1) 156 + goto error_out; 157 + 158 + pos = i + 1; 159 + } 160 + } 161 + 162 + return first; 163 + 164 + error_out: 165 + while (first) { 166 + current = first->next; 167 + free(first); 168 + first = current; 169 + } 170 + return NULL; 171 + } 407 172 408 173 struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned int cpu) 409 174 { 410 - return sysfs_get_freq_affected_cpus(cpu); 175 + return sysfs_get_cpu_list(cpu, "affected_cpus"); 411 176 } 412 177 413 178 void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *any) ··· 483 138 484 139 struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned int cpu) 485 140 { 486 - return sysfs_get_freq_related_cpus(cpu); 141 + return sysfs_get_cpu_list(cpu, "related_cpus"); 487 142 } 488 143 489 144 void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *any) ··· 491 146 cpufreq_put_affected_cpus(any); 492 147 } 493 148 149 + static int verify_gov(char *new_gov, char *passed_gov) 150 + { 151 + unsigned int i, j = 0; 152 + 153 + if (!passed_gov || (strlen(passed_gov) > 19)) 154 + return -EINVAL; 155 + 156 + strncpy(new_gov, passed_gov, 20); 157 + for (i = 0; i < 20; i++) { 158 + if (j) { 159 + new_gov[i] = '\0'; 160 + continue; 161 + } 162 + if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z')) 163 + continue; 164 + 165 + if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z')) 166 + continue; 167 + 168 + if (new_gov[i] == '-') 169 + continue; 170 + 171 + if (new_gov[i] == '_') 172 + continue; 173 + 174 + if (new_gov[i] == '\0') { 175 + j = 1; 176 + continue; 177 + } 178 + return -EINVAL; 179 + } 180 + new_gov[19] = '\0'; 181 + return 0; 182 + } 494 183 495 184 int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy) 496 185 { 186 + char min[SYSFS_PATH_MAX]; 187 + char max[SYSFS_PATH_MAX]; 188 + char gov[SYSFS_PATH_MAX]; 189 + int ret; 190 + unsigned long old_min; 191 + int write_max_first; 192 + 497 193 if (!policy || !(policy->governor)) 498 194 return -EINVAL; 499 195 500 - return sysfs_set_freq_policy(cpu, policy); 196 + if (policy->max < policy->min) 197 + return -EINVAL; 198 + 199 + if (verify_gov(gov, policy->governor)) 200 + return -EINVAL; 201 + 202 + snprintf(min, SYSFS_PATH_MAX, "%lu", policy->min); 203 + snprintf(max, SYSFS_PATH_MAX, "%lu", policy->max); 204 + 205 + old_min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ); 206 + write_max_first = (old_min && (policy->max < old_min) ? 0 : 1); 207 + 208 + if (write_max_first) { 209 + ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, 210 + max, strlen(max)); 211 + if (ret) 212 + return ret; 213 + } 214 + 215 + ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, min, 216 + strlen(min)); 217 + if (ret) 218 + return ret; 219 + 220 + if (!write_max_first) { 221 + ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, 222 + max, strlen(max)); 223 + if (ret) 224 + return ret; 225 + } 226 + 227 + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR, 228 + gov, strlen(gov)); 501 229 } 502 230 503 231 504 232 int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq) 505 233 { 506 - return sysfs_modify_freq_policy_min(cpu, min_freq); 234 + char value[SYSFS_PATH_MAX]; 235 + 236 + snprintf(value, SYSFS_PATH_MAX, "%lu", min_freq); 237 + 238 + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, 239 + value, strlen(value)); 507 240 } 508 241 509 242 510 243 int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq) 511 244 { 512 - return sysfs_modify_freq_policy_max(cpu, max_freq); 513 - } 245 + char value[SYSFS_PATH_MAX]; 514 246 247 + snprintf(value, SYSFS_PATH_MAX, "%lu", max_freq); 248 + 249 + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, 250 + value, strlen(value)); 251 + } 515 252 516 253 int cpufreq_modify_policy_governor(unsigned int cpu, char *governor) 517 254 { 255 + char new_gov[SYSFS_PATH_MAX]; 256 + 518 257 if ((!governor) || (strlen(governor) > 19)) 519 258 return -EINVAL; 520 259 521 - return sysfs_modify_freq_policy_governor(cpu, governor); 260 + if (verify_gov(new_gov, governor)) 261 + return -EINVAL; 262 + 263 + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR, 264 + new_gov, strlen(new_gov)); 522 265 } 523 266 524 267 int cpufreq_set_frequency(unsigned int cpu, unsigned long target_frequency) 525 268 { 526 - return sysfs_set_frequency(cpu, target_frequency); 269 + struct cpufreq_policy *pol = cpufreq_get_policy(cpu); 270 + char userspace_gov[] = "userspace"; 271 + char freq[SYSFS_PATH_MAX]; 272 + int ret; 273 + 274 + if (!pol) 275 + return -ENODEV; 276 + 277 + if (strncmp(pol->governor, userspace_gov, 9) != 0) { 278 + ret = cpufreq_modify_policy_governor(cpu, userspace_gov); 279 + if (ret) { 280 + cpufreq_put_policy(pol); 281 + return ret; 282 + } 283 + } 284 + 285 + cpufreq_put_policy(pol); 286 + 287 + snprintf(freq, SYSFS_PATH_MAX, "%lu", target_frequency); 288 + 289 + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_SET_SPEED, 290 + freq, strlen(freq)); 527 291 } 528 292 529 293 struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu, 530 294 unsigned long long *total_time) 531 295 { 532 - return sysfs_get_freq_stats(cpu, total_time); 296 + struct cpufreq_stats *first = NULL; 297 + struct cpufreq_stats *current = NULL; 298 + char one_value[SYSFS_PATH_MAX]; 299 + char linebuf[MAX_LINE_LEN]; 300 + unsigned int pos, i; 301 + unsigned int len; 302 + 303 + len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state", 304 + linebuf, sizeof(linebuf)); 305 + if (len == 0) 306 + return NULL; 307 + 308 + *total_time = 0; 309 + pos = 0; 310 + for (i = 0; i < len; i++) { 311 + if (i == strlen(linebuf) || linebuf[i] == '\n') { 312 + if (i - pos < 2) 313 + continue; 314 + if ((i - pos) >= SYSFS_PATH_MAX) 315 + goto error_out; 316 + if (current) { 317 + current->next = malloc(sizeof(*current)); 318 + if (!current->next) 319 + goto error_out; 320 + current = current->next; 321 + } else { 322 + first = malloc(sizeof(*first)); 323 + if (!first) 324 + goto error_out; 325 + current = first; 326 + } 327 + current->first = first; 328 + current->next = NULL; 329 + 330 + memcpy(one_value, linebuf + pos, i - pos); 331 + one_value[i - pos] = '\0'; 332 + if (sscanf(one_value, "%lu %llu", 333 + &current->frequency, 334 + &current->time_in_state) != 2) 335 + goto error_out; 336 + 337 + *total_time = *total_time + current->time_in_state; 338 + pos = i + 1; 339 + } 340 + } 341 + 342 + return first; 343 + 344 + error_out: 345 + while (first) { 346 + current = first->next; 347 + free(first); 348 + first = current; 349 + } 350 + return NULL; 533 351 } 534 352 535 353 void cpufreq_put_stats(struct cpufreq_stats *any) ··· 712 204 713 205 unsigned long cpufreq_get_transitions(unsigned int cpu) 714 206 { 715 - return sysfs_get_freq_transitions(cpu); 207 + return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS); 716 208 }
+26 -33
tools/power/cpupower/lib/cpufreq.h
··· 17 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 18 */ 19 19 20 - #ifndef _CPUFREQ_H 21 - #define _CPUFREQ_H 1 20 + #ifndef __CPUPOWER_CPUFREQ_H__ 21 + #define __CPUPOWER_CPUFREQ_H__ 22 22 23 23 struct cpufreq_policy { 24 24 unsigned long min; ··· 58 58 extern "C" { 59 59 #endif 60 60 61 - /* 62 - * returns 0 if the specified CPU is present (it doesn't say 63 - * whether it is online!), and an error value if not. 64 - */ 65 - 66 - extern int cpufreq_cpu_exists(unsigned int cpu); 67 - 68 61 /* determine current CPU frequency 69 62 * - _kernel variant means kernel's opinion of CPU frequency 70 63 * - _hardware variant means actual hardware CPU frequency, ··· 66 73 * returns 0 on failure, else frequency in kHz. 67 74 */ 68 75 69 - extern unsigned long cpufreq_get_freq_kernel(unsigned int cpu); 76 + unsigned long cpufreq_get_freq_kernel(unsigned int cpu); 70 77 71 - extern unsigned long cpufreq_get_freq_hardware(unsigned int cpu); 78 + unsigned long cpufreq_get_freq_hardware(unsigned int cpu); 72 79 73 80 #define cpufreq_get(cpu) cpufreq_get_freq_kernel(cpu); 74 81 ··· 77 84 * 78 85 * returns 0 on failure, else transition latency in 10^(-9) s = nanoseconds 79 86 */ 80 - extern unsigned long cpufreq_get_transition_latency(unsigned int cpu); 87 + unsigned long cpufreq_get_transition_latency(unsigned int cpu); 81 88 82 89 83 90 /* determine hardware CPU frequency limits ··· 86 93 * considerations by cpufreq policy notifiers in the kernel. 87 94 */ 88 95 89 - extern int cpufreq_get_hardware_limits(unsigned int cpu, 96 + int cpufreq_get_hardware_limits(unsigned int cpu, 90 97 unsigned long *min, 91 98 unsigned long *max); 92 99 ··· 97 104 * to avoid memory leakage, please. 98 105 */ 99 106 100 - extern char *cpufreq_get_driver(unsigned int cpu); 107 + char *cpufreq_get_driver(unsigned int cpu); 101 108 102 - extern void cpufreq_put_driver(char *ptr); 109 + void cpufreq_put_driver(char *ptr); 103 110 104 111 105 112 /* determine CPUfreq policy currently used ··· 109 116 */ 110 117 111 118 112 - extern struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu); 119 + struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu); 113 120 114 - extern void cpufreq_put_policy(struct cpufreq_policy *policy); 121 + void cpufreq_put_policy(struct cpufreq_policy *policy); 115 122 116 123 117 124 /* determine CPUfreq governors currently available ··· 122 129 */ 123 130 124 131 125 - extern struct cpufreq_available_governors 132 + struct cpufreq_available_governors 126 133 *cpufreq_get_available_governors(unsigned int cpu); 127 134 128 - extern void cpufreq_put_available_governors( 135 + void cpufreq_put_available_governors( 129 136 struct cpufreq_available_governors *first); 130 137 131 138 ··· 136 143 * cpufreq_put_available_frequencies after use. 137 144 */ 138 145 139 - extern struct cpufreq_available_frequencies 146 + struct cpufreq_available_frequencies 140 147 *cpufreq_get_available_frequencies(unsigned int cpu); 141 148 142 - extern void cpufreq_put_available_frequencies( 149 + void cpufreq_put_available_frequencies( 143 150 struct cpufreq_available_frequencies *first); 144 151 145 152 ··· 149 156 * to avoid memory leakage, please. 150 157 */ 151 158 152 - extern struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned 159 + struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned 153 160 int cpu); 154 161 155 - extern void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *first); 162 + void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *first); 156 163 157 164 158 165 /* determine related CPUs ··· 161 168 * to avoid memory leakage, please. 162 169 */ 163 170 164 - extern struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned 171 + struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned 165 172 int cpu); 166 173 167 - extern void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *first); 174 + void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *first); 168 175 169 176 170 177 /* determine stats for cpufreq subsystem ··· 172 179 * This is not available in all kernel versions or configurations. 173 180 */ 174 181 175 - extern struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu, 182 + struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu, 176 183 unsigned long long *total_time); 177 184 178 - extern void cpufreq_put_stats(struct cpufreq_stats *stats); 185 + void cpufreq_put_stats(struct cpufreq_stats *stats); 179 186 180 - extern unsigned long cpufreq_get_transitions(unsigned int cpu); 187 + unsigned long cpufreq_get_transitions(unsigned int cpu); 181 188 182 189 183 190 /* set new cpufreq policy ··· 186 193 * but results may differ depending e.g. on governors being available. 187 194 */ 188 195 189 - extern int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy); 196 + int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy); 190 197 191 198 192 199 /* modify a policy by only changing min/max freq or governor ··· 194 201 * Does not check whether result is what was intended. 195 202 */ 196 203 197 - extern int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq); 198 - extern int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq); 199 - extern int cpufreq_modify_policy_governor(unsigned int cpu, char *governor); 204 + int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq); 205 + int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq); 206 + int cpufreq_modify_policy_governor(unsigned int cpu, char *governor); 200 207 201 208 202 209 /* set a specific frequency ··· 206 213 * occurs. Also does not work on ->range() cpufreq drivers. 207 214 */ 208 215 209 - extern int cpufreq_set_frequency(unsigned int cpu, 216 + int cpufreq_set_frequency(unsigned int cpu, 210 217 unsigned long target_frequency); 211 218 212 219 #ifdef __cplusplus
+380
tools/power/cpupower/lib/cpuidle.c
··· 1 + /* 2 + * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de> 3 + * (C) 2011 Thomas Renninger <trenn@novell.com> Novell Inc. 4 + * 5 + * Licensed under the terms of the GNU GPL License version 2. 6 + */ 7 + 8 + #include <stdio.h> 9 + #include <errno.h> 10 + #include <stdlib.h> 11 + #include <string.h> 12 + #include <sys/types.h> 13 + #include <sys/stat.h> 14 + #include <fcntl.h> 15 + #include <unistd.h> 16 + 17 + #include "cpuidle.h" 18 + #include "cpupower_intern.h" 19 + 20 + /* 21 + * helper function to check whether a file under "../cpuX/cpuidle/stateX/" dir 22 + * exists. 23 + * For example the functionality to disable c-states was introduced in later 24 + * kernel versions, this function can be used to explicitly check for this 25 + * feature. 26 + * 27 + * returns 1 if the file exists, 0 otherwise. 28 + */ 29 + static 30 + unsigned int cpuidle_state_file_exists(unsigned int cpu, 31 + unsigned int idlestate, 32 + const char *fname) 33 + { 34 + char path[SYSFS_PATH_MAX]; 35 + struct stat statbuf; 36 + 37 + 38 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", 39 + cpu, idlestate, fname); 40 + if (stat(path, &statbuf) != 0) 41 + return 0; 42 + return 1; 43 + } 44 + 45 + /* 46 + * helper function to read file from /sys into given buffer 47 + * fname is a relative path under "cpuX/cpuidle/stateX/" dir 48 + * cstates starting with 0, C0 is not counted as cstate. 49 + * This means if you want C1 info, pass 0 as idlestate param 50 + */ 51 + static 52 + unsigned int cpuidle_state_read_file(unsigned int cpu, 53 + unsigned int idlestate, 54 + const char *fname, char *buf, 55 + size_t buflen) 56 + { 57 + char path[SYSFS_PATH_MAX]; 58 + int fd; 59 + ssize_t numread; 60 + 61 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", 62 + cpu, idlestate, fname); 63 + 64 + fd = open(path, O_RDONLY); 65 + if (fd == -1) 66 + return 0; 67 + 68 + numread = read(fd, buf, buflen - 1); 69 + if (numread < 1) { 70 + close(fd); 71 + return 0; 72 + } 73 + 74 + buf[numread] = '\0'; 75 + close(fd); 76 + 77 + return (unsigned int) numread; 78 + } 79 + 80 + /* 81 + * helper function to write a new value to a /sys file 82 + * fname is a relative path under "../cpuX/cpuidle/cstateY/" dir 83 + * 84 + * Returns the number of bytes written or 0 on error 85 + */ 86 + static 87 + unsigned int cpuidle_state_write_file(unsigned int cpu, 88 + unsigned int idlestate, 89 + const char *fname, 90 + const char *value, size_t len) 91 + { 92 + char path[SYSFS_PATH_MAX]; 93 + int fd; 94 + ssize_t numwrite; 95 + 96 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", 97 + cpu, idlestate, fname); 98 + 99 + fd = open(path, O_WRONLY); 100 + if (fd == -1) 101 + return 0; 102 + 103 + numwrite = write(fd, value, len); 104 + if (numwrite < 1) { 105 + close(fd); 106 + return 0; 107 + } 108 + 109 + close(fd); 110 + 111 + return (unsigned int) numwrite; 112 + } 113 + 114 + /* read access to files which contain one numeric value */ 115 + 116 + enum idlestate_value { 117 + IDLESTATE_USAGE, 118 + IDLESTATE_POWER, 119 + IDLESTATE_LATENCY, 120 + IDLESTATE_TIME, 121 + IDLESTATE_DISABLE, 122 + MAX_IDLESTATE_VALUE_FILES 123 + }; 124 + 125 + static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = { 126 + [IDLESTATE_USAGE] = "usage", 127 + [IDLESTATE_POWER] = "power", 128 + [IDLESTATE_LATENCY] = "latency", 129 + [IDLESTATE_TIME] = "time", 130 + [IDLESTATE_DISABLE] = "disable", 131 + }; 132 + 133 + static 134 + unsigned long long cpuidle_state_get_one_value(unsigned int cpu, 135 + unsigned int idlestate, 136 + enum idlestate_value which) 137 + { 138 + unsigned long long value; 139 + unsigned int len; 140 + char linebuf[MAX_LINE_LEN]; 141 + char *endp; 142 + 143 + if (which >= MAX_IDLESTATE_VALUE_FILES) 144 + return 0; 145 + 146 + len = cpuidle_state_read_file(cpu, idlestate, 147 + idlestate_value_files[which], 148 + linebuf, sizeof(linebuf)); 149 + if (len == 0) 150 + return 0; 151 + 152 + value = strtoull(linebuf, &endp, 0); 153 + 154 + if (endp == linebuf || errno == ERANGE) 155 + return 0; 156 + 157 + return value; 158 + } 159 + 160 + /* read access to files which contain one string */ 161 + 162 + enum idlestate_string { 163 + IDLESTATE_DESC, 164 + IDLESTATE_NAME, 165 + MAX_IDLESTATE_STRING_FILES 166 + }; 167 + 168 + static const char *idlestate_string_files[MAX_IDLESTATE_STRING_FILES] = { 169 + [IDLESTATE_DESC] = "desc", 170 + [IDLESTATE_NAME] = "name", 171 + }; 172 + 173 + 174 + static char *cpuidle_state_get_one_string(unsigned int cpu, 175 + unsigned int idlestate, 176 + enum idlestate_string which) 177 + { 178 + char linebuf[MAX_LINE_LEN]; 179 + char *result; 180 + unsigned int len; 181 + 182 + if (which >= MAX_IDLESTATE_STRING_FILES) 183 + return NULL; 184 + 185 + len = cpuidle_state_read_file(cpu, idlestate, 186 + idlestate_string_files[which], 187 + linebuf, sizeof(linebuf)); 188 + if (len == 0) 189 + return NULL; 190 + 191 + result = strdup(linebuf); 192 + if (result == NULL) 193 + return NULL; 194 + 195 + if (result[strlen(result) - 1] == '\n') 196 + result[strlen(result) - 1] = '\0'; 197 + 198 + return result; 199 + } 200 + 201 + /* 202 + * Returns: 203 + * 1 if disabled 204 + * 0 if enabled 205 + * -1 if idlestate is not available 206 + * -2 if disabling is not supported by the kernel 207 + */ 208 + int cpuidle_is_state_disabled(unsigned int cpu, 209 + unsigned int idlestate) 210 + { 211 + if (cpuidle_state_count(cpu) <= idlestate) 212 + return -1; 213 + 214 + if (!cpuidle_state_file_exists(cpu, idlestate, 215 + idlestate_value_files[IDLESTATE_DISABLE])) 216 + return -2; 217 + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_DISABLE); 218 + } 219 + 220 + /* 221 + * Pass 1 as last argument to disable or 0 to enable the state 222 + * Returns: 223 + * 0 on success 224 + * negative values on error, for example: 225 + * -1 if idlestate is not available 226 + * -2 if disabling is not supported by the kernel 227 + * -3 No write access to disable/enable C-states 228 + */ 229 + int cpuidle_state_disable(unsigned int cpu, 230 + unsigned int idlestate, 231 + unsigned int disable) 232 + { 233 + char value[SYSFS_PATH_MAX]; 234 + int bytes_written; 235 + 236 + if (cpuidle_state_count(cpu) <= idlestate) 237 + return -1; 238 + 239 + if (!cpuidle_state_file_exists(cpu, idlestate, 240 + idlestate_value_files[IDLESTATE_DISABLE])) 241 + return -2; 242 + 243 + snprintf(value, SYSFS_PATH_MAX, "%u", disable); 244 + 245 + bytes_written = cpuidle_state_write_file(cpu, idlestate, "disable", 246 + value, sizeof(disable)); 247 + if (bytes_written) 248 + return 0; 249 + return -3; 250 + } 251 + 252 + unsigned long cpuidle_state_latency(unsigned int cpu, 253 + unsigned int idlestate) 254 + { 255 + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); 256 + } 257 + 258 + unsigned long cpuidle_state_usage(unsigned int cpu, 259 + unsigned int idlestate) 260 + { 261 + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_USAGE); 262 + } 263 + 264 + unsigned long long cpuidle_state_time(unsigned int cpu, 265 + unsigned int idlestate) 266 + { 267 + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_TIME); 268 + } 269 + 270 + char *cpuidle_state_name(unsigned int cpu, unsigned int idlestate) 271 + { 272 + return cpuidle_state_get_one_string(cpu, idlestate, IDLESTATE_NAME); 273 + } 274 + 275 + char *cpuidle_state_desc(unsigned int cpu, unsigned int idlestate) 276 + { 277 + return cpuidle_state_get_one_string(cpu, idlestate, IDLESTATE_DESC); 278 + } 279 + 280 + /* 281 + * Returns number of supported C-states of CPU core cpu 282 + * Negativ in error case 283 + * Zero if cpuidle does not export any C-states 284 + */ 285 + unsigned int cpuidle_state_count(unsigned int cpu) 286 + { 287 + char file[SYSFS_PATH_MAX]; 288 + struct stat statbuf; 289 + int idlestates = 1; 290 + 291 + 292 + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle"); 293 + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) 294 + return 0; 295 + 296 + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu); 297 + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) 298 + return 0; 299 + 300 + while (stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { 301 + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU 302 + "cpu%u/cpuidle/state%d", cpu, idlestates); 303 + idlestates++; 304 + } 305 + idlestates--; 306 + return idlestates; 307 + } 308 + 309 + /* CPUidle general /sys/devices/system/cpu/cpuidle/ sysfs access ********/ 310 + 311 + /* 312 + * helper function to read file from /sys into given buffer 313 + * fname is a relative path under "cpu/cpuidle/" dir 314 + */ 315 + static unsigned int sysfs_cpuidle_read_file(const char *fname, char *buf, 316 + size_t buflen) 317 + { 318 + char path[SYSFS_PATH_MAX]; 319 + 320 + snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname); 321 + 322 + return sysfs_read_file(path, buf, buflen); 323 + } 324 + 325 + 326 + 327 + /* read access to files which contain one string */ 328 + 329 + enum cpuidle_string { 330 + CPUIDLE_GOVERNOR, 331 + CPUIDLE_GOVERNOR_RO, 332 + CPUIDLE_DRIVER, 333 + MAX_CPUIDLE_STRING_FILES 334 + }; 335 + 336 + static const char *cpuidle_string_files[MAX_CPUIDLE_STRING_FILES] = { 337 + [CPUIDLE_GOVERNOR] = "current_governor", 338 + [CPUIDLE_GOVERNOR_RO] = "current_governor_ro", 339 + [CPUIDLE_DRIVER] = "current_driver", 340 + }; 341 + 342 + 343 + static char *sysfs_cpuidle_get_one_string(enum cpuidle_string which) 344 + { 345 + char linebuf[MAX_LINE_LEN]; 346 + char *result; 347 + unsigned int len; 348 + 349 + if (which >= MAX_CPUIDLE_STRING_FILES) 350 + return NULL; 351 + 352 + len = sysfs_cpuidle_read_file(cpuidle_string_files[which], 353 + linebuf, sizeof(linebuf)); 354 + if (len == 0) 355 + return NULL; 356 + 357 + result = strdup(linebuf); 358 + if (result == NULL) 359 + return NULL; 360 + 361 + if (result[strlen(result) - 1] == '\n') 362 + result[strlen(result) - 1] = '\0'; 363 + 364 + return result; 365 + } 366 + 367 + char *cpuidle_get_governor(void) 368 + { 369 + char *tmp = sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR_RO); 370 + if (!tmp) 371 + return sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR); 372 + else 373 + return tmp; 374 + } 375 + 376 + char *cpuidle_get_driver(void) 377 + { 378 + return sysfs_cpuidle_get_one_string(CPUIDLE_DRIVER); 379 + } 380 + /* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
+23
tools/power/cpupower/lib/cpuidle.h
··· 1 + #ifndef __CPUPOWER_CPUIDLE_H__ 2 + #define __CPUPOWER_CPUIDLE_H__ 3 + 4 + int cpuidle_is_state_disabled(unsigned int cpu, 5 + unsigned int idlestate); 6 + int cpuidle_state_disable(unsigned int cpu, unsigned int idlestate, 7 + unsigned int disable); 8 + unsigned long cpuidle_state_latency(unsigned int cpu, 9 + unsigned int idlestate); 10 + unsigned long cpuidle_state_usage(unsigned int cpu, 11 + unsigned int idlestate); 12 + unsigned long long cpuidle_state_time(unsigned int cpu, 13 + unsigned int idlestate); 14 + char *cpuidle_state_name(unsigned int cpu, 15 + unsigned int idlestate); 16 + char *cpuidle_state_desc(unsigned int cpu, 17 + unsigned int idlestate); 18 + unsigned int cpuidle_state_count(unsigned int cpu); 19 + 20 + char *cpuidle_get_governor(void); 21 + char *cpuidle_get_driver(void); 22 + 23 + #endif /* __CPUPOWER_HELPERS_SYSFS_H__ */
+192
tools/power/cpupower/lib/cpupower.c
··· 1 + /* 2 + * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de> 3 + * 4 + * Licensed under the terms of the GNU GPL License version 2. 5 + */ 6 + 7 + #include <sys/types.h> 8 + #include <sys/stat.h> 9 + #include <fcntl.h> 10 + #include <unistd.h> 11 + #include <stdio.h> 12 + #include <errno.h> 13 + #include <stdlib.h> 14 + 15 + #include "cpupower.h" 16 + #include "cpupower_intern.h" 17 + 18 + unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) 19 + { 20 + int fd; 21 + ssize_t numread; 22 + 23 + fd = open(path, O_RDONLY); 24 + if (fd == -1) 25 + return 0; 26 + 27 + numread = read(fd, buf, buflen - 1); 28 + if (numread < 1) { 29 + close(fd); 30 + return 0; 31 + } 32 + 33 + buf[numread] = '\0'; 34 + close(fd); 35 + 36 + return (unsigned int) numread; 37 + } 38 + 39 + /* 40 + * Detect whether a CPU is online 41 + * 42 + * Returns: 43 + * 1 -> if CPU is online 44 + * 0 -> if CPU is offline 45 + * negative errno values in error case 46 + */ 47 + int cpupower_is_cpu_online(unsigned int cpu) 48 + { 49 + char path[SYSFS_PATH_MAX]; 50 + int fd; 51 + ssize_t numread; 52 + unsigned long long value; 53 + char linebuf[MAX_LINE_LEN]; 54 + char *endp; 55 + struct stat statbuf; 56 + 57 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu); 58 + 59 + if (stat(path, &statbuf) != 0) 60 + return 0; 61 + 62 + /* 63 + * kernel without CONFIG_HOTPLUG_CPU 64 + * -> cpuX directory exists, but not cpuX/online file 65 + */ 66 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu); 67 + if (stat(path, &statbuf) != 0) 68 + return 1; 69 + 70 + fd = open(path, O_RDONLY); 71 + if (fd == -1) 72 + return -errno; 73 + 74 + numread = read(fd, linebuf, MAX_LINE_LEN - 1); 75 + if (numread < 1) { 76 + close(fd); 77 + return -EIO; 78 + } 79 + linebuf[numread] = '\0'; 80 + close(fd); 81 + 82 + value = strtoull(linebuf, &endp, 0); 83 + if (value > 1) 84 + return -EINVAL; 85 + 86 + return value; 87 + } 88 + 89 + /* returns -1 on failure, 0 on success */ 90 + static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result) 91 + { 92 + char linebuf[MAX_LINE_LEN]; 93 + char *endp; 94 + char path[SYSFS_PATH_MAX]; 95 + 96 + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", 97 + cpu, fname); 98 + if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) 99 + return -1; 100 + *result = strtol(linebuf, &endp, 0); 101 + if (endp == linebuf || errno == ERANGE) 102 + return -1; 103 + return 0; 104 + } 105 + 106 + static int __compare(const void *t1, const void *t2) 107 + { 108 + struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1; 109 + struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2; 110 + if (top1->pkg < top2->pkg) 111 + return -1; 112 + else if (top1->pkg > top2->pkg) 113 + return 1; 114 + else if (top1->core < top2->core) 115 + return -1; 116 + else if (top1->core > top2->core) 117 + return 1; 118 + else if (top1->cpu < top2->cpu) 119 + return -1; 120 + else if (top1->cpu > top2->cpu) 121 + return 1; 122 + else 123 + return 0; 124 + } 125 + 126 + /* 127 + * Returns amount of cpus, negative on error, cpu_top must be 128 + * passed to cpu_topology_release to free resources 129 + * 130 + * Array is sorted after ->pkg, ->core, then ->cpu 131 + */ 132 + int get_cpu_topology(struct cpupower_topology *cpu_top) 133 + { 134 + int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF); 135 + 136 + cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus); 137 + if (cpu_top->core_info == NULL) 138 + return -ENOMEM; 139 + cpu_top->pkgs = cpu_top->cores = 0; 140 + for (cpu = 0; cpu < cpus; cpu++) { 141 + cpu_top->core_info[cpu].cpu = cpu; 142 + cpu_top->core_info[cpu].is_online = cpupower_is_cpu_online(cpu); 143 + if(sysfs_topology_read_file( 144 + cpu, 145 + "physical_package_id", 146 + &(cpu_top->core_info[cpu].pkg)) < 0) { 147 + cpu_top->core_info[cpu].pkg = -1; 148 + cpu_top->core_info[cpu].core = -1; 149 + continue; 150 + } 151 + if(sysfs_topology_read_file( 152 + cpu, 153 + "core_id", 154 + &(cpu_top->core_info[cpu].core)) < 0) { 155 + cpu_top->core_info[cpu].pkg = -1; 156 + cpu_top->core_info[cpu].core = -1; 157 + continue; 158 + } 159 + } 160 + 161 + qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), 162 + __compare); 163 + 164 + /* Count the number of distinct pkgs values. This works 165 + because the primary sort of the core_info struct was just 166 + done by pkg value. */ 167 + last_pkg = cpu_top->core_info[0].pkg; 168 + for(cpu = 1; cpu < cpus; cpu++) { 169 + if (cpu_top->core_info[cpu].pkg != last_pkg && 170 + cpu_top->core_info[cpu].pkg != -1) { 171 + 172 + last_pkg = cpu_top->core_info[cpu].pkg; 173 + cpu_top->pkgs++; 174 + } 175 + } 176 + if (!(cpu_top->core_info[0].pkg == -1)) 177 + cpu_top->pkgs++; 178 + 179 + /* Intel's cores count is not consecutively numbered, there may 180 + * be a core_id of 3, but none of 2. Assume there always is 0 181 + * Get amount of cores by counting duplicates in a package 182 + for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) { 183 + if (cpu_top->core_info[cpu].core == 0) 184 + cpu_top->cores++; 185 + */ 186 + return cpus; 187 + } 188 + 189 + void cpu_topology_release(struct cpupower_topology cpu_top) 190 + { 191 + free(cpu_top.core_info); 192 + }
+35
tools/power/cpupower/lib/cpupower.h
··· 1 + #ifndef __CPUPOWER_CPUPOWER_H__ 2 + #define __CPUPOWER_CPUPOWER_H__ 3 + 4 + struct cpupower_topology { 5 + /* Amount of CPU cores, packages and threads per core in the system */ 6 + unsigned int cores; 7 + unsigned int pkgs; 8 + unsigned int threads; /* per core */ 9 + 10 + /* Array gets mallocated with cores entries, holding per core info */ 11 + struct cpuid_core_info *core_info; 12 + }; 13 + 14 + struct cpuid_core_info { 15 + int pkg; 16 + int core; 17 + int cpu; 18 + 19 + /* flags */ 20 + unsigned int is_online:1; 21 + }; 22 + 23 + #ifdef __cplusplus 24 + extern "C" { 25 + #endif 26 + 27 + int get_cpu_topology(struct cpupower_topology *cpu_top); 28 + void cpu_topology_release(struct cpupower_topology cpu_top); 29 + int cpupower_is_cpu_online(unsigned int cpu); 30 + 31 + #ifdef __cplusplus 32 + } 33 + #endif 34 + 35 + #endif
+5
tools/power/cpupower/lib/cpupower_intern.h
··· 1 + #define PATH_TO_CPU "/sys/devices/system/cpu/" 2 + #define MAX_LINE_LEN 4096 3 + #define SYSFS_PATH_MAX 255 4 + 5 + unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
-672
tools/power/cpupower/lib/sysfs.c
··· 1 - /* 2 - * (C) 2004-2009 Dominik Brodowski <linux@dominikbrodowski.de> 3 - * 4 - * Licensed under the terms of the GNU GPL License version 2. 5 - */ 6 - 7 - #include <stdio.h> 8 - #include <errno.h> 9 - #include <stdlib.h> 10 - #include <string.h> 11 - #include <limits.h> 12 - #include <sys/types.h> 13 - #include <sys/stat.h> 14 - #include <fcntl.h> 15 - #include <unistd.h> 16 - 17 - #include "cpufreq.h" 18 - 19 - #define PATH_TO_CPU "/sys/devices/system/cpu/" 20 - #define MAX_LINE_LEN 4096 21 - #define SYSFS_PATH_MAX 255 22 - 23 - 24 - static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) 25 - { 26 - int fd; 27 - ssize_t numread; 28 - 29 - fd = open(path, O_RDONLY); 30 - if (fd == -1) 31 - return 0; 32 - 33 - numread = read(fd, buf, buflen - 1); 34 - if (numread < 1) { 35 - close(fd); 36 - return 0; 37 - } 38 - 39 - buf[numread] = '\0'; 40 - close(fd); 41 - 42 - return (unsigned int) numread; 43 - } 44 - 45 - 46 - /* CPUFREQ sysfs access **************************************************/ 47 - 48 - /* helper function to read file from /sys into given buffer */ 49 - /* fname is a relative path under "cpuX/cpufreq" dir */ 50 - static unsigned int sysfs_cpufreq_read_file(unsigned int cpu, const char *fname, 51 - char *buf, size_t buflen) 52 - { 53 - char path[SYSFS_PATH_MAX]; 54 - 55 - snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", 56 - cpu, fname); 57 - return sysfs_read_file(path, buf, buflen); 58 - } 59 - 60 - /* helper function to write a new value to a /sys file */ 61 - /* fname is a relative path under "cpuX/cpufreq" dir */ 62 - static unsigned int sysfs_cpufreq_write_file(unsigned int cpu, 63 - const char *fname, 64 - const char *value, size_t len) 65 - { 66 - char path[SYSFS_PATH_MAX]; 67 - int fd; 68 - ssize_t numwrite; 69 - 70 - snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", 71 - cpu, fname); 72 - 73 - fd = open(path, O_WRONLY); 74 - if (fd == -1) 75 - return 0; 76 - 77 - numwrite = write(fd, value, len); 78 - if (numwrite < 1) { 79 - close(fd); 80 - return 0; 81 - } 82 - 83 - close(fd); 84 - 85 - return (unsigned int) numwrite; 86 - } 87 - 88 - /* read access to files which contain one numeric value */ 89 - 90 - enum cpufreq_value { 91 - CPUINFO_CUR_FREQ, 92 - CPUINFO_MIN_FREQ, 93 - CPUINFO_MAX_FREQ, 94 - CPUINFO_LATENCY, 95 - SCALING_CUR_FREQ, 96 - SCALING_MIN_FREQ, 97 - SCALING_MAX_FREQ, 98 - STATS_NUM_TRANSITIONS, 99 - MAX_CPUFREQ_VALUE_READ_FILES 100 - }; 101 - 102 - static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = { 103 - [CPUINFO_CUR_FREQ] = "cpuinfo_cur_freq", 104 - [CPUINFO_MIN_FREQ] = "cpuinfo_min_freq", 105 - [CPUINFO_MAX_FREQ] = "cpuinfo_max_freq", 106 - [CPUINFO_LATENCY] = "cpuinfo_transition_latency", 107 - [SCALING_CUR_FREQ] = "scaling_cur_freq", 108 - [SCALING_MIN_FREQ] = "scaling_min_freq", 109 - [SCALING_MAX_FREQ] = "scaling_max_freq", 110 - [STATS_NUM_TRANSITIONS] = "stats/total_trans" 111 - }; 112 - 113 - 114 - static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, 115 - enum cpufreq_value which) 116 - { 117 - unsigned long value; 118 - unsigned int len; 119 - char linebuf[MAX_LINE_LEN]; 120 - char *endp; 121 - 122 - if (which >= MAX_CPUFREQ_VALUE_READ_FILES) 123 - return 0; 124 - 125 - len = sysfs_cpufreq_read_file(cpu, cpufreq_value_files[which], 126 - linebuf, sizeof(linebuf)); 127 - 128 - if (len == 0) 129 - return 0; 130 - 131 - value = strtoul(linebuf, &endp, 0); 132 - 133 - if (endp == linebuf || errno == ERANGE) 134 - return 0; 135 - 136 - return value; 137 - } 138 - 139 - /* read access to files which contain one string */ 140 - 141 - enum cpufreq_string { 142 - SCALING_DRIVER, 143 - SCALING_GOVERNOR, 144 - MAX_CPUFREQ_STRING_FILES 145 - }; 146 - 147 - static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES] = { 148 - [SCALING_DRIVER] = "scaling_driver", 149 - [SCALING_GOVERNOR] = "scaling_governor", 150 - }; 151 - 152 - 153 - static char *sysfs_cpufreq_get_one_string(unsigned int cpu, 154 - enum cpufreq_string which) 155 - { 156 - char linebuf[MAX_LINE_LEN]; 157 - char *result; 158 - unsigned int len; 159 - 160 - if (which >= MAX_CPUFREQ_STRING_FILES) 161 - return NULL; 162 - 163 - len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which], 164 - linebuf, sizeof(linebuf)); 165 - if (len == 0) 166 - return NULL; 167 - 168 - result = strdup(linebuf); 169 - if (result == NULL) 170 - return NULL; 171 - 172 - if (result[strlen(result) - 1] == '\n') 173 - result[strlen(result) - 1] = '\0'; 174 - 175 - return result; 176 - } 177 - 178 - /* write access */ 179 - 180 - enum cpufreq_write { 181 - WRITE_SCALING_MIN_FREQ, 182 - WRITE_SCALING_MAX_FREQ, 183 - WRITE_SCALING_GOVERNOR, 184 - WRITE_SCALING_SET_SPEED, 185 - MAX_CPUFREQ_WRITE_FILES 186 - }; 187 - 188 - static const char *cpufreq_write_files[MAX_CPUFREQ_WRITE_FILES] = { 189 - [WRITE_SCALING_MIN_FREQ] = "scaling_min_freq", 190 - [WRITE_SCALING_MAX_FREQ] = "scaling_max_freq", 191 - [WRITE_SCALING_GOVERNOR] = "scaling_governor", 192 - [WRITE_SCALING_SET_SPEED] = "scaling_setspeed", 193 - }; 194 - 195 - static int sysfs_cpufreq_write_one_value(unsigned int cpu, 196 - enum cpufreq_write which, 197 - const char *new_value, size_t len) 198 - { 199 - if (which >= MAX_CPUFREQ_WRITE_FILES) 200 - return 0; 201 - 202 - if (sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which], 203 - new_value, len) != len) 204 - return -ENODEV; 205 - 206 - return 0; 207 - }; 208 - 209 - unsigned long sysfs_get_freq_kernel(unsigned int cpu) 210 - { 211 - return sysfs_cpufreq_get_one_value(cpu, SCALING_CUR_FREQ); 212 - } 213 - 214 - unsigned long sysfs_get_freq_hardware(unsigned int cpu) 215 - { 216 - return sysfs_cpufreq_get_one_value(cpu, CPUINFO_CUR_FREQ); 217 - } 218 - 219 - unsigned long sysfs_get_freq_transition_latency(unsigned int cpu) 220 - { 221 - return sysfs_cpufreq_get_one_value(cpu, CPUINFO_LATENCY); 222 - } 223 - 224 - int sysfs_get_freq_hardware_limits(unsigned int cpu, 225 - unsigned long *min, 226 - unsigned long *max) 227 - { 228 - if ((!min) || (!max)) 229 - return -EINVAL; 230 - 231 - *min = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MIN_FREQ); 232 - if (!*min) 233 - return -ENODEV; 234 - 235 - *max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ); 236 - if (!*max) 237 - return -ENODEV; 238 - 239 - return 0; 240 - } 241 - 242 - char *sysfs_get_freq_driver(unsigned int cpu) 243 - { 244 - return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER); 245 - } 246 - 247 - struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu) 248 - { 249 - struct cpufreq_policy *policy; 250 - 251 - policy = malloc(sizeof(struct cpufreq_policy)); 252 - if (!policy) 253 - return NULL; 254 - 255 - policy->governor = sysfs_cpufreq_get_one_string(cpu, SCALING_GOVERNOR); 256 - if (!policy->governor) { 257 - free(policy); 258 - return NULL; 259 - } 260 - policy->min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ); 261 - policy->max = sysfs_cpufreq_get_one_value(cpu, SCALING_MAX_FREQ); 262 - if ((!policy->min) || (!policy->max)) { 263 - free(policy->governor); 264 - free(policy); 265 - return NULL; 266 - } 267 - 268 - return policy; 269 - } 270 - 271 - struct cpufreq_available_governors * 272 - sysfs_get_freq_available_governors(unsigned int cpu) { 273 - struct cpufreq_available_governors *first = NULL; 274 - struct cpufreq_available_governors *current = NULL; 275 - char linebuf[MAX_LINE_LEN]; 276 - unsigned int pos, i; 277 - unsigned int len; 278 - 279 - len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors", 280 - linebuf, sizeof(linebuf)); 281 - if (len == 0) 282 - return NULL; 283 - 284 - pos = 0; 285 - for (i = 0; i < len; i++) { 286 - if (linebuf[i] == ' ' || linebuf[i] == '\n') { 287 - if (i - pos < 2) 288 - continue; 289 - if (current) { 290 - current->next = malloc(sizeof(*current)); 291 - if (!current->next) 292 - goto error_out; 293 - current = current->next; 294 - } else { 295 - first = malloc(sizeof(*first)); 296 - if (!first) 297 - goto error_out; 298 - current = first; 299 - } 300 - current->first = first; 301 - current->next = NULL; 302 - 303 - current->governor = malloc(i - pos + 1); 304 - if (!current->governor) 305 - goto error_out; 306 - 307 - memcpy(current->governor, linebuf + pos, i - pos); 308 - current->governor[i - pos] = '\0'; 309 - pos = i + 1; 310 - } 311 - } 312 - 313 - return first; 314 - 315 - error_out: 316 - while (first) { 317 - current = first->next; 318 - if (first->governor) 319 - free(first->governor); 320 - free(first); 321 - first = current; 322 - } 323 - return NULL; 324 - } 325 - 326 - 327 - struct cpufreq_available_frequencies * 328 - sysfs_get_available_frequencies(unsigned int cpu) { 329 - struct cpufreq_available_frequencies *first = NULL; 330 - struct cpufreq_available_frequencies *current = NULL; 331 - char one_value[SYSFS_PATH_MAX]; 332 - char linebuf[MAX_LINE_LEN]; 333 - unsigned int pos, i; 334 - unsigned int len; 335 - 336 - len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies", 337 - linebuf, sizeof(linebuf)); 338 - if (len == 0) 339 - return NULL; 340 - 341 - pos = 0; 342 - for (i = 0; i < len; i++) { 343 - if (linebuf[i] == ' ' || linebuf[i] == '\n') { 344 - if (i - pos < 2) 345 - continue; 346 - if (i - pos >= SYSFS_PATH_MAX) 347 - goto error_out; 348 - if (current) { 349 - current->next = malloc(sizeof(*current)); 350 - if (!current->next) 351 - goto error_out; 352 - current = current->next; 353 - } else { 354 - first = malloc(sizeof(*first)); 355 - if (!first) 356 - goto error_out; 357 - current = first; 358 - } 359 - current->first = first; 360 - current->next = NULL; 361 - 362 - memcpy(one_value, linebuf + pos, i - pos); 363 - one_value[i - pos] = '\0'; 364 - if (sscanf(one_value, "%lu", &current->frequency) != 1) 365 - goto error_out; 366 - 367 - pos = i + 1; 368 - } 369 - } 370 - 371 - return first; 372 - 373 - error_out: 374 - while (first) { 375 - current = first->next; 376 - free(first); 377 - first = current; 378 - } 379 - return NULL; 380 - } 381 - 382 - static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu, 383 - const char *file) 384 - { 385 - struct cpufreq_affected_cpus *first = NULL; 386 - struct cpufreq_affected_cpus *current = NULL; 387 - char one_value[SYSFS_PATH_MAX]; 388 - char linebuf[MAX_LINE_LEN]; 389 - unsigned int pos, i; 390 - unsigned int len; 391 - 392 - len = sysfs_cpufreq_read_file(cpu, file, linebuf, sizeof(linebuf)); 393 - if (len == 0) 394 - return NULL; 395 - 396 - pos = 0; 397 - for (i = 0; i < len; i++) { 398 - if (i == len || linebuf[i] == ' ' || linebuf[i] == '\n') { 399 - if (i - pos < 1) 400 - continue; 401 - if (i - pos >= SYSFS_PATH_MAX) 402 - goto error_out; 403 - if (current) { 404 - current->next = malloc(sizeof(*current)); 405 - if (!current->next) 406 - goto error_out; 407 - current = current->next; 408 - } else { 409 - first = malloc(sizeof(*first)); 410 - if (!first) 411 - goto error_out; 412 - current = first; 413 - } 414 - current->first = first; 415 - current->next = NULL; 416 - 417 - memcpy(one_value, linebuf + pos, i - pos); 418 - one_value[i - pos] = '\0'; 419 - 420 - if (sscanf(one_value, "%u", &current->cpu) != 1) 421 - goto error_out; 422 - 423 - pos = i + 1; 424 - } 425 - } 426 - 427 - return first; 428 - 429 - error_out: 430 - while (first) { 431 - current = first->next; 432 - free(first); 433 - first = current; 434 - } 435 - return NULL; 436 - } 437 - 438 - struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus(unsigned int cpu) 439 - { 440 - return sysfs_get_cpu_list(cpu, "affected_cpus"); 441 - } 442 - 443 - struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus(unsigned int cpu) 444 - { 445 - return sysfs_get_cpu_list(cpu, "related_cpus"); 446 - } 447 - 448 - struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu, 449 - unsigned long long *total_time) { 450 - struct cpufreq_stats *first = NULL; 451 - struct cpufreq_stats *current = NULL; 452 - char one_value[SYSFS_PATH_MAX]; 453 - char linebuf[MAX_LINE_LEN]; 454 - unsigned int pos, i; 455 - unsigned int len; 456 - 457 - len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state", 458 - linebuf, sizeof(linebuf)); 459 - if (len == 0) 460 - return NULL; 461 - 462 - *total_time = 0; 463 - pos = 0; 464 - for (i = 0; i < len; i++) { 465 - if (i == strlen(linebuf) || linebuf[i] == '\n') { 466 - if (i - pos < 2) 467 - continue; 468 - if ((i - pos) >= SYSFS_PATH_MAX) 469 - goto error_out; 470 - if (current) { 471 - current->next = malloc(sizeof(*current)); 472 - if (!current->next) 473 - goto error_out; 474 - current = current->next; 475 - } else { 476 - first = malloc(sizeof(*first)); 477 - if (!first) 478 - goto error_out; 479 - current = first; 480 - } 481 - current->first = first; 482 - current->next = NULL; 483 - 484 - memcpy(one_value, linebuf + pos, i - pos); 485 - one_value[i - pos] = '\0'; 486 - if (sscanf(one_value, "%lu %llu", 487 - &current->frequency, 488 - &current->time_in_state) != 2) 489 - goto error_out; 490 - 491 - *total_time = *total_time + current->time_in_state; 492 - pos = i + 1; 493 - } 494 - } 495 - 496 - return first; 497 - 498 - error_out: 499 - while (first) { 500 - current = first->next; 501 - free(first); 502 - first = current; 503 - } 504 - return NULL; 505 - } 506 - 507 - unsigned long sysfs_get_freq_transitions(unsigned int cpu) 508 - { 509 - return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS); 510 - } 511 - 512 - static int verify_gov(char *new_gov, char *passed_gov) 513 - { 514 - unsigned int i, j = 0; 515 - 516 - if (!passed_gov || (strlen(passed_gov) > 19)) 517 - return -EINVAL; 518 - 519 - strncpy(new_gov, passed_gov, 20); 520 - for (i = 0; i < 20; i++) { 521 - if (j) { 522 - new_gov[i] = '\0'; 523 - continue; 524 - } 525 - if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z')) 526 - continue; 527 - 528 - if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z')) 529 - continue; 530 - 531 - if (new_gov[i] == '-') 532 - continue; 533 - 534 - if (new_gov[i] == '_') 535 - continue; 536 - 537 - if (new_gov[i] == '\0') { 538 - j = 1; 539 - continue; 540 - } 541 - return -EINVAL; 542 - } 543 - new_gov[19] = '\0'; 544 - return 0; 545 - } 546 - 547 - int sysfs_modify_freq_policy_governor(unsigned int cpu, char *governor) 548 - { 549 - char new_gov[SYSFS_PATH_MAX]; 550 - 551 - if (!governor) 552 - return -EINVAL; 553 - 554 - if (verify_gov(new_gov, governor)) 555 - return -EINVAL; 556 - 557 - return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR, 558 - new_gov, strlen(new_gov)); 559 - }; 560 - 561 - int sysfs_modify_freq_policy_max(unsigned int cpu, unsigned long max_freq) 562 - { 563 - char value[SYSFS_PATH_MAX]; 564 - 565 - snprintf(value, SYSFS_PATH_MAX, "%lu", max_freq); 566 - 567 - return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, 568 - value, strlen(value)); 569 - }; 570 - 571 - 572 - int sysfs_modify_freq_policy_min(unsigned int cpu, unsigned long min_freq) 573 - { 574 - char value[SYSFS_PATH_MAX]; 575 - 576 - snprintf(value, SYSFS_PATH_MAX, "%lu", min_freq); 577 - 578 - return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, 579 - value, strlen(value)); 580 - }; 581 - 582 - 583 - int sysfs_set_freq_policy(unsigned int cpu, struct cpufreq_policy *policy) 584 - { 585 - char min[SYSFS_PATH_MAX]; 586 - char max[SYSFS_PATH_MAX]; 587 - char gov[SYSFS_PATH_MAX]; 588 - int ret; 589 - unsigned long old_min; 590 - int write_max_first; 591 - 592 - if (!policy || !(policy->governor)) 593 - return -EINVAL; 594 - 595 - if (policy->max < policy->min) 596 - return -EINVAL; 597 - 598 - if (verify_gov(gov, policy->governor)) 599 - return -EINVAL; 600 - 601 - snprintf(min, SYSFS_PATH_MAX, "%lu", policy->min); 602 - snprintf(max, SYSFS_PATH_MAX, "%lu", policy->max); 603 - 604 - old_min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ); 605 - write_max_first = (old_min && (policy->max < old_min) ? 0 : 1); 606 - 607 - if (write_max_first) { 608 - ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, 609 - max, strlen(max)); 610 - if (ret) 611 - return ret; 612 - } 613 - 614 - ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, min, 615 - strlen(min)); 616 - if (ret) 617 - return ret; 618 - 619 - if (!write_max_first) { 620 - ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, 621 - max, strlen(max)); 622 - if (ret) 623 - return ret; 624 - } 625 - 626 - return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR, 627 - gov, strlen(gov)); 628 - } 629 - 630 - int sysfs_set_frequency(unsigned int cpu, unsigned long target_frequency) 631 - { 632 - struct cpufreq_policy *pol = sysfs_get_freq_policy(cpu); 633 - char userspace_gov[] = "userspace"; 634 - char freq[SYSFS_PATH_MAX]; 635 - int ret; 636 - 637 - if (!pol) 638 - return -ENODEV; 639 - 640 - if (strncmp(pol->governor, userspace_gov, 9) != 0) { 641 - ret = sysfs_modify_freq_policy_governor(cpu, userspace_gov); 642 - if (ret) { 643 - cpufreq_put_policy(pol); 644 - return ret; 645 - } 646 - } 647 - 648 - cpufreq_put_policy(pol); 649 - 650 - snprintf(freq, SYSFS_PATH_MAX, "%lu", target_frequency); 651 - 652 - return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_SET_SPEED, 653 - freq, strlen(freq)); 654 - } 655 - 656 - /* CPUFREQ sysfs access **************************************************/ 657 - 658 - /* General sysfs access **************************************************/ 659 - int sysfs_cpu_exists(unsigned int cpu) 660 - { 661 - char file[SYSFS_PATH_MAX]; 662 - struct stat statbuf; 663 - 664 - snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/", cpu); 665 - 666 - if (stat(file, &statbuf) != 0) 667 - return -ENOSYS; 668 - 669 - return S_ISDIR(statbuf.st_mode) ? 0 : -ENOSYS; 670 - } 671 - 672 - /* General sysfs access **************************************************/
-31
tools/power/cpupower/lib/sysfs.h
··· 1 - /* General */ 2 - extern unsigned int sysfs_cpu_exists(unsigned int cpu); 3 - 4 - /* CPUfreq */ 5 - extern unsigned long sysfs_get_freq_kernel(unsigned int cpu); 6 - extern unsigned long sysfs_get_freq_hardware(unsigned int cpu); 7 - extern unsigned long sysfs_get_freq_transition_latency(unsigned int cpu); 8 - extern int sysfs_get_freq_hardware_limits(unsigned int cpu, 9 - unsigned long *min, unsigned long *max); 10 - extern char *sysfs_get_freq_driver(unsigned int cpu); 11 - extern struct cpufreq_policy *sysfs_get_freq_policy(unsigned int cpu); 12 - extern struct cpufreq_available_governors *sysfs_get_freq_available_governors( 13 - unsigned int cpu); 14 - extern struct cpufreq_available_frequencies *sysfs_get_available_frequencies( 15 - unsigned int cpu); 16 - extern struct cpufreq_affected_cpus *sysfs_get_freq_affected_cpus( 17 - unsigned int cpu); 18 - extern struct cpufreq_affected_cpus *sysfs_get_freq_related_cpus( 19 - unsigned int cpu); 20 - extern struct cpufreq_stats *sysfs_get_freq_stats(unsigned int cpu, 21 - unsigned long long *total_time); 22 - extern unsigned long sysfs_get_freq_transitions(unsigned int cpu); 23 - extern int sysfs_set_freq_policy(unsigned int cpu, 24 - struct cpufreq_policy *policy); 25 - extern int sysfs_modify_freq_policy_min(unsigned int cpu, 26 - unsigned long min_freq); 27 - extern int sysfs_modify_freq_policy_max(unsigned int cpu, 28 - unsigned long max_freq); 29 - extern int sysfs_modify_freq_policy_governor(unsigned int cpu, char *governor); 30 - extern int sysfs_set_frequency(unsigned int cpu, 31 - unsigned long target_frequency);
+4 -4
tools/power/cpupower/utils/cpufreq-set.c
··· 16 16 #include <getopt.h> 17 17 18 18 #include "cpufreq.h" 19 + #include "cpuidle.h" 19 20 #include "helpers/helpers.h" 20 - #include "helpers/sysfs.h" 21 21 22 22 #define NORM_FREQ_LEN 32 23 23 ··· 296 296 struct cpufreq_affected_cpus *cpus; 297 297 298 298 if (!bitmask_isbitset(cpus_chosen, cpu) || 299 - cpufreq_cpu_exists(cpu)) 299 + cpupower_is_cpu_online(cpu)) 300 300 continue; 301 301 302 302 cpus = cpufreq_get_related_cpus(cpu); ··· 316 316 cpu <= bitmask_last(cpus_chosen); cpu++) { 317 317 318 318 if (!bitmask_isbitset(cpus_chosen, cpu) || 319 - cpufreq_cpu_exists(cpu)) 319 + cpupower_is_cpu_online(cpu)) 320 320 continue; 321 321 322 - if (sysfs_is_cpu_online(cpu) != 1) 322 + if (cpupower_is_cpu_online(cpu) != 1) 323 323 continue; 324 324 325 325 printf(_("Setting cpu: %d\n"), cpu);
+17 -15
tools/power/cpupower/utils/cpuidle-info.c
··· 13 13 #include <string.h> 14 14 #include <getopt.h> 15 15 16 - #include "helpers/helpers.h" 16 + #include <cpuidle.h> 17 + 17 18 #include "helpers/sysfs.h" 19 + #include "helpers/helpers.h" 18 20 #include "helpers/bitmask.h" 19 21 20 22 #define LINE_LEN 10 ··· 26 24 unsigned int idlestates, idlestate; 27 25 char *tmp; 28 26 29 - idlestates = sysfs_get_idlestate_count(cpu); 27 + idlestates = cpuidle_state_count(cpu); 30 28 if (idlestates == 0) { 31 29 printf(_("CPU %u: No idle states\n"), cpu); 32 30 return; ··· 35 33 printf(_("Number of idle states: %d\n"), idlestates); 36 34 printf(_("Available idle states:")); 37 35 for (idlestate = 0; idlestate < idlestates; idlestate++) { 38 - tmp = sysfs_get_idlestate_name(cpu, idlestate); 36 + tmp = cpuidle_state_name(cpu, idlestate); 39 37 if (!tmp) 40 38 continue; 41 39 printf(" %s", tmp); ··· 47 45 return; 48 46 49 47 for (idlestate = 0; idlestate < idlestates; idlestate++) { 50 - int disabled = sysfs_is_idlestate_disabled(cpu, idlestate); 48 + int disabled = cpuidle_is_state_disabled(cpu, idlestate); 51 49 /* Disabled interface not supported on older kernels */ 52 50 if (disabled < 0) 53 51 disabled = 0; 54 - tmp = sysfs_get_idlestate_name(cpu, idlestate); 52 + tmp = cpuidle_state_name(cpu, idlestate); 55 53 if (!tmp) 56 54 continue; 57 55 printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : ""); 58 56 free(tmp); 59 57 60 - tmp = sysfs_get_idlestate_desc(cpu, idlestate); 58 + tmp = cpuidle_state_desc(cpu, idlestate); 61 59 if (!tmp) 62 60 continue; 63 61 printf(_("Flags/Description: %s\n"), tmp); 64 62 free(tmp); 65 63 66 64 printf(_("Latency: %lu\n"), 67 - sysfs_get_idlestate_latency(cpu, idlestate)); 65 + cpuidle_state_latency(cpu, idlestate)); 68 66 printf(_("Usage: %lu\n"), 69 - sysfs_get_idlestate_usage(cpu, idlestate)); 67 + cpuidle_state_usage(cpu, idlestate)); 70 68 printf(_("Duration: %llu\n"), 71 - sysfs_get_idlestate_time(cpu, idlestate)); 69 + cpuidle_state_time(cpu, idlestate)); 72 70 } 73 71 } 74 72 ··· 76 74 { 77 75 char *tmp; 78 76 79 - tmp = sysfs_get_cpuidle_driver(); 77 + tmp = cpuidle_get_driver(); 80 78 if (!tmp) { 81 79 printf(_("Could not determine cpuidle driver\n")); 82 80 return; ··· 85 83 printf(_("CPUidle driver: %s\n"), tmp); 86 84 free(tmp); 87 85 88 - tmp = sysfs_get_cpuidle_governor(); 86 + tmp = cpuidle_get_governor(); 89 87 if (!tmp) { 90 88 printf(_("Could not determine cpuidle governor\n")); 91 89 return; ··· 100 98 long max_allowed_cstate = 2000000000; 101 99 unsigned int cstate, cstates; 102 100 103 - cstates = sysfs_get_idlestate_count(cpu); 101 + cstates = cpuidle_state_count(cpu); 104 102 if (cstates == 0) { 105 103 printf(_("CPU %u: No C-states info\n"), cpu); 106 104 return; ··· 115 113 "type[C%d] "), cstate, cstate); 116 114 printf(_("promotion[--] demotion[--] ")); 117 115 printf(_("latency[%03lu] "), 118 - sysfs_get_idlestate_latency(cpu, cstate)); 116 + cpuidle_state_latency(cpu, cstate)); 119 117 printf(_("usage[%08lu] "), 120 - sysfs_get_idlestate_usage(cpu, cstate)); 118 + cpuidle_state_usage(cpu, cstate)); 121 119 printf(_("duration[%020Lu] \n"), 122 - sysfs_get_idlestate_time(cpu, cstate)); 120 + cpuidle_state_time(cpu, cstate)); 123 121 } 124 122 } 125 123
+13 -13
tools/power/cpupower/utils/cpuidle-set.c
··· 5 5 #include <limits.h> 6 6 #include <string.h> 7 7 #include <ctype.h> 8 - 9 8 #include <getopt.h> 10 9 11 - #include "cpufreq.h" 10 + #include <cpufreq.h> 11 + #include <cpuidle.h> 12 + 12 13 #include "helpers/helpers.h" 13 - #include "helpers/sysfs.h" 14 14 15 15 static struct option info_opts[] = { 16 16 {"disable", required_argument, NULL, 'd'}, ··· 104 104 if (!bitmask_isbitset(cpus_chosen, cpu)) 105 105 continue; 106 106 107 - if (sysfs_is_cpu_online(cpu) != 1) 107 + if (cpupower_is_cpu_online(cpu) != 1) 108 108 continue; 109 109 110 - idlestates = sysfs_get_idlestate_count(cpu); 110 + idlestates = cpuidle_state_count(cpu); 111 111 if (idlestates <= 0) 112 112 continue; 113 113 114 114 switch (param) { 115 115 case 'd': 116 - ret = sysfs_idlestate_disable(cpu, idlestate, 1); 116 + ret = cpuidle_state_disable(cpu, idlestate, 1); 117 117 if (ret == 0) 118 118 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); 119 119 else if (ret == -1) ··· 126 126 idlestate, cpu); 127 127 break; 128 128 case 'e': 129 - ret = sysfs_idlestate_disable(cpu, idlestate, 0); 129 + ret = cpuidle_state_disable(cpu, idlestate, 0); 130 130 if (ret == 0) 131 131 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); 132 132 else if (ret == -1) ··· 140 140 break; 141 141 case 'D': 142 142 for (idlestate = 0; idlestate < idlestates; idlestate++) { 143 - disabled = sysfs_is_idlestate_disabled 143 + disabled = cpuidle_is_state_disabled 144 144 (cpu, idlestate); 145 - state_latency = sysfs_get_idlestate_latency 145 + state_latency = cpuidle_state_latency 146 146 (cpu, idlestate); 147 147 if (disabled == 1) { 148 148 if (latency > state_latency){ 149 - ret = sysfs_idlestate_disable 149 + ret = cpuidle_state_disable 150 150 (cpu, idlestate, 0); 151 151 if (ret == 0) 152 152 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); ··· 154 154 continue; 155 155 } 156 156 if (latency <= state_latency){ 157 - ret = sysfs_idlestate_disable 157 + ret = cpuidle_state_disable 158 158 (cpu, idlestate, 1); 159 159 if (ret == 0) 160 160 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); ··· 163 163 break; 164 164 case 'E': 165 165 for (idlestate = 0; idlestate < idlestates; idlestate++) { 166 - disabled = sysfs_is_idlestate_disabled 166 + disabled = cpuidle_is_state_disabled 167 167 (cpu, idlestate); 168 168 if (disabled == 1) { 169 - ret = sysfs_idlestate_disable 169 + ret = cpuidle_state_disable 170 170 (cpu, idlestate, 0); 171 171 if (ret == 0) 172 172 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
+1 -25
tools/power/cpupower/utils/helpers/helpers.h
··· 14 14 #include <locale.h> 15 15 16 16 #include "helpers/bitmask.h" 17 + #include <cpupower.h> 17 18 18 19 /* Internationalization ****************************/ 19 20 #ifdef NLS ··· 92 91 extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info); 93 92 extern struct cpupower_cpu_info cpupower_cpu_info; 94 93 /* cpuid and cpuinfo helpers **************************/ 95 - 96 - struct cpuid_core_info { 97 - int pkg; 98 - int core; 99 - int cpu; 100 - 101 - /* flags */ 102 - unsigned int is_online:1; 103 - }; 104 - 105 - /* CPU topology/hierarchy parsing ******************/ 106 - struct cpupower_topology { 107 - /* Amount of CPU cores, packages and threads per core in the system */ 108 - unsigned int cores; 109 - unsigned int pkgs; 110 - unsigned int threads; /* per core */ 111 - 112 - /* Array gets mallocated with cores entries, holding per core info */ 113 - struct cpuid_core_info *core_info; 114 - }; 115 - 116 - extern int get_cpu_topology(struct cpupower_topology *cpu_top); 117 - extern void cpu_topology_release(struct cpupower_topology cpu_top); 118 - 119 - /* CPU topology/hierarchy parsing ******************/ 120 94 121 95 /* X86 ONLY ****************************************/ 122 96 #if defined(__i386__) || defined(__x86_64__)
+2 -105
tools/power/cpupower/utils/helpers/topology.c
··· 16 16 #include <errno.h> 17 17 #include <fcntl.h> 18 18 19 - #include <helpers/helpers.h> 20 - #include <helpers/sysfs.h> 19 + #include <cpuidle.h> 21 20 22 - /* returns -1 on failure, 0 on success */ 23 - static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result) 24 - { 25 - char linebuf[MAX_LINE_LEN]; 26 - char *endp; 27 - char path[SYSFS_PATH_MAX]; 21 + /* CPU topology/hierarchy parsing ******************/ 28 22 29 - snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", 30 - cpu, fname); 31 - if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) 32 - return -1; 33 - *result = strtol(linebuf, &endp, 0); 34 - if (endp == linebuf || errno == ERANGE) 35 - return -1; 36 - return 0; 37 - } 38 - 39 - static int __compare(const void *t1, const void *t2) 40 - { 41 - struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1; 42 - struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2; 43 - if (top1->pkg < top2->pkg) 44 - return -1; 45 - else if (top1->pkg > top2->pkg) 46 - return 1; 47 - else if (top1->core < top2->core) 48 - return -1; 49 - else if (top1->core > top2->core) 50 - return 1; 51 - else if (top1->cpu < top2->cpu) 52 - return -1; 53 - else if (top1->cpu > top2->cpu) 54 - return 1; 55 - else 56 - return 0; 57 - } 58 - 59 - /* 60 - * Returns amount of cpus, negative on error, cpu_top must be 61 - * passed to cpu_topology_release to free resources 62 - * 63 - * Array is sorted after ->pkg, ->core, then ->cpu 64 - */ 65 - int get_cpu_topology(struct cpupower_topology *cpu_top) 66 - { 67 - int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF); 68 - 69 - cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus); 70 - if (cpu_top->core_info == NULL) 71 - return -ENOMEM; 72 - cpu_top->pkgs = cpu_top->cores = 0; 73 - for (cpu = 0; cpu < cpus; cpu++) { 74 - cpu_top->core_info[cpu].cpu = cpu; 75 - cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu); 76 - if(sysfs_topology_read_file( 77 - cpu, 78 - "physical_package_id", 79 - &(cpu_top->core_info[cpu].pkg)) < 0) { 80 - cpu_top->core_info[cpu].pkg = -1; 81 - cpu_top->core_info[cpu].core = -1; 82 - continue; 83 - } 84 - if(sysfs_topology_read_file( 85 - cpu, 86 - "core_id", 87 - &(cpu_top->core_info[cpu].core)) < 0) { 88 - cpu_top->core_info[cpu].pkg = -1; 89 - cpu_top->core_info[cpu].core = -1; 90 - continue; 91 - } 92 - } 93 - 94 - qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), 95 - __compare); 96 - 97 - /* Count the number of distinct pkgs values. This works 98 - because the primary sort of the core_info struct was just 99 - done by pkg value. */ 100 - last_pkg = cpu_top->core_info[0].pkg; 101 - for(cpu = 1; cpu < cpus; cpu++) { 102 - if (cpu_top->core_info[cpu].pkg != last_pkg && 103 - cpu_top->core_info[cpu].pkg != -1) { 104 - 105 - last_pkg = cpu_top->core_info[cpu].pkg; 106 - cpu_top->pkgs++; 107 - } 108 - } 109 - if (!(cpu_top->core_info[0].pkg == -1)) 110 - cpu_top->pkgs++; 111 - 112 - /* Intel's cores count is not consecutively numbered, there may 113 - * be a core_id of 3, but none of 2. Assume there always is 0 114 - * Get amount of cores by counting duplicates in a package 115 - for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) { 116 - if (cpu_top->core_info[cpu].core == 0) 117 - cpu_top->cores++; 118 - */ 119 - return cpus; 120 - } 121 - 122 - void cpu_topology_release(struct cpupower_topology cpu_top) 123 - { 124 - free(cpu_top.core_info); 125 - }
+6 -6
tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c
··· 10 10 #include <stdint.h> 11 11 #include <string.h> 12 12 #include <limits.h> 13 + #include <cpuidle.h> 13 14 14 - #include "helpers/sysfs.h" 15 15 #include "helpers/helpers.h" 16 16 #include "idle_monitor/cpupower-monitor.h" 17 17 ··· 51 51 for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num; 52 52 state++) { 53 53 previous_count[cpu][state] = 54 - sysfs_get_idlestate_time(cpu, state); 54 + cpuidle_state_time(cpu, state); 55 55 dprint("CPU %d - State: %d - Val: %llu\n", 56 56 cpu, state, previous_count[cpu][state]); 57 57 } ··· 70 70 for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num; 71 71 state++) { 72 72 current_count[cpu][state] = 73 - sysfs_get_idlestate_time(cpu, state); 73 + cpuidle_state_time(cpu, state); 74 74 dprint("CPU %d - State: %d - Val: %llu\n", 75 75 cpu, state, previous_count[cpu][state]); 76 76 } ··· 132 132 char *tmp; 133 133 134 134 /* Assume idle state count is the same for all CPUs */ 135 - cpuidle_sysfs_monitor.hw_states_num = sysfs_get_idlestate_count(0); 135 + cpuidle_sysfs_monitor.hw_states_num = cpuidle_state_count(0); 136 136 137 137 if (cpuidle_sysfs_monitor.hw_states_num <= 0) 138 138 return NULL; 139 139 140 140 for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) { 141 - tmp = sysfs_get_idlestate_name(0, num); 141 + tmp = cpuidle_state_name(0, num); 142 142 if (tmp == NULL) 143 143 continue; 144 144 ··· 146 146 strncpy(cpuidle_cstates[num].name, tmp, CSTATE_NAME_LEN - 1); 147 147 free(tmp); 148 148 149 - tmp = sysfs_get_idlestate_desc(0, num); 149 + tmp = cpuidle_state_desc(0, num); 150 150 if (tmp == NULL) 151 151 continue; 152 152 strncpy(cpuidle_cstates[num].desc, tmp, CSTATE_DESC_LEN - 1);