Power management (Русский)

From ArchWiki
Состояние перевода: На этой странице представлен перевод статьи Power management. Дата последней синхронизации: 3 июня 2023. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Управление питанием — это функция, которая отключает питание или переводит компоненты системы в состояние низкого энергопотребления, когда они неактивны.

В Arch Linux управление питанием состоит из двух основных частей:

  1. Конфигурация ядра Linux, которое взаимодействует с аппаратным обеспечением.
  2. Конфигурация пользовательских инструментов, которые взаимодействуют с ядром и реагируют на его события. Многие инструменты также предоставляют удобные способы изменения конфигурация ядра. Смотрите раздел #Пользовательские инструменты.

Пользовательские инструменты

Эти инструменты являются удобной альтернативой ручной установке многих параметров. Запускайте только один из этих инструментов, чтобы избежать возможных конфликтов, так как все они работают примерно одинаково. Просмотрите Category:Power management (Русский), чтобы получить представление о том, какие возможности управления питанием существуют в Arch Linux.

Популярные скрипты и инструменты, управляющие энергосбережением:

Консольные

  • acpid — Демон для доставки событий управления питанием ACPI с поддержкой netlink.
https://sourceforge.net/projects/acpid2/ || acpid
  • Laptop Mode Tools — Инструмент для настройки параметров энергосбережения ноутбука, которую многие считают де-факто утилитой для энергосбережения, хотя она может потребовать некоторой настройки.
https://github.com/rickysarraf/laptop-mode-tools || laptop-mode-toolsAUR
  • libsmbios — Библиотека и инструменты для взаимодействия с таблицами Dell SMBIOS.
https://github.com/dell/libsmbios || libsmbios
  • powertop — Инструмент для диагностики проблем с энергопотреблением и управлением питанием, помогающий установить параметры энергосбережения.
https://01.org/powertop/[устаревшая ссылка 2023-09-16 ⓘ] || powertop
  • systemd — Менеджер системы и служб.
https://systemd.io/ || systemd
  • TLP — Расширенное управление питанием для Linux.
https://linrunner.de/tlp || tlp

Графические

  • batsignal — Лёгкий монитор батареи, использующий libnotify для предупреждения о низком уровне заряда.
https://github.com/electrickite/batsignal || batsignal
  • cbatticon — Лёгкий и быстрый значок батареи в системном трее.
https://github.com/valr/cbatticon || cbatticon
  • GNOME Power Statistics — Информация о питании системы и статистика для среды GNOME.
https://gitlab.gnome.org/GNOME/gnome-power-manager || gnome-power-manager
  • KDE Power Devil — Модуль управления питанием для Plasma.
https://invent.kde.org/plasma/powerdevil || powerdevil
  • LXQt Power Management — Модуль управления питанием для LXQt.
https://github.com/lxqt/lxqt-powermanagement || lxqt-powermanagement
  • MATE Power Management — Инструмент управления питанием для MATE.
https://github.com/mate-desktop/mate-power-manager || mate-power-manager
  • MATE Power Statistics — Информация о питании системы и статистика для среды MATE.
https://github.com/mate-desktop/mate-power-manager || mate-power-manager
  • poweralertd — Демон для доставки уведомлений UPower.
https://git.sr.ht/~kennylevinsen/poweralertd || poweralertdAUR
  • powerkit — Менеджер питания, независимый от сред рабочего стола.
https://github.com/rodlie/powerkit || powerkitAUR
  • Xfce Power Manager — Менеджер питания для Xfce.
https://docs.xfce.org/xfce/xfce4-power-manager/start || xfce4-power-manager
  • vattery — Приложение, написанное на Vala, которое отображает состояние батареи ноутбука в системном трее.
https://www.jezra.net/projects/vattery.html || vatteryAUR

Управление питанием

События ACPI

