Minor cleanups
[meego-developer-tools:powertop.git] / misctips.c
1 /*
2  * Copyright 2007, Intel Corporation
3  *
4  * This file is part of PowerTOP
5  *
6  * This program file is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program in a file named COPYING; if not, write to the
17  * Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301 USA
20  *
21  * Authors:
22  *      Arjan van de Ven <arjan@linux.intel.com>
23  */
24
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdint.h>
30 #include <sys/types.h>
31 #include <dirent.h>
32
33 #include "powertop.h"
34
35 void nmi_watchdog_off(void)
36 {
37         FILE *file;
38         file = fopen("/proc/sys/kernel/nmi_watchdog", "w");
39         if (!file)
40                 return;
41         fprintf(file,"0\n");
42         fclose(file);
43 }
44 void suggest_nmi_watchdog(void)
45 {
46         FILE *file;
47         int i;
48         char buffer[1024];
49         file = fopen("/proc/sys/kernel/nmi_watchdog", "r");
50         if (!file)
51                 return;
52         memset(buffer, 0, 1024);
53         if (!fgets(buffer, 1023, file)) {
54                 fclose(file);
55                 return;
56         }
57         i = strtoul(buffer, NULL, 10);
58         if (i!=0) {
59                 add_suggestion( _("Suggestion: disable the NMI watchdog by executing the following command:\n"
60                         "   echo 0 > /proc/sys/kernel/nmi_watchdog \n"
61                         "The NMI watchdog is a kernel debug mechanism to detect deadlocks"), 25, 'N', _(" N - Turn NMI watchdog off "), nmi_watchdog_off);
62         }
63         fclose(file);
64 }
65
66 void suggest_hpet(void)
67 {
68         FILE *file;
69         char buffer[1024];
70         file = fopen("/sys/devices/system/clocksource/clocksource0/available_clocksource", "r");
71         if (!file)
72                 return;
73         memset(buffer, 0, 1024);
74
75         if (!fgets(buffer, 1023, file)) {
76                 fclose(file);
77                 return;
78         }
79
80         if (strstr(buffer, "hpet")) {
81                 fclose(file);
82                 return;
83         }
84
85         fclose(file);
86
87         add_suggestion( _("Suggestion: enable the HPET (Multimedia Timer) in your BIOS or add \n"
88                           "the kernel patch to force-enable HPET. HPET support allows Linux to \n"
89                           "have much longer sleep intervals."), 7, 0, NULL, NULL);
90 }
91
92 void ac97_power_on(void)
93 {
94         FILE *file;
95         file = fopen("/sys/module/snd_ac97_codec/parameters/power_save", "w");
96         if (!file)
97                 return;
98         fprintf(file,"1");
99         fclose(file);
100         if (access("/dev/dsp", F_OK))
101                 return;
102         /* kick power mgmt update to the driver */
103         file = fopen("/dev/dsp", "w");
104         if (file) {
105                 fprintf(file,"1");
106                 fclose(file);
107         }
108 }
109
110 void suggest_ac97_powersave(void)
111 {
112         FILE *file;
113         char buffer[1024];
114         file = fopen("/sys/module/snd_ac97_codec/parameters/power_save", "r");
115         if (!file)
116                 return;
117         memset(buffer, 0, 1024);
118         if (!fgets(buffer, 1023, file)) {
119                 fclose(file);
120                 return;
121         }
122         if (buffer[0]=='N') {
123                 add_suggestion( _("Suggestion: enable AC97 powersave mode by executing the following command:\n"
124                         "   echo 1 > /sys/module/snd_ac97_codec/parameters/power_save \n"
125                         "or by passing power_save=1 as module parameter."), 25, 'A', _(" A - Turn AC97 powersave on "), ac97_power_on);
126         }
127         fclose(file);
128 }
129
130 void hda_power_on(void)
131 {
132         FILE *file;
133
134         file = fopen("/sys/module/snd_hda_intel/parameters/power_save", "w");
135         if (!file)
136                 return;
137         fprintf(file,"1");
138         fclose(file);
139         if (access("/dev/dsp", F_OK))
140                 return;
141         /* kick power mgmt update to the driver */
142         file = fopen("/dev/dsp", "w");
143         if (file) {
144                 fprintf(file,"1");
145                 fclose(file);
146         }
147 }
148
149 void suggest_hda_powersave(void)
150 {
151         FILE *file;
152         char buffer[1024];
153
154         file = fopen("/sys/module/snd_hda_intel/parameters/power_save", "r");
155         if (!file)
156                 return;
157         memset(buffer, 0, 1024);
158         if (!fgets(buffer, 1023, file)) {
159                 fclose(file);
160                 return;
161         }
162         if (buffer[0]=='0') {
163                 add_suggestion( _("Suggestion: enable HD audio powersave mode by executing the following command:\n"
164                         "   echo 1 > /sys/module/snd_hda_intel/parameters/power_save \n"
165                         "or by passing power_save=1 as module parameter."), 25, 'A', _(" A - Turn HD audio powersave on "), hda_power_on);
166         }
167         fclose(file);
168 }
169
170 void noatime_on(void)
171 {
172         system("/bin/mount -o remount,noatime,nodiratime /");
173 }
174
175 void suggest_noatime(void)
176 {
177         FILE *file;
178         char buffer[1024];
179         int suggest = 0;
180         file = fopen("/proc/mounts","r");
181         if (!file)
182                 return;
183         while (!feof(file)) {
184                 memset(buffer, 0, 1024);
185                 if (!fgets(buffer, 1023, file))
186                         break;
187                 if (strstr(buffer, " / ext3") && !strstr(buffer, "noatime") && !strstr(buffer, "relatime"))
188                         suggest = 1;
189
190         }
191         if (suggest) {
192                 add_suggestion( _("Suggestion: enable the noatime filesystem option by executing the following command:\n"
193                         "   mount -o remount,noatime /          or by pressing the T key \n"
194                         "noatime disables persistent access time of file accesses, which causes lots of disk IO."), 5, 'T', _(" T - enable noatime "), noatime_on);
195         }
196         fclose(file);
197 }
198
199 void powersched_on(void)
200 {
201         FILE *file;
202         file = fopen("/sys/devices/system/cpu/sched_mc_power_savings", "w");
203         if (!file)
204                 return;
205         fprintf(file,"1");
206         fclose(file);
207 }
208
209 void suggest_powersched(void)
210 {
211         FILE *file;
212         char buffer[1024];
213         int suggest = 0;
214         int cpu;
215
216         file = fopen("/sys/devices/system/cpu/sched_mc_power_savings","r");
217         if (!file)
218                 return;
219         memset(buffer, 0, 1024);
220         if (!fgets(buffer, 1023, file)) {
221                 fclose(file);
222                 return;
223         }
224         fclose(file);
225         if (buffer[0]!='0')
226                 return;
227         /* ok so power saving scheduler is off; now to see if we actually have a multi-package system */
228         cpu =  sysconf(_SC_NPROCESSORS_ONLN);
229
230         if (cpu<2)
231                 return; /* UP system */
232
233         file = fopen("/proc/cpuinfo", "r");
234         suggest = 1;
235         if (!file)
236                 return;
237         while (!feof(file)) {
238                 memset(buffer, 0, 1024);
239                 if (!fgets(buffer, 1023, file))
240                         break;
241                 if (strstr(buffer, "cpu cores")) {
242                         char *c = strchr(buffer, ':');
243                         if (!c)
244                                 continue;
245                         c++;
246                         if (strtoll(c, NULL, 10) >= cpu)
247                                 suggest = 0;
248                 }
249         }
250         fclose(file);
251
252
253         if (suggest) {
254                 add_suggestion( _("Suggestion: enable the power aware CPU scheduler with the following command:\n"
255                         "  echo 1 > /sys/devices/system/cpu/sched_mc_power_savings\n"
256                         "or by pressing the C key."), 5, 'C', _(" C - Power aware CPU scheduler "), powersched_on);
257         }
258 }
259
260
261 void writeback_long(void)
262 {
263         FILE *file;
264         file = fopen("/proc/sys/vm/dirty_writeback_centisecs", "w");
265         if (!file)
266                 return;
267         fprintf(file,"1500");
268         fclose(file);
269 }
270
271 void suggest_writeback_time(void)
272 {
273         FILE *file;
274         char buffer[1024];
275         int i;
276         file = fopen("/proc/sys/vm/dirty_writeback_centisecs", "r");
277         if (!file)
278                 return;
279         memset(buffer, 0, 1024);
280         if (!fgets(buffer, 1023, file)) {
281                 fclose(file);
282                 return;
283         }
284         i = strtoull(buffer, NULL, 10);
285         if (i<1400) {
286                 char line[1024];
287                 sprintf(line,_("Suggestion: increase the VM dirty writeback time from %1.2f to 15 seconds with:\n"
288                                 "  echo 1500 > /proc/sys/vm/dirty_writeback_centisecs \n"
289                                 "This wakes the disk up less frequently for background VM activity"),
290                         i/100.0);
291                 add_suggestion(line, 15, 'W', _(" W - Increase Writeback time "), writeback_long);
292         }
293         fclose(file);
294 }