aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorThomas Renninger <trenn@suse.de>2013-06-28 09:34:30 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-07-04 19:52:19 -0400
commit0924c369bc5492cf181a066fc2d459aa18ffa5ac (patch)
treeda95fc8a244654d0ea196e5e483704566f45ce3d /tools
parentf605181abd95a109031a23c67a824eb8e5dcfe67 (diff)
cpupower: Implement disabling of cstate interface
Latest kernel allows to disable C-states via: /sys/devices/system/cpu/cpuX/cpuidle/stateY/disable This patch provides lower level sysfs access functions to make use of this interface. A later patch will implement the higher level stuff. Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c116
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.h8
2 files changed, 123 insertions, 1 deletions
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
index 891f6710d026..5cdc600e8152 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.c
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -89,6 +89,33 @@ int sysfs_is_cpu_online(unsigned int cpu)
89 89
90/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ 90/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
91 91
92
93/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
94
95/*
96 * helper function to check whether a file under "../cpuX/cpuidle/stateX/" dir
97 * exists.
98 * For example the functionality to disable c-states was introduced in later
99 * kernel versions, this function can be used to explicitly check for this
100 * feature.
101 *
102 * returns 1 if the file exists, 0 otherwise.
103 */
104unsigned int sysfs_idlestate_file_exists(unsigned int cpu,
105 unsigned int idlestate,
106 const char *fname)
107{
108 char path[SYSFS_PATH_MAX];
109 struct stat statbuf;
110
111
112 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
113 cpu, idlestate, fname);
114 if (stat(path, &statbuf) != 0)
115 return 0;
116 return 1;
117}
118
92/* 119/*
93 * helper function to read file from /sys into given buffer 120 * helper function to read file from /sys into given buffer
94 * fname is a relative path under "cpuX/cpuidle/stateX/" dir 121 * fname is a relative path under "cpuX/cpuidle/stateX/" dir
@@ -121,6 +148,40 @@ unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate,
121 return (unsigned int) numread; 148 return (unsigned int) numread;
122} 149}
123 150
151/*
152 * helper function to write a new value to a /sys file
153 * fname is a relative path under "../cpuX/cpuidle/cstateY/" dir
154 *
155 * Returns the number of bytes written or 0 on error
156 */
157static
158unsigned int sysfs_idlestate_write_file(unsigned int cpu,
159 unsigned int idlestate,
160 const char *fname,
161 const char *value, size_t len)
162{
163 char path[SYSFS_PATH_MAX];
164 int fd;
165 ssize_t numwrite;
166
167 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
168 cpu, idlestate, fname);
169
170 fd = open(path, O_WRONLY);
171 if (fd == -1)
172 return 0;
173
174 numwrite = write(fd, value, len);
175 if (numwrite < 1) {
176 close(fd);
177 return 0;
178 }
179
180 close(fd);
181
182 return (unsigned int) numwrite;
183}
184
124/* read access to files which contain one numeric value */ 185/* read access to files which contain one numeric value */
125 186
126enum idlestate_value { 187enum idlestate_value {
@@ -128,6 +189,7 @@ enum idlestate_value {
128 IDLESTATE_POWER, 189 IDLESTATE_POWER,
129 IDLESTATE_LATENCY, 190 IDLESTATE_LATENCY,
130 IDLESTATE_TIME, 191 IDLESTATE_TIME,
192 IDLESTATE_DISABLE,
131 MAX_IDLESTATE_VALUE_FILES 193 MAX_IDLESTATE_VALUE_FILES
132}; 194};
133 195
@@ -136,6 +198,7 @@ static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = {
136 [IDLESTATE_POWER] = "power", 198 [IDLESTATE_POWER] = "power",
137 [IDLESTATE_LATENCY] = "latency", 199 [IDLESTATE_LATENCY] = "latency",
138 [IDLESTATE_TIME] = "time", 200 [IDLESTATE_TIME] = "time",
201 [IDLESTATE_DISABLE] = "disable",
139}; 202};
140 203
141static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu, 204static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu,
@@ -205,8 +268,59 @@ static char *sysfs_idlestate_get_one_string(unsigned int cpu,
205 return result; 268 return result;
206} 269}
207 270
271/*
272 * Returns:
273 * 1 if disabled
274 * 0 if enabled
275 * -1 if idlestate is not available
276 * -2 if disabling is not supported by the kernel
277 */
278int sysfs_is_idlestate_disabled(unsigned int cpu,
279 unsigned int idlestate)
280{
281 if (sysfs_get_idlestate_count(cpu) < idlestate)
282 return -1;
283
284 if (!sysfs_idlestate_file_exists(cpu, idlestate,
285 idlestate_value_files[IDLESTATE_DISABLE]))
286 return -2;
287 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_DISABLE);
288}
289
290/*
291 * Pass 1 as last argument to disable or 0 to enable the state
292 * Returns:
293 * 0 on success
294 * negative values on error, for example:
295 * -1 if idlestate is not available
296 * -2 if disabling is not supported by the kernel
297 * -3 No write access to disable/enable C-states
298 */
299int sysfs_idlestate_disable(unsigned int cpu,
300 unsigned int idlestate,
301 unsigned int disable)
302{
303 char value[SYSFS_PATH_MAX];
304 int bytes_written;
305
306 if (sysfs_get_idlestate_count(cpu) < idlestate)
307 return -1;
308
309 if (!sysfs_idlestate_file_exists(cpu, idlestate,
310 idlestate_value_files[IDLESTATE_DISABLE]))
311 return -2;
312
313 snprintf(value, SYSFS_PATH_MAX, "%u", disable);
314
315 bytes_written = sysfs_idlestate_write_file(cpu, idlestate, "disable",
316 value, sizeof(disable));
317 if (bytes_written)
318 return 0;
319 return -3;
320}
321
208unsigned long sysfs_get_idlestate_latency(unsigned int cpu, 322unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
209 unsigned int idlestate) 323 unsigned int idlestate)
210{ 324{
211 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); 325 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY);
212} 326}
diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h
index 0401a97a4cab..d28f11fedbda 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.h
+++ b/tools/power/cpupower/utils/helpers/sysfs.h
@@ -7,8 +7,16 @@
7 7
8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); 8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
9 9
10extern unsigned int sysfs_idlestate_file_exists(unsigned int cpu,
11 unsigned int idlestate,
12 const char *fname);
13
10extern int sysfs_is_cpu_online(unsigned int cpu); 14extern int sysfs_is_cpu_online(unsigned int cpu);
11 15
16extern int sysfs_is_idlestate_disabled(unsigned int cpu,
17 unsigned int idlestate);
18extern int sysfs_idlestate_disable(unsigned int cpu, unsigned int idlestate,
19 unsigned int disable);
12extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, 20extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
13 unsigned int idlestate); 21 unsigned int idlestate);
14extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, 22extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,