systemd обрабатывает некоторые события ACPI, связанные с питанием. Выполняемые при этом действия можно настроить в /etc/systemd/logind.conf или /etc/systemd/logind.conf.d/*.conf — смотрите logind.conf(5). В системах без специального менеджера питания он может заменить демон acpid, который обычно использовался для реагирования на эти события ACPI.

Возможные действия — ignore, poweroff, reboot, halt, suspend, hibernate, hybrid-sleep, suspend-then-hibernate, lock или kexec. Для использования ждущего (suspend) и спящего (hibernate) режимов требуется предварительная настройка. При отсутствии настроек systemd будет выполнять действие по умолчанию.

Обработчик Описание Действие по умолчанию
HandlePowerKey Срабатывает, когда нажата кнопка питания. poweroff
HandleSuspendKey Срабатывает, когда нажата кнопка ждущего режима. suspend
HandleHibernateKey Срабатывает, когда нажата кнопка спящего режима. hibernate
HandleLidSwitch Срабатывает, когда закрывается крышка (ноутбука), за исключением описанных ниже случаев. suspend
HandleLidSwitchDocked Срабатывает, когда закрывается крышка, но система подключена к док-станции или подключено более одного монитора. ignore
HandleLidSwitchExternalPower Срабатывает, когда закрывается крышка, но система подключена к внешнему питанию. действие, установленное для HandleLidSwitch

Для применения изменений отправьте процессу systemd-logind сигнал HUP:

# systemctl kill -s HUP systemd-logind
Примечание: systemd не умеет обрабатывать события ACPI, связанные с внешним питанием или батареей, поэтому если вы используете Laptop Mode Tools или другие подобные инструменты, то acpid по-прежнему необходим.

Менеджеры питания

Некоторые среды рабочего стола предоставляют менеджеры питания, которые блокируют (inhibit, временно отключают) некоторые или все настройки systemd ACPI. Если такой менеджер питания запущен, то действия для событий ACPI могут быть настроены только в этом менеджере. Изменения в /etc/systemd/logind.conf или /etc/systemd/logind.conf.d/*.conf нужны только в том случае, если вы хотите настроить поведение для события, которое не блокируется используемым вами менеджером питания.

Обратите внимание, что если менеджер питания не блокирует соответствующие события в systemd, вы можете оказаться в ситуации, когда systemd уводит систему в сон, а затем, когда система пробуждается, другой менеджер питания снова уводит её в сон. Менеджеры питания KDE, GNOME, Xfce и MATE выдают необходимые команды inhibited. Если они не выдаются, например, при использовании acpid или других инструментов для обработки событий ACPI, установите в опциях Handle значение ignore. Смотрите также systemd-inhibit(1).

xss-lock

xss-lock подписывается на systemd-события suspend, hibernate, lock-session и unlock-session с соответствующими действиями (запустить блокировщик и ждать, пока пользователь разблокирует или убьёт блокировщик). xss-lock также реагирует на события DPMS и в ответ запускает или завершает блокировщик.

Добавьте xss-lock в автозапуск, например:

xss-lock -- i3lock -n -i фоновая_картинка.png &

Ждущий и спящий режимы

systemd предоставляет команды для перехода в ждущий (suspend) или спящий (hibernate) режим, использующие встроенную в ядро функциональность. Также есть механизм хуков для настройки действий до и после сна.

Команда systemctl suspend должна работать из коробки, а для systemctl hibernate требуется предварительная настройка, описанная в статье Ждущий и спящий режимы#Гибернация.

Также есть ещё два режима, комбинирующих ждущий и спящий режимы:

  • systemctl hybrid-sleep сохраняет состояние системы одновременно и в оперативной памяти, и на диске, благодаря чему отключение питания не приводит к потере данных. Этот режим также называют suspend to both.
  • systemctl suspend-then-hibernate изначально уходит в ждущий режим на максимально возможное время, затем по сигналу от аппаратных часов (или по сигналу о низком заряде батареи, если это реализовано в системе) просыпается и уходит в спящий режим. Время срабатывания аппаратных часов указывается в настройке HibernateDelaySec в файле systemd-sleep.conf(5). Значение по умолчанию вычисляется на основе скорости разряда батареи так, чтобы к моменту пробуждения оставалось 5% заряда; если батареи нет, то значение по умолчанию 2 часа. Вычисление производится на основе измерения уровня заряда батареи после времени, заданного в настройке SuspendEstimationSec в systemd-sleep.conf(5): после истечения указанного времени система ненадолго проснётся для выполнения измерения (измерение также производится при пробуждении пользователем).

Отключение сна

При использовании устройства в качестве, например, сервера уход в сон может быть не нужен или даже нежелателен. Можно настроить любое состояние сна:

/etc/systemd/sleep.conf.d/disable-suspend.conf
[Sleep]
AllowSuspend=no
AllowHibernation=no
AllowSuspendThenHibernate=no
AllowHybridSleep=no

Хуки

Файлы служб

Можно запускать службы до или после сна, если связать их с юнитами suspend.target, hibernate.target, sleep.target, hybrid-sleep.target и suspend-then-hibernate.target. Для общесистемных и пользовательских действий нужно создавать отдельные файлы. Ниже приведены примеры таких файлов; включите службы suspend@пользователь и resume@пользователь.

/etc/systemd/system/suspend@.service
[Unit]
Description=User suspend actions
Before=sleep.target

[Service]
User=%I
Type=forking
Environment=DISPLAY=:0
ExecStartPre= -/usr/bin/pkill -u %u unison ; /usr/local/bin/music.sh stop
ExecStart=/usr/bin/sflock
ExecStartPost=/usr/bin/sleep 1

[Install]
WantedBy=sleep.target
/etc/systemd/system/resume@.service
[Unit]
Description=User resume actions
After=suspend.target

[Service]
User=%I
Type=simple
ExecStart=/usr/local/bin/ssh-connect.sh

[Install]
WantedBy=suspend.target
Примечание: Так как процесс, запускающий блокировку экрана, может завершиться до того, как экран реально заблокируется, — есть вероятность, что экран не успеет заблокироваться перед уходом в сон, и после пробуждения на экране может на мгновение отобразиться незаблокированный рабочий стол. Добавление небольшой задержки через ExecStartPost=/usr/bin/sleep 1 помогает предотвратить это, позволяя блокировщику экрана успеть заблокировать экран.

Пример для общесистемных действий (включите службы root-resume и root-suspend):

/etc/systemd/system/root-suspend.service
[Unit]
Description=Local system suspend actions
Before=sleep.target

[Service]
Type=simple
ExecStart=-/usr/bin/pkill sshfs

[Install]
WantedBy=sleep.target
/etc/systemd/system/root-resume.service
[Unit]
Description=Local system resume actions
After=suspend.target

[Service]
Type=simple
ExecStart=/usr/bin/systemctl restart mnt-media.automount

[Install]
WantedBy=suspend.target
Совет: Несколько советов по поводу этих файлов служб (подробнее в systemd.service(5)):
  • Если указать Type=oneshot, то вы сможете использовать несколько строк ExecStart=. В противном случае допускается только одна строка ExecStart. Вы можете добавлять дополнительные команды либо с помощью ExecStartPre, либо разделяя команды точкой с запятой (смотрите первый пример выше; обратите внимание на пробелы до и после точки с запятой, так как они обязательны).
  • Если к команде добавить префикс -, то ненулевой статус выхода будет игнорироваться и любое завершение работы команды будет считаться успешным выполнением команды.
  • Лучшее место для поиска ошибок при решении проблем, связанных с этими файлами, — это, конечно, journalctl.

Комбинированный файл службы

При использовании комбинированного файла службы один и тот же хук выполняет всю работу для разных фаз (сон и пробуждение) и для разных целей (ждущий/спящий/гибридный режимы).

Пример и объяснение:

/etc/systemd/system/wicd-sleep.service
[Unit]
Description=Wicd sleep hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/usr/share/wicd/daemon/suspend.py
ExecStop=-/usr/share/wicd/daemon/autoconnect.py

[Install]
WantedBy=sleep.target
  • RemainAfterExit=yes: После запуска служба считается активной до тех пор, пока её явно не остановят.
  • StopWhenUnneeded=yes: Если служба активна, она будет остановлена, если ни одна другая активная служба не нуждается в ней. В данном конкретном примере она будет остановлена после остановки sleep.target.
  • Поскольку sleep.target связан с suspend.target, hibernate.target и hybrid-sleep.target и поскольку sleep.target сам является StopWhenUnneeded службой, хук гарантированно запустится/остановится правильно для различных режимов.
Общая служба-шаблон

В следующем примере показана служба-шаблон, которая может быть использована для подключения любой существующей службы systemd к событиям питания:[1]

/etc/systemd/system/sleep@.service
[Unit]
Description=%I sleep hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=-/usr/bin/systemctl stop %i
ExecStop=-/usr/bin/systemctl start %i

[Install]
WantedBy=sleep.target

Включите экземпляр этого шаблона, после символа @ указав название существующей службы systemd, то есть sleep@название-файла-службы.service. Смотрите systemd.unit(5) § DESCRIPTION для более подробной информации о юнитах-шаблонах.

Совет: Шаблоны не ограничены управлением службами systemd и могут использоваться с другими программами. Примеры можно посмотреть здесь: [2]

Хуки в /usr/lib/systemd/system-sleep

systemd запускает все исполняемые файлы из каталога /usr/lib/systemd/system-sleep/, передавая им два аргумента:

  • Аргумент 1: pre или post в зависимости от того, уходит ли система в сон или пробуждается
  • Аргумент 2: suspend, hibernate или hybrid-sleep в зависимости от конкретного режима сна

systemd запускает все файлы одновременно, а не последовательно друг за другом.

Вывод будет записан в журнал службы systemd-suspend.service, systemd-hibernate.service или systemd-hybrid-sleep.service, который можно посмотреть с помощью journalctl:

# journalctl -b -u systemd-suspend.service
Примечание: Вместо написания скриптов можно связывать юниты systemd с sleep.target, suspend.target, hibernate.target или hybrid-sleep.target.

Пример скрипта:

/usr/lib/systemd/system-sleep/example.sh
#!/bin/sh
case $1/$2 in
  pre/*)
    echo "Going to $2..."
    ;;
  post/*)
    echo "Waking up from $2..."
    ;;
esac

Не забудьте сделать скрипт исполняемым.

Смотрите systemd.special(7) и systemd-sleep(8) для более подробной информации.

Решение проблем

Отложенное выполнение действия при закрытии крышки ноутбука

Если ноутбук закрывается и открывается несколько раз подряд, logind задержит переход в ждущий режим до 90 секунд, чтобы дать ядру время для обнаружения подключенной док-станции. [3] С версии systemd v220 время задержки можно настроить:[4]

/etc/systemd/logind.conf
...
HoldoffTimeoutSec=30s
...

Fn-кнопка сна на ноутбуке не работает

Если независимо от настроек в logind.conf кнопка сна не работает (её нажатие даже не приводит к появлению сообщения в syslog), то logind, вероятно, не отслеживает клавиатуру. [5] Выполните:

# journalctl --grep="Watching system buttons"

Вы увидите что-то подобное:

May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event2 (Power Button)
May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event3 (Sleep Button)
May 25 21:28:19 vmarch.lan systemd-logind[210]: Watching system buttons on /dev/input/event4 (Video Bus)

Если здесь нет клавиатуры, то найдите её ATTRS{name} [6] :

# udevadm info -a /dev/input/by-path/*-kbd
...
KERNEL=="event0"
...
ATTRS{name}=="AT Translated Set 2 keyboard"

И напишите правило udev для добавления тега "power-switch":

/etc/udev/rules.d/70-power-switch-my.rules
ACTION=="remove", GOTO="power_switch_my_end"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="AT Translated Set 2 keyboard", TAG+="power-switch"
LABEL="power_switch_my_end"

Перезапустите службу systemd-udevd.service, перезагрузите правила выполнением команды udevadm trigger от имени root и перезапустите службу systemd-logind.service.

Теперь в журнале должна появиться строка, связанная с клавиатурой: Watching system buttons on /dev/input/event0.

Компьютер с чипсетом A520I или B550I не пробуждается

На некоторых материнских платах с чипсетами A520i и B550i система не полностью входит в состояние сна или выходит из него. Симптомы: система переходит в сон, монитор выключается, а внутренние светодиоды на материнской плате или светодиод питания остаются включенными. Впоследствии система не возвращается из этого состояния и требует полного выключения питания. Если у вас возникли подобные проблемы с AMD, сначала убедитесь, что ваша система полностью обновлена, и проверьте, установлен ли пакет с микрокодом для AMD.

Убедитесь, что строка, начинающаяся с GPP0, имеет статус enabled:

$ cat /proc/acpi/wakeup
Device	S-state	  Status   Sysfs node
GP12	  S4	*enabled   pci:0000:00:07.1
GP13	  S4	*enabled   pci:0000:00:08.1
XHC0	  S4	*enabled   pci:0000:0b:00.3
GP30	  S4	*disabled
GP31	  S4	*disabled
PS2K	  S3	*disabled
GPP0	  S4	*enabled   pci:0000:00:01.1
GPP8	  S4	*enabled   pci:0000:00:03.1
PTXH	  S4	*enabled   pci:0000:05:00.0
PT20	  S4	*disabled
PT24	  S4	*disabled
PT26	  S4	*disabled
PT27	  S4	*disabled
PT28	  S4	*enabled   pci:0000:06:08.0
PT29	  S4	*enabled   pci:0000:06:09.0

Если enabled, вы можете выполнить следующую команду:

# echo GPP0 > /proc/acpi/wakeup

Теперь проверьте, запустив systemctl suspend и позволив системе перейти в ждущий режим. Затем попробуйте разбудить систему через несколько секунд. Если это сработает, вы можете сделать этот обходной путь постоянным. Создайте файл юнита systemd:

/etc/systemd/system/toggle-gpp0-to-fix-wakeup.service
[Unit]
Description="Disable GPP0 to fix suspend issue"

[Service]
ExecStart=/bin/sh -c "/bin/echo GPP0 > /proc/acpi/wakeup"

[Install]
WantedBy=multi-user.target

Выполните daemon-reload и запустите/включите этот юнит.

Советы и рекомендации

Подкачка только для спящего режима

Иногда может потребоваться, чтобы подкачка включалась только для спящего режима и выключалась после пробуждения.

Хотя это можно реализовать с помощью описанных выше хуков, можно также напрямую настроить юнит подкачки (смотрите systemd.swap(5)):

/etc/systemd/system/путь-к-подкачке.swap
[Unit]
Before=systemd-hibernate.service
StopWhenUnneeded=true

[Swap]
What=/путь/к/подкачке
Options=noauto

[Install]
RequiredBy=systemd-hibernate.service

Обратите внимание, что имя файла юнита должно соответствовать пути подкачки и что юнит должен быть включен, чтобы параметр RequiredBy= вступил в силу.

Можно также прописать в зависимости hibernate.target вместо systemd-hibernate.service, но тогда прямой запуск systemctl start systemd-hibernate.service не будет работать.

Обратите внимание, что среды рабочего стола теперь могут не показывать опцию перехода в спящий режим и systemctl hibernate не будет работать, потому что они запрашивают у systemd-logind доступные режимы энергосбережения, а он не будет сообщать о возможности перехода в спящий режим, если нет активной подкачки.

Это можно обойти, запустив systemd-logind с переменной окружения SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1, например, создав drop-in файл:

/etc/systemd/system/systemd-logind.service.d/disable-hibernation-swap-check.conf
[Service]
Environment="SYSTEMD_BYPASS_HIBERNATION_MEMORY_CHECK=1"

Энергосбережение

Примечание: Специфичные для ноутбуков вещи, такие как мониторинг батареи, описаны в статье Laptop#Power management. Также посмотрите статьи для ваших моделей процессора или видеокарты (например, Ryzen или AMDGPU).

Данный раздел является справочником по созданию скриптов и настроек энергосбережения, например, с помощью правил udev. Убедитесь, что настройки не управляются каким-либо другим пользовательским инструментом, чтобы не было конфликтов.

Почти все перечисленные здесь функции стоит использовать независимо от того, работает ли компьютер от сети или от батареи. Большинство из них имеют незначительное влияние на производительность и просто не включены по умолчанию из-за распространённых неисправностей оборудования/драйверов. Снижение энергопотребления означает снижение тепловыделения, что может даже привести к повышению производительности современного процессора Intel или AMD благодаря динамическому изменению тактовой частоты.

Процессоры с поддержкой Intel HWP (Intel Hardware P-state)

Доступные энергетические предпочтения (energy preferences) процессора, поддерживающего HWP: default, performance, balance_performance, balance_power, power.

Это можно проверить командой

$ cat /sys/devices/system/cpu/cpufreq/policy?/energy_performance_available_preferences

Чтобы сэкономить больше энергии, можно создать следующий файл:

/etc/tmpfiles.d/energy_performance_preference.conf
w /sys/devices/system/cpu/cpufreq/policy?/energy_performance_preference - - - - balance_power

Смотрите systemd-tmpfiles(8) и tmpfiles.d(5) для более подробной информации.

Звук

Ядро

По умолчанию энергосбережение звуковых устройств отключено в большинстве драйверов. Его можно включить, задав параметр power_save — время (в секундах) до перехода в режим ожидания. Чтобы отключить звуковую карту через одну секунду, создайте следующий файл для звуковых карт Intel.

/etc/modprobe.d/audio_powersave.conf
options snd_hda_intel power_save=1

Для ac97 используйте следующее:

options snd_ac97_codec power_save=1
Примечание:
  • Чтобы узнать производителя звуковой карты и соответствующий драйвер ядра, выполните lspci -k.
  • Переключение состояния питания аудиокарты может вызвать щёлкающий звук или заметную задержку на некотором оборудовании.

Также можно ещё больше снизить требования к питанию звука, отключив аудиовыход HDMI, что можно сделать, заблокировав соответствующие модули ядра (например, snd_hda_codec_hdmi для Intel).

PulseAudio

По умолчанию PulseAudio приостанавливает работу всех источников звука, которые слишком долго простаивают. При использовании внешнего USB-микрофона запись может начинаться с щелчком. В качестве обходного пути закомментируйте следующую строку в файле /etc/pulse/default.pa:

load-module module-suspend-on-idle

После этого перезапустите PulseAudio: systemctl restart --user pulseaudio.

Подсветка экрана

Смотрите Backlight (Русский).

Bluetooth

Чтобы полностью отключить Bluetooth, заблокируйте модули btusb и bluetooth.

Для временного отключения используйте rfkill:

# rfkill block bluetooth

Или с помощью правила udev:

/etc/udev/rules.d/50-bluetooth.rules
# disable bluetooth
SUBSYSTEM=="rfkill", ATTR{type}=="bluetooth", ATTR{state}="0"

Веб-камера

Если вы не используете встроенную веб-камеру, заблокируйте модуль uvcvideo.

Параметры ядра

Этот раздел использует конфигурацию /etc/sysctl.d/ — drop-in каталог для sysctl-параметров ядра. Смотрите The New Configuration Files и sysctl.d(5) для более подробной информации.

Отключение сторожевого таймера с NMI

Сторожевой таймер, использующий немаскируемое прерывание (Non-maskable interrupt), — это отладочная функция, позволяющая отлавливать аппаратные зависания, которые вызывают панику ядра. В некоторых системах он может генерировать большое количество прерываний, вызывая заметное увеличение энергопотребления:

/etc/sysctl.d/disable_watchdog.conf
kernel.nmi_watchdog = 0

Или добавьте nmi_watchdog=0 в параметры ядра для полного отключения с начала загрузки.

Время Writeback

Увеличение времени перед записью изменённых данных из памяти на диск помогает сгруппировать операции ввода-вывода, тем самым уменьшая нагрузку на диск и потребление энергии. Чтобы установить значение 60 секунд (по умолчанию 5 секунд):

/etc/sysctl.d/dirty.conf
vm.dirty_writeback_centisecs = 6000

Чтобы сделать то же самое для записи журналов на поддерживаемых файловых системах (например, ext4, btrfs...), используйте commit=60 в качестве опции в fstab.

Обратите внимание, что это значение изменяется как побочный эффект настройки Laptop Mode, приведённой ниже. Другие параметры, влияющие на производительность ввода-вывода и энергосбережение, описаны в разделе sysctl (Русский)#Виртуальная память.

Laptop Mode

Смотрите документацию ядра. "A sensible value for the knob is 5 seconds."

/etc/sysctl.d/laptop.conf
vm.laptop_mode = 5
Примечание: Эта настройка в основном относится к жёстким дискам.

Сетевые интерфейсы

Wake-on-LAN может быть полезной функцией, но если вы не используете её, то она впустую потребляет дополнительную энергию в режиме сна. Вы можете адаптировать правило Wake-on-LAN#udev, чтобы отключить эту функцию для всех Ethernet-интерфейсов. Чтобы включить энергосбережение с помощью iw на всех беспроводных интерфейсах:

/etc/udev/rules.d/81-wifi-powersave.rules
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wl*", RUN+="/usr/bin/iw dev $name set power_save on"

Имя этого файла имеет важное значение. При использовании постоянных имён устройств в systemd это правило, которое в лексикографической сортировке находится после 80-net-setup-link.rules, применяется после переименования устройства в его постоянное имя, например wlan0 переименовывается в wlp3s0. Помните, что команда RUN выполняется после обработки всех правил и в любом случае должна использовать постоянное имя, доступное в $name для сопоставленного устройства.

Беспроводные карты Intel (iwlwifi)

Дополнительные функции энергосбережения беспроводных карт Intel с драйвером iwlwifi можно включить путём передачи правильных параметров в модуль ядра. Сделать их постоянными можно, добавив следующие строки в файл /etc/modprobe.d/iwlwifi.conf:

options iwlwifi power_save=1

Эта опция, вероятно, увеличит медианную задержку:

options iwlwifi uapsd_disable=0

На ядрах < 5.4 вы можете использовать эту опцию, но это, вероятно, снизит максимальную пропускную способность:

options iwlwifi d0i3_disable=0

В зависимости от вашей беспроводной карты будет применяться один из этих двух вариантов.

options iwlmvm power_scheme=3
options iwldvm force_cam=0

Вы можете проверить, какой из них является актуальным, проверив, какой из этих модулей запущен, используя

# lsmod | grep '^iwl.vm'

Помните, что эти варианты энергосбережения являются экспериментальными и могут привести к нестабильной работе системы.

Управление питанием шин

Active State Power Management

Если система считает, что компьютер не поддерживает ASPM, он будет отключен при загрузке:

# lspci -vv | grep 'ASPM.*abled;'

ASPM управляется через BIOS. Если ASPM отключен, это происходит потому, что [7]:

  1. BIOS отключил его по какой-то причине (из-за конфликтов?).
  2. PCIE требует ASPM, но L0s необязательны (поэтому L0s могут быть отключены, а включен только L1).
  3. BIOS мог быть не запрограммирован для этого.
  4. BIOS глючит.

Если компьютер точно поддерживает ASPM, его можно принудительно включить с помощью параметра ядра pcie_aspm=force.

Важно:
  • Принудительное включение ASPM может вызвать зависание/панику, поэтому убедитесь, что у вас есть возможность удалить этот параметр, если он не сработает.
  • На системах, которые не поддерживают эту функцию, принудительное включение ASPM может даже увеличить энергопотребление.
  • Это принудительно включает ASPM в ядре, в то время как в аппаратной части он может оставаться отключенным и не работать. Чтобы проверить, так ли это, выполните dmesg | grep ASPM от имени root. Если да, обратитесь к вики-статье, относящейся к вашему оборудованию.

Чтобы переключиться на powersave, выполните (следующая команда не будет работать, если ASPM не включен):

# echo powersave > /sys/module/pcie_aspm/parameters/policy

По умолчанию этот файл выглядит примерно так:

$ cat /sys/module/pcie_aspm/parameters/policy
[default] performance powersave powersupersave

PCI Runtime Power Management

/etc/udev/rules.d/pci_pm.rules
SUBSYSTEM=="pci", ATTR{power/control}="auto"

Это правило выключает все неиспользуемые устройства, но некоторые из них не проснутся обратно. Чтобы разрешить Runtime Power Management только для устройств, о которых известно, что они работают нормально, используйте простое сопоставление с идентификаторами производителя и устройства (используйте lspci -nn для получения этих значений):

/etc/udev/rules.d/pci_pm.rules
# whitelist for pci autosuspend
SUBSYSTEM=="pci", ATTR{vendor}=="0x1234", ATTR{device}=="0x1234", ATTR{power/control}="auto"

Альтернативный вариант — заблокировать устройства, не работающие с PCI Runtime Power Management, и включить его для всех остальных устройств:

/etc/udev/rules.d/pci_pm.rules
# blacklist for pci runtime power management
SUBSYSTEM=="pci", ATTR{vendor}=="0x1234", ATTR{device}=="0x1234", ATTR{power/control}="on", GOTO="pci_pm_end"

SUBSYSTEM=="pci", ATTR{power/control}="auto"
LABEL="pci_pm_end"

Автоматическая приостановка устройств USB

Ядро Linux может автоматически приостанавливать работу USB-устройств, когда они не используются (USB autosuspend). Иногда это позволяет сэкономить довольно много энергии, однако некоторые USB-устройства не совместимы с функцией энергосбережения и начинают вести себя неадекватно (частое явление среди USB-мышей/клавиатур). Правила udev, основанные на фильтрации по белым или чёрным спискам, могут помочь смягчить проблему.

Самый простой и, скорее всего, бесполезный пример — включение автоматической приостановки для всех USB-устройств:

/etc/udev/rules.d/50-usb_power_save.rules
ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="auto"

Чтобы разрешить автоотключение только для устройств, о которых известно, что они работают нормально, используйте простое сопоставление с идентификаторами производителя и продукта (используйте lsusb для получения этих значений):

/etc/udev/rules.d/50-usb_power_save.rules
# whitelist for usb autosuspend
ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", ATTR{power/control}="auto"

Альтернативный вариант — заблокировать устройства, не работающие с USB autosuspend, и включить его для всех остальных устройств:

/etc/udev/rules.d/50-usb_power_save.rules
# blacklist for usb autosuspend
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", GOTO="power_usb_rules_end"

ACTION=="add", SUBSYSTEM=="usb", TEST=="power/control", ATTR{power/control}="auto"
LABEL="power_usb_rules_end"

Время задержки по умолчанию контролируется параметром autosuspend встроенного модуля ядра usbcore. Чтобы установить задержку на 5 секунд вместо стандартных 2 секунд, добавьте следующий параметр ядра в настройках вашего загрузчика:

usbcore.autosuspend=5

По аналогии с power/control, время задержки можно изменить для отдельного устройства с помощью атрибута power/autosuspend. Установка значения -1 полностью отключит автоматическую приостановку:

/etc/udev/rules.d/50-usb_power_save.rules
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9205", ATTR{power/autosuspend}="-1"

Дополнительная информации об управлении питанием USB доступна в документации ядра.

SATA Active Link Power Management

Важно: SATA Active Link Power Management может привести к потере данных на некоторых устройствах. Не включайте это, если вы не создаёте резервные копии регулярно.

В Linux 4.15 появилась новая настройка med_power_with_dipm, которая соответствует поведению настроек драйвера Windows IRST и не должна приводить к потере данных на последних SSD или HDD. Экономия энергии может быть значительной — от 1,0 до 1,5 Вт (в режиме ожидания). Это станет настройкой по умолчанию для ноутбуков на базе Intel в Linux 4.16 [8].

Текущую настройку можно прочитать из /sys/class/scsi_host/host*/link_power_management_policy с помощью команды:

