Commit | Line | Data |
---|---|---|
bfbf6e1e MO |
1 | ;;; GNU Guix --- Functional package management for GNU |
2 | ;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com> | |
3 | ;;; | |
4 | ;;; This file is part of GNU Guix. | |
5 | ;;; | |
6a18183f | 6 | ;;; GNU Guix is free software; you can redistribute it and/or modify |
bfbf6e1e MO |
7 | ;;; it under the terms of the GNU General Public License as published by |
8 | ;;; the Free Software Foundation, either version 3 of the License, or | |
9 | ;;; (at your option) any later version. | |
10 | ;;; | |
11 | ;;; GNU Guix is distributed in the hope that it will be useful, | |
12 | ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | ;;; GNU General Public License for more details. | |
15 | ;;; | |
16 | ;;; You should have received a copy of the GNU General Public License | |
17 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | |
18 | ||
19 | (define-module (gnu services pm) | |
20 | #:use-module (guix gexp) | |
21 | #:use-module (guix packages) | |
22 | #:use-module (guix records) | |
d7fa39cc | 23 | #:use-module (gnu packages admin) |
bfbf6e1e MO |
24 | #:use-module (gnu packages linux) |
25 | #:use-module (gnu services) | |
26 | #:use-module (gnu services base) | |
27 | #:use-module (gnu services configuration) | |
28 | #:use-module (gnu services shepherd) | |
29 | #:use-module (gnu system shadow) | |
30 | #:export (tlp-service-type | |
d7fa39cc CAW |
31 | tlp-configuration |
32 | ||
33 | thermald-configuration | |
34 | thermald-service-type)) | |
bfbf6e1e MO |
35 | |
36 | (define (uglify-field-name field-name) | |
37 | (let ((str (symbol->string field-name))) | |
38 | (string-join (string-split | |
39 | (string-upcase | |
40 | (if (string-suffix? "?" str) | |
41 | (substring str 0 (1- (string-length str))) | |
42 | str)) | |
43 | #\-) | |
44 | "_"))) | |
45 | ||
46 | (define (serialize-field field-name val) | |
47 | (format #t "~a=~a\n" (uglify-field-name field-name) val)) | |
48 | ||
49 | (define (serialize-boolean field-name val) | |
50 | (serialize-field field-name (if val "1" "0"))) | |
51 | (define-maybe boolean) | |
52 | ||
53 | (define (serialize-string field-name val) | |
54 | (serialize-field field-name val)) | |
55 | (define-maybe string) | |
56 | ||
57 | (define (space-separated-string-list? val) | |
58 | (and (list? val) | |
59 | (and-map (lambda (x) | |
60 | (and (string? x) (not (string-index x #\space)))) | |
61 | val))) | |
62 | (define (serialize-space-separated-string-list field-name val) | |
63 | (serialize-field field-name | |
64 | (format #f "~s" | |
65 | (string-join val " ")))) | |
66 | (define-maybe space-separated-string-list) | |
67 | ||
68 | (define (non-negative-integer? val) | |
69 | (and (exact-integer? val) (not (negative? val)))) | |
70 | (define (serialize-non-negative-integer field-name val) | |
71 | (serialize-field field-name val)) | |
72 | (define-maybe non-negative-integer) | |
73 | ||
74 | (define (on-off-boolean? val) | |
75 | (boolean? val)) | |
76 | (define (serialize-on-off-boolean field-name val) | |
77 | (serialize-field field-name (if val "on" "off"))) | |
78 | (define-maybe on-off-boolean) | |
79 | ||
80 | (define (y-n-boolean? val) | |
81 | (boolean? val)) | |
82 | (define (serialize-y-n-boolean field-name val) | |
83 | (serialize-field field-name (if val "Y" "N"))) | |
84 | ||
85 | (define-configuration tlp-configuration | |
86 | (tlp | |
892f1b72 | 87 | (file-like tlp) |
bfbf6e1e MO |
88 | "The TLP package.") |
89 | ||
90 | (tlp-enable? | |
91 | (boolean #t) | |
92 | "Set to true if you wish to enable TLP.") | |
93 | ||
94 | (tlp-default-mode | |
95 | (string "AC") | |
96 | "Default mode when no power supply can be detected. Alternatives are | |
97 | AC and BAT.") | |
98 | ||
99 | (disk-idle-secs-on-ac | |
100 | (non-negative-integer 0) | |
101 | "Number of seconds Linux kernel has to wait after the disk goes idle, | |
102 | before syncing on AC.") | |
103 | ||
104 | (disk-idle-secs-on-bat | |
105 | (non-negative-integer 2) | |
106 | "Same as @code{disk-idle-ac} but on BAT mode.") | |
107 | ||
108 | (max-lost-work-secs-on-ac | |
109 | (non-negative-integer 15) | |
110 | "Dirty pages flushing periodicity, expressed in seconds.") | |
111 | ||
112 | (max-lost-work-secs-on-bat | |
113 | (non-negative-integer 60) | |
114 | "Same as @code{max-lost-work-secs-on-ac} but on BAT mode.") | |
115 | ||
116 | (cpu-scaling-governor-on-ac | |
8cb1a49a | 117 | maybe-space-separated-string-list |
bfbf6e1e MO |
118 | "CPU frequency scaling governor on AC mode. With intel_pstate |
119 | driver, alternatives are powersave and performance. With acpi-cpufreq driver, | |
120 | alternatives are ondemand, powersave, performance and conservative.") | |
121 | ||
122 | (cpu-scaling-governor-on-bat | |
8cb1a49a | 123 | maybe-space-separated-string-list |
bfbf6e1e MO |
124 | "Same as @code{cpu-scaling-governor-on-ac} but on BAT mode.") |
125 | ||
126 | (cpu-scaling-min-freq-on-ac | |
8cb1a49a | 127 | maybe-non-negative-integer |
bfbf6e1e MO |
128 | "Set the min available frequency for the scaling governor on AC.") |
129 | ||
130 | (cpu-scaling-max-freq-on-ac | |
8cb1a49a | 131 | maybe-non-negative-integer |
bfbf6e1e MO |
132 | "Set the max available frequency for the scaling governor on AC.") |
133 | ||
134 | (cpu-scaling-min-freq-on-bat | |
8cb1a49a | 135 | maybe-non-negative-integer |
bfbf6e1e MO |
136 | "Set the min available frequency for the scaling governor on BAT.") |
137 | ||
138 | (cpu-scaling-max-freq-on-bat | |
8cb1a49a | 139 | maybe-non-negative-integer |
bfbf6e1e MO |
140 | "Set the max available frequency for the scaling governor on BAT.") |
141 | ||
142 | (cpu-min-perf-on-ac | |
8cb1a49a | 143 | maybe-non-negative-integer |
bfbf6e1e MO |
144 | "Limit the min P-state to control the power dissipation of the CPU, |
145 | in AC mode. Values are stated as a percentage of the available performance.") | |
146 | ||
147 | (cpu-max-perf-on-ac | |
8cb1a49a | 148 | maybe-non-negative-integer |
bfbf6e1e MO |
149 | "Limit the max P-state to control the power dissipation of the CPU, |
150 | in AC mode. Values are stated as a percentage of the available performance.") | |
151 | ||
152 | (cpu-min-perf-on-bat | |
8cb1a49a | 153 | maybe-non-negative-integer |
bfbf6e1e MO |
154 | "Same as @code{cpu-min-perf-on-ac} on BAT mode.") |
155 | ||
156 | (cpu-max-perf-on-bat | |
8cb1a49a | 157 | maybe-non-negative-integer |
bfbf6e1e MO |
158 | "Same as @code{cpu-max-perf-on-ac} on BAT mode.") |
159 | ||
160 | (cpu-boost-on-ac? | |
8cb1a49a | 161 | maybe-boolean |
bfbf6e1e MO |
162 | "Enable CPU turbo boost feature on AC mode.") |
163 | ||
164 | (cpu-boost-on-bat? | |
8cb1a49a | 165 | maybe-boolean |
bfbf6e1e MO |
166 | "Same as @code{cpu-boost-on-ac?} on BAT mode.") |
167 | ||
168 | (sched-powersave-on-ac? | |
169 | (boolean #f) | |
170 | "Allow Linux kernel to minimize the number of CPU cores/hyper-threads | |
171 | used under light load conditions.") | |
172 | ||
173 | (sched-powersave-on-bat? | |
174 | (boolean #t) | |
175 | "Same as @code{sched-powersave-on-ac?} but on BAT mode.") | |
176 | ||
177 | (nmi-watchdog? | |
178 | (boolean #f) | |
179 | "Enable Linux kernel NMI watchdog.") | |
180 | ||
181 | (phc-controls | |
8cb1a49a | 182 | maybe-string |
bfbf6e1e MO |
183 | "For Linux kernels with PHC patch applied, change CPU voltages. |
184 | An example value would be @samp{\"F:V F:V F:V F:V\"}.") | |
185 | ||
186 | (energy-perf-policy-on-ac | |
187 | (string "performance") | |
188 | "Set CPU performance versus energy saving policy on AC. Alternatives are | |
189 | performance, normal, powersave.") | |
190 | ||
191 | (energy-perf-policy-on-bat | |
192 | (string "powersave") | |
193 | "Same as @code{energy-perf-policy-ac} but on BAT mode.") | |
194 | ||
195 | (disks-devices | |
196 | (space-separated-string-list '("sda")) | |
197 | "Hard disk devices.") | |
198 | ||
199 | (disk-apm-level-on-ac | |
200 | (space-separated-string-list '("254" "254")) | |
201 | "Hard disk advanced power management level.") | |
202 | ||
203 | (disk-apm-level-on-bat | |
204 | (space-separated-string-list '("128" "128")) | |
205 | "Same as @code{disk-apm-bat} but on BAT mode.") | |
206 | ||
207 | (disk-spindown-timeout-on-ac | |
8cb1a49a | 208 | maybe-space-separated-string-list |
bfbf6e1e MO |
209 | "Hard disk spin down timeout. One value has to be specified for |
210 | each declared hard disk.") | |
211 | ||
212 | (disk-spindown-timeout-on-bat | |
8cb1a49a | 213 | maybe-space-separated-string-list |
bfbf6e1e MO |
214 | "Same as @code{disk-spindown-timeout-on-ac} but on BAT mode.") |
215 | ||
216 | (disk-iosched | |
8cb1a49a | 217 | maybe-space-separated-string-list |
bfbf6e1e MO |
218 | "Select IO scheduler for disk devices. One value has to be specified |
219 | for each declared hard disk. Example alternatives are cfq, deadline and noop.") | |
220 | ||
221 | (sata-linkpwr-on-ac | |
222 | (string "max_performance") | |
223 | "SATA aggressive link power management (ALPM) level. Alternatives are | |
224 | min_power, medium_power, max_performance.") | |
225 | ||
226 | (sata-linkpwr-on-bat | |
227 | (string "min_power") | |
228 | "Same as @code{sata-linkpwr-ac} but on BAT mode.") | |
229 | ||
230 | (sata-linkpwr-blacklist | |
8cb1a49a | 231 | maybe-string |
bfbf6e1e MO |
232 | "Exclude specified SATA host devices for link power management.") |
233 | ||
234 | (ahci-runtime-pm-on-ac? | |
8cb1a49a | 235 | maybe-on-off-boolean |
bfbf6e1e MO |
236 | "Enable Runtime Power Management for AHCI controller and disks |
237 | on AC mode.") | |
238 | ||
239 | (ahci-runtime-pm-on-bat? | |
8cb1a49a | 240 | maybe-on-off-boolean |
bfbf6e1e MO |
241 | "Same as @code{ahci-runtime-pm-on-ac} on BAT mode.") |
242 | ||
243 | (ahci-runtime-pm-timeout | |
244 | (non-negative-integer 15) | |
245 | "Seconds of inactivity before disk is suspended.") | |
246 | ||
247 | (pcie-aspm-on-ac | |
248 | (string "performance") | |
249 | "PCI Express Active State Power Management level. Alternatives are | |
250 | default, performance, powersave.") | |
251 | ||
252 | (pcie-aspm-on-bat | |
253 | (string "powersave") | |
254 | "Same as @code{pcie-aspm-ac} but on BAT mode.") | |
255 | ||
67f28faf | 256 | (start-charge-thresh-bat0 |
8cb1a49a | 257 | maybe-non-negative-integer |
67f28faf AL |
258 | "Percentage when battery 0 should begin charging.") |
259 | ||
260 | (stop-charge-thresh-bat0 | |
8cb1a49a | 261 | maybe-non-negative-integer |
67f28faf AL |
262 | "Percentage when battery 0 should stop charging.") |
263 | ||
264 | (start-charge-thresh-bat1 | |
8cb1a49a | 265 | maybe-non-negative-integer |
67f28faf AL |
266 | "Percentage when battery 1 should begin charging.") |
267 | ||
268 | (stop-charge-thresh-bat1 | |
8cb1a49a | 269 | maybe-non-negative-integer |
67f28faf AL |
270 | "Percentage when battery 1 should stop charging.") |
271 | ||
bfbf6e1e MO |
272 | (radeon-power-profile-on-ac |
273 | (string "high") | |
274 | "Radeon graphics clock speed level. Alternatives are | |
275 | low, mid, high, auto, default.") | |
276 | ||
277 | (radeon-power-profile-on-bat | |
278 | (string "low") | |
279 | "Same as @code{radeon-power-ac} but on BAT mode.") | |
280 | ||
281 | (radeon-dpm-state-on-ac | |
282 | (string "performance") | |
283 | "Radeon dynamic power management method (DPM). Alternatives are | |
284 | battery, performance.") | |
285 | ||
286 | (radeon-dpm-state-on-bat | |
287 | (string "battery") | |
288 | "Same as @code{radeon-dpm-state-ac} but on BAT mode.") | |
289 | ||
290 | (radeon-dpm-perf-level-on-ac | |
291 | (string "auto") | |
292 | "Radeon DPM performance level. Alternatives are | |
293 | auto, low, high.") | |
294 | ||
295 | (radeon-dpm-perf-level-on-bat | |
296 | (string "auto") | |
297 | "Same as @code{radeon-dpm-perf-ac} but on BAT mode.") | |
298 | ||
299 | (wifi-pwr-on-ac? | |
300 | (on-off-boolean #f) | |
301 | "Wifi power saving mode.") | |
302 | ||
303 | (wifi-pwr-on-bat? | |
304 | (on-off-boolean #t) | |
305 | "Same as @code{wifi-power-ac?} but on BAT mode.") | |
306 | ||
307 | (wol-disable? | |
308 | (y-n-boolean #t) | |
309 | "Disable wake on LAN.") | |
310 | ||
311 | (sound-power-save-on-ac | |
312 | (non-negative-integer 0) | |
313 | "Timeout duration in seconds before activating audio power saving | |
314 | on Intel HDA and AC97 devices. A value of 0 disables power saving.") | |
315 | ||
316 | (sound-power-save-on-bat | |
317 | (non-negative-integer 1) | |
318 | "Same as @code{sound-powersave-ac} but on BAT mode.") | |
319 | ||
320 | (sound-power-save-controller? | |
321 | (y-n-boolean #t) | |
322 | "Disable controller in powersaving mode on Intel HDA devices.") | |
323 | ||
324 | (bay-poweroff-on-bat? | |
325 | (boolean #f) | |
326 | "Enable optical drive in UltraBay/MediaBay on BAT mode. | |
327 | Drive can be powered on again by releasing (and reinserting) the eject lever | |
328 | or by pressing the disc eject button on newer models.") | |
329 | ||
330 | (bay-device | |
331 | (string "sr0") | |
332 | "Name of the optical drive device to power off.") | |
333 | ||
334 | (runtime-pm-on-ac | |
335 | (string "on") | |
336 | "Runtime Power Management for PCI(e) bus devices. Alternatives are | |
337 | on and auto.") | |
338 | ||
339 | (runtime-pm-on-bat | |
340 | (string "auto") | |
341 | "Same as @code{runtime-pm-ac} but on BAT mode.") | |
342 | ||
343 | (runtime-pm-all? | |
344 | (boolean #t) | |
345 | "Runtime Power Management for all PCI(e) bus devices, except | |
346 | blacklisted ones.") | |
347 | ||
348 | (runtime-pm-blacklist | |
8cb1a49a | 349 | maybe-space-separated-string-list |
9fc221b5 | 350 | "Exclude specified PCI(e) device addresses from Runtime Power Management.") |
bfbf6e1e MO |
351 | |
352 | (runtime-pm-driver-blacklist | |
353 | (space-separated-string-list '("radeon" "nouveau")) | |
354 | "Exclude PCI(e) devices assigned to the specified drivers from | |
355 | Runtime Power Management.") | |
356 | ||
357 | (usb-autosuspend? | |
358 | (boolean #t) | |
359 | "Enable USB autosuspend feature.") | |
360 | ||
361 | (usb-blacklist | |
8cb1a49a | 362 | maybe-string |
bfbf6e1e MO |
363 | "Exclude specified devices from USB autosuspend.") |
364 | ||
365 | (usb-blacklist-wwan? | |
366 | (boolean #t) | |
367 | "Exclude WWAN devices from USB autosuspend.") | |
368 | ||
369 | (usb-whitelist | |
8cb1a49a | 370 | maybe-string |
bfbf6e1e MO |
371 | "Include specified devices into USB autosuspend, even if they are |
372 | already excluded by the driver or via @code{usb-blacklist-wwan?}.") | |
373 | ||
374 | (usb-autosuspend-disable-on-shutdown? | |
8cb1a49a | 375 | maybe-boolean |
bfbf6e1e MO |
376 | "Enable USB autosuspend before shutdown.") |
377 | ||
378 | (restore-device-state-on-startup? | |
379 | (boolean #f) | |
380 | "Restore radio device state (bluetooth, wifi, wwan) from previous | |
381 | shutdown on system startup.")) | |
382 | ||
383 | ||
384 | (define (tlp-shepherd-service config) | |
385 | (let* ((tlp-bin (file-append | |
386 | (tlp-configuration-tlp config) "/bin/tlp")) | |
387 | (tlp-action (lambda args | |
388 | #~(lambda _ | |
389 | (zero? (system* #$tlp-bin #$@args)))))) | |
390 | (list (shepherd-service | |
391 | (documentation "Run TLP script.") | |
392 | (provision '(tlp)) | |
393 | (requirement '(user-processes)) | |
394 | (start (tlp-action "init" "start")) | |
395 | (stop (tlp-action "init" "stop")))))) | |
396 | ||
397 | (define (tlp-activation config) | |
398 | (let* ((config-str (with-output-to-string | |
399 | (lambda () | |
400 | (serialize-configuration | |
401 | config | |
402 | tlp-configuration-fields)))) | |
403 | (config-file (plain-file "tlp" config-str))) | |
404 | (with-imported-modules '((guix build utils)) | |
405 | #~(begin | |
406 | (use-modules (guix build utils)) | |
8a890f3c | 407 | (copy-file #$config-file "/etc/tlp.conf"))))) |
bfbf6e1e MO |
408 | |
409 | (define tlp-service-type | |
410 | (service-type | |
411 | (name 'tlp) | |
412 | (extensions | |
413 | (list | |
414 | (service-extension shepherd-root-service-type | |
415 | tlp-shepherd-service) | |
416 | (service-extension udev-service-type | |
417 | (compose list tlp-configuration-tlp)) | |
418 | (service-extension activation-service-type | |
3d3c5650 | 419 | tlp-activation))) |
94b98ef7 LC |
420 | (default-value (tlp-configuration)) |
421 | (description "Run TLP, a power management tool."))) | |
bfbf6e1e MO |
422 | |
423 | (define (generate-tlp-documentation) | |
424 | (generate-documentation | |
425 | `((tlp-configuration ,tlp-configuration-fields)) | |
426 | 'tlp-configuration)) | |
d7fa39cc CAW |
427 | |
428 | \f | |
429 | ||
430 | ;;; | |
431 | ;;; thermald | |
432 | ;;; | |
433 | ;;; This service implements cpu scaling. Helps prevent overheating! | |
434 | ||
435 | (define-record-type* <thermald-configuration> | |
436 | thermald-configuration make-thermald-configuration | |
437 | thermald-configuration? | |
10d865aa JL |
438 | (adaptive? thermald-adaptive? ;boolean |
439 | (default #f)) | |
d7fa39cc CAW |
440 | (ignore-cpuid-check? thermald-ignore-cpuid-check? ;boolean |
441 | (default #f)) | |
892f1b72 | 442 | (thermald thermald-thermald ;file-like |
d7fa39cc CAW |
443 | (default thermald))) |
444 | ||
445 | (define (thermald-shepherd-service config) | |
446 | (list | |
447 | (shepherd-service | |
448 | (provision '(thermald)) | |
449 | (documentation "Run thermald cpu frequency scaling.") | |
450 | (start #~(make-forkexec-constructor | |
451 | '(#$(file-append (thermald-thermald config) "/sbin/thermald") | |
452 | "--no-daemon" | |
10d865aa JL |
453 | #$@(if (thermald-adaptive? config) |
454 | '("--adaptive") | |
455 | '()) | |
d7fa39cc CAW |
456 | #$@(if (thermald-ignore-cpuid-check? config) |
457 | '("--ignore-cpuid-check") | |
458 | '())))) | |
459 | (stop #~(make-kill-destructor))))) | |
460 | ||
461 | (define thermald-service-type | |
462 | (service-type | |
463 | (name 'thermald) | |
464 | (extensions (list (service-extension shepherd-root-service-type | |
465 | thermald-shepherd-service))) | |
94b98ef7 LC |
466 | (default-value (thermald-configuration)) |
467 | (description "Run thermald, a CPU frequency scaling service that helps | |
468 | prevent overheating."))) |