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 (at) 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 set_laptop_mode(void) 36 { 37 FILE *file; 38 file = fopen("/proc/sys/vm/laptop_mode", "w"); 39 if (!file) 40 return; 41 fprintf(file,"5\n"); 42 fclose(file); 43 } 44 45 void suggest_laptop_mode(void) 46 { 47 FILE *file; 48 int i; 49 char buffer[1024]; 50 /* 51 * Check to see if we are on AC - lots of distros have 52 * annoying scripts to turn laptop mode off when on AC, which 53 * results in annoying distracting return of set laptop mode 54 * hint. 55 */ 56 file = fopen("/proc/acpi/ac_adapter/AC/state", "r"); 57 if (!file) 58 return; 59 memset(buffer, 0, 1024); 60 if (!fgets(buffer, 1023, file)) { 61 fclose(file); 62 return; 63 } 64 fclose(file); 65 if (strstr(buffer, "on-line") != NULL) 66 return; 67 68 /* Now check for laptop mode */ 69 file = fopen("/proc/sys/vm/laptop_mode", "r"); 70 if (!file) 71 return; 72 memset(buffer, 0, 1024); 73 if (!fgets(buffer, 1023, file)) { 74 fclose(file); 75 return; 76 } 77 i = strtoul(buffer, NULL, 10); 78 if (i<1) { 79 add_suggestion( _("Suggestion: Enable laptop-mode by executing the following command:\n" 80 " echo 5 > /proc/sys/vm/laptop_mode \n"), 15, 'L', _(" L - enable Laptop mode "), set_laptop_mode); 81 } 82 fclose(file); 83 } 84 85 void nmi_watchdog_off(void) 86 { 87 FILE *file; 88 file = fopen("/proc/sys/kernel/nmi_watchdog", "w"); 89 if (!file) 90 return; 91 fprintf(file,"0\n"); 92 fclose(file); 93 } 94 void suggest_nmi_watchdog(void) 95 { 96 FILE *file; 97 int i; 98 char buffer[1024]; 99 file = fopen("/proc/sys/kernel/nmi_watchdog", "r"); 100 if (!file) 101 return; 102 memset(buffer, 0, 1024); 103 if (!fgets(buffer, 1023, file)) { 104 fclose(file); 105 return; 106 } 107 i = strtoul(buffer, NULL, 10); 108 if (i!=0) { 109 add_suggestion( _("Suggestion: disable the NMI watchdog by executing the following command:\n" 110 " echo 0 > /proc/sys/kernel/nmi_watchdog \n" 111 "The NMI watchdog is a kernel debug mechanism to detect deadlocks"), 25, 'N', _(" N - Turn NMI watchdog off "), nmi_watchdog_off); 112 } 113 fclose(file); 114 } 115 116 void suggest_hpet(void) 117 { 118 FILE *file; 119 char buffer[1024]; 120 file = fopen("/sys/devices/system/clocksource/clocksource0/available_clocksource", "r"); 121 if (!file) 122 return; 123 memset(buffer, 0, 1024); 124 125 if (!fgets(buffer, 1023, file)) { 126 fclose(file); 127 return; 128 } 129 130 if (strstr(buffer, "hpet")) { 131 fclose(file); 132 return; 133 } 134 135 fclose(file); 136 137 add_suggestion( _("Suggestion: enable the HPET (Multimedia Timer) in your BIOS or add \n" 138 "the kernel patch to force-enable HPET. HPET support allows Linux to \n" 139 "have much longer sleep intervals."), 7, 0, NULL, NULL); 140 } 141 142 void ac97_power_on(void) 143 { 144 FILE *file; 145 file = fopen("/sys/module/snd_ac97_codec/parameters/power_save", "w"); 146 if (!file) 147 return; 148 fprintf(file,"1"); 149 fclose(file); 150 if (access("/dev/dsp", F_OK)) 151 return; 152 file = fopen("/dev/dsp", "w"); 153 if (file) { 154 fprintf(file,"1"); 155 fclose(file); 156 } 157 } 158 159 void suggest_ac97_powersave(void) 160 { 161 FILE *file; 162 char buffer[1024]; 163 file = fopen("/sys/module/snd_ac97_codec/parameters/power_save", "r"); 164 if (!file) 165 return; 166 memset(buffer, 0, 1024); 167 if (!fgets(buffer, 1023, file)) { 168 fclose(file); 169 return; 170 } 171 if (buffer[0]=='N') { 172 add_suggestion( _("Suggestion: enable AC97 powersave mode by executing the following command:\n" 173 " echo 1 > /sys/module/snd_ac97_codec/parameters/power_save \n" 174 "or by passing power_save=1 as module parameter."), 25, 'A', _(" A - Turn AC97 powersave on "), ac97_power_on); 175 } 176 fclose(file); 177 } 178 179 void noatime_on(void) 180 { 181 system("/bin/mount -o remount,noatime,nodiratime /"); 182 } 183 184 void suggest_noatime(void) 185 { 186 FILE *file; 187 char buffer[1024]; 188 int suggest = 0; 189 file = fopen("/proc/mounts","r"); 190 if (!file) 191 return; 192 while (!feof(file)) { 193 memset(buffer, 0, 1024); 194 if (!fgets(buffer, 1023, file)) 195 break; 196 if (strstr(buffer, " / ext3") && !strstr(buffer, "noatime") && !strstr(buffer, "relatime")) 197 suggest = 1; 198 199 } 200 if (suggest) { 201 add_suggestion( _("Suggestion: enable the noatime filesystem option by executing the following command:\n" 202 " mount -o remount,noatime / or by pressing the T key \n" 203 "noatime disables persistent access time of file accesses, which causes lots of disk IO."), 5, 'T', _(" T - enable noatime "), noatime_on); 204 } 205 fclose(file); 206 } 207 208 void powersched_on(void) 209 { 210 FILE *file; 211 file = fopen("/sys/devices/system/cpu/sched_mc_power_savings", "w"); 212 if (!file) 213 return; 214 fprintf(file,"1"); 215 fclose(file); 216 } 217 218 void suggest_powersched(void) 219 { 220 FILE *file; 221 char buffer[1024]; 222 int suggest = 0; 223 int cpu; 224 225 file = fopen("/sys/devices/system/cpu/sched_mc_power_savings","r"); 226 if (!file) 227 return; 228 memset(buffer, 0, 1024); 229 if (!fgets(buffer, 1023, file)) { 230 fclose(file); 231 return; 232 } 233 fclose(file); 234 if (buffer[0]!='0') 235 return; 236 /* ok so power saving scheduler is off; now to see if we actually have a multi-package system */ 237 cpu = sysconf(_SC_NPROCESSORS_ONLN); 238 239 if (cpu<2) 240 return; /* UP system */ 241 242 file = fopen("/proc/cpuinfo", "r"); 243 suggest = 1; 244 if (!file) 245 return; 246 while (!feof(file)) { 247 memset(buffer, 0, 1024); 248 char *c; 249 if (!fgets(buffer, 1023, file)) 250 break; 251 if (strstr(buffer, "cpu cores")) { 252 c = strchr(buffer, ':'); 253 if (!c) 254 continue; 255 c++; 256 if (strtoll(c, NULL, 10) >= cpu) 257 suggest = 0; 258 } 259 } 260 fclose(file); 261 262 263 if (suggest) { 264 add_suggestion( _("Suggestion: enable the power aware CPU scheduler with the following command:\n" 265 " echo 1 > /sys/devices/system/cpu/sched_mc_power_savings\n" 266 "or by pressing the C key."), 5, 'C', _(" C - Power aware CPU scheduler "), powersched_on); 267 } 268 } 269 270 271 void writeback_long(void) 272 { 273 FILE *file; 274 file = fopen("/proc/sys/vm/dirty_writeback_centisecs", "w"); 275 if (!file) 276 return; 277 fprintf(file,"1500"); 278 fclose(file); 279 } 280 281 void suggest_writeback_time(void) 282 { 283 FILE *file; 284 char buffer[1024]; 285 int i; 286 file = fopen("/proc/sys/vm/dirty_writeback_centisecs", "r"); 287 if (!file) 288 return; 289 memset(buffer, 0, 1024); 290 if (!fgets(buffer, 1023, file)) { 291 fclose(file); 292 return; 293 } 294 i = strtoull(buffer, NULL, 10); 295 if (i<1400) { 296 char line[1024]; 297 sprintf(line,_("Suggestion: increase the VM dirty writeback time from %1.2f to 15 seconds with:\n" 298 " echo 1500 > /proc/sys/vm/dirty_writeback_centisecs \n" 299 "This wakes the disk up less frequently for background VM activity"), 300 i/100.0); 301 add_suggestion(line, 15, 'W', _(" W - Increase Writeback time "), writeback_long); 302 } 303 fclose(file); 304 } 305