$ cat /sys/class/scsi_host/host*/link_power_management_policy
Доступные настройки ALPM
Настройка Описание Энергосбережение
max_performance текущее значение по умолчанию нет
medium_power - ~1,0 Вт
med_power_with_dipm рекомендуемое значение ~1,5 Вт
min_power ВНИМАНИЕ: возможна потеря данных ~1,5 Вт
/etc/udev/rules.d/hd_power_save.rules
ACTION=="add", SUBSYSTEM=="scsi_host", KERNEL=="host*", ATTR{link_power_management_policy}="med_power_with_dipm"
Примечание: Это увеличивает задержку при обращении к диску, который простаивал, поэтому это один из немногих параметров, которые стоит переключать в зависимости от того, подключено ли внешнее питание или нет.

Жёсткие диски

Возможные параметры для управления питанием диска описаны в разделе hdparm (Русский)#Настройка управления питанием.

Сберечь энергию не получится, если много программ часто записывают данные на диск. Отслеживание всех программ, а также того, как и когда они записывают данные на диск, является способом ограничения использования диска. Используйте iotop, чтобы увидеть, какие программы часто используют диск. Другие советы есть в разделе Увеличение производительности#Устройства хранения.

Также могут помочь такие мелочи, как установка опции noatime. Если доступно достаточно оперативной памяти, подумайте об отключении или ограничении swappiness, так как это может заметно уменьшить запись на диск.

Для дисков Seagate с технологией PowerChoice трюки с настройкой APM через hdparm не работают. Вместо этого установите пакет seagate-seachestAUR. Например, для полного отключения EPC на диске можно использовать следующее:

# SeaChest_PowerControl --scan
# SeaChest_PowerControl -d /dev/sdX -i
# SeaChest_PowerControl -d /dev/sdX --showEPCSettings
# SeaChest_PowerControl -d /dev/sdX --EPCfeature disable
# SeaChest_PowerControl -d /dev/sdX --showEPCSettings

Последняя команда выведет информацию:

==========================================================================================
 SeaChest_PowerControl - Seagate drive utilities - NVMe Enabled
 Copyright (c) 2014-2022 Seagate Technology LLC and/or its Affiliates, All Rights Reserved
 SeaChest_PowerControl Version: 3.1.10-3_2_1 X86_64
 Build Date: Jul 26 2022
 Today: Sat May 20 15:49:25 2023        User: root
==========================================================================================

/dev/sdc - ST1000NM0008-2F2100 - ZFA19JG2 - SN02 - ATA
.

===EPC Settings===
        * = timer is enabled
        C column = Changeable
        S column = Savable
        All times are in 100 milliseconds

Name       Current Timer Default Timer Saved Timer   Recovery Time C S
Idle A      0            *10           *10           1             Y Y
Idle B      0            *1200         *1200         3             Y Y
Idle C      0             6000          6000         16            Y Y
Standby Z   0             9000          9000         46            Y Y

Нули в первом столбце означают, что парковка и остановка вращения были отключены.

Инструменты и скрипты

Использование скрипта с правилом udev

Поскольку пользователи systemd могут переводить систему в ждущий или спящий режим через systemctl suspend или systemctl hibernate и обрабатывать события acpi с помощью /etc/systemd/logind.conf, может быть интересно удалить pm-utils и acpid. Есть только одна вещь, которую systemd не может сделать (по состоянию на systemd-204): управление питанием в зависимости от того, работает ли система от сети или от батареи. Чтобы заполнить этот пробел, вы можете создать правило udev, которое запускает скрипт при подключении и отключении внешнего питания:

/etc/udev/rules.d/powersave.rules
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/путь/к/вашему/скрипту true"
SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/путь/к/вашему/скрипту false"
Примечание: Вы можете использовать тот же скрипт, что и в pm-powersave. Вам просто нужно сделать его исполняемым и поместить в другое место (например, /usr/local/bin/).

Примеры powersave скриптов:

Приведённое выше правило udev должно работать как задумано, но если ваши настройки питания не обновляются после пробуждения системы, добавьте такой скрипт в /usr/lib/systemd/system-sleep/:

/usr/lib/systemd/system-sleep/00powersave
#!/bin/sh

case $1 in
    pre) /путь/к/вашему/скрипту false ;;
    post)
	if cat /sys/class/power_supply/AC0/online | grep 0 > /dev/null 2>&1
	then
    		/путь/к/вашему/скрипту true
	else
    		/путь/к/вашему/скрипту false
	fi
    ;;
esac
exit 0

Не забудьте сделать его исполняемым.

Примечание: Название AC0 может быть другим на вашем ноутбуке, измените его по необходимости.

Вывод параметров питания

Этот скрипт выводит параметры питания и ряд других свойств для USB и PCI устройств. Обратите внимание, что для просмотра всех настроек необходимы права root.

#!/bin/bash

for i in $(find /sys/devices -name "bMaxPower")
do
	busdir=${i%/*}
	busnum=$(<$busdir/busnum)
	devnum=$(<$busdir/devnum)
	title=$(lsusb -s $busnum:$devnum)

	printf "\n\n+++ %s\n  -%s\n" "$title" "$busdir"

	for ff in $(find $busdir/power -type f ! -empty 2>/dev/null)
	do
		v=$(cat $ff 2>/dev/null|tr -d "\n")
		[[ ${#v} -gt 0 ]] && echo -e " ${ff##*/}=$v";
		v=;
	done | sort -g;
done;

printf "\n\n\n+++ %s\n" "Kernel Modules"
for mod in $(lspci -k | sed -n '/in use:/s,^.*: ,,p' | sort -u)
do
	echo "+ $mod";
	systool -v -m $mod 2> /dev/null | sed -n "/Parameters:/,/^$/p";
done

Разрешить пользователям выключение системы

События нажатия кнопки питания и закрытия крышки ноутбука

События нажатия кнопок ждущего режима, выключения и режима гибернации, а также закрытия крышки ноутбука обрабатываются logind, как описано в разделе #События ACPI.

Используя systemd-logind

Если вы используете polkit, пользователи через локальный сеанс могут вызывать команды управления режимами электропитания, пока сеанс не будет нарушен.

Чтобы убедиться, что ваш сеанс активен, наберите:

$ loginctl show-session $XDG_SESSION_ID --property=Active

Пользователь может использовать команды systemctl в командной строке, или добавить их в меню среды рабочего стола:

$ systemctl poweroff
$ systemctl reboot

Другие команды, такие как systemctl suspend и systemctl hibernate также могут быть использованы. Смотрите раздел System Commands в справочном руководстве systemctl(1).

Используя sudo

Установите sudo и добавьте текущего пользователя в список sudoers. После этого, текущий пользователь сможет вызывать команды sudo systemctl (например, sudo systemctl poweroff, sudo systemctl reboot, sudo systemctl suspend и sudo systemctl hibernate) через sudo из командной строки. Смотрите раздел System Commands в справочном руководстве systemctl(1).

Ограничение привилегий sudo

Если пользователю следует разрешить только, например, использовать команду выключения, добавьте следующее в конец файла /etc/sudoers, используя команду visudo:

имя_пользователя имя_хоста=NOPASSWD: /usr/bin/systemctl poweroff,/usr/bin/systemctl halt,/usr/bin/systemctl reboot

Имя хоста вы можете не указывать (или указать localhost). Теперь пользователь сможет выключить компьютер используя sudo systemctl poweroff или sudo systemctl halt, и перезагрузить его с помощью sudo systemctl reboot без ввода пароля. Удалите NOPASSWD:, если вы хотите, чтобы у пользователя запрашивался его пароль перед продолжением.

Смотрите также