Power management (Русский)/Suspend and hibernate (Русский)

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

Существует несколько режимов приостановки работы компьютера, в частности:

Suspend to idle
Intel называет его S0ix, Microsoft — Modern Standby (ранее «Connected Standby»), а ядро — S2Idle. Предназначен для использования вместо состояния S3 в поддерживаемых системах, обеспечивая идентичное энергосбережение, но значительно сокращая время пробуждения.
Совет: Хотя в Windows или macOS это состояние может привести к разряду батареи, поскольку они могут пробуждать устройства для подключения к сети, Linux эту функцию в настоящее время не использует и не должен быть подвержен этой проблеме.
Suspend to RAM (ждущий режим, сон)
Состояние S3 по определению ACPI. Отключает питание большинства устройств компьютера, кроме оперативной памяти, которая продолжает хранить в себе состояние компьютера для его восстановления при пробуждении. Из-за большой экономии энергии рекомендуется, чтобы ноутбуки автоматически входили в этот режим при работе от батареи и закрытой крышке (или когда пользователь неактивен в течение некоторого времени).
Suspend to disk (спящий режим, гибернация)
Состояние S4 по определению ACPI. Сохраняет состояние машины в подкачку и полностью выключает её. При включении питания состояние восстанавливается. До этого момента энергопотребление равно нулю.
Hybrid suspend (гибридный спящий режим)
Гибрид ждущего и спящего режимов, иногда называется suspend to both. Сохраняет состояние машины в подкачку, но не выключает её. Вместо этого выполняется переход в обычный ждущий режим. Поэтому, если батарея не разряжена, система может возобновить работу мгновенно. Если батарея разряжена, система может восстановить своё состояние с диска, что намного медленнее, чем возобновление работы из ОЗУ, но состояние не будет потеряно.

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

Низкоуровневые интерфейсы

Хотя эти интерфейсы могут использоваться напрямую, рекомендуется использовать #Интерфейсы высокого уровня для перехода в ждущий или спящий режим. Использование низкоуровневых интерфейсов напрямую существенно быстрее, чем использование любого интерфейса высокого уровня, поскольку запуск всех хуков перед сном и после него требует времени, но хуки могут правильно устанавливать аппаратные часы, восстанавливать беспроводное соединение и т.д.

Ядро (swsusp)

Самый простой подход для входа в режим сна заключается в прямом информировании встроенного программного кода ядра (swsusp); точный метод и состояние зависят от уровня аппаратной поддержки. В современных ядрах основным механизмом переключения режимов является запись соответствующих значений в /sys/power/state.

Cмотрите документацию ядра для подробностей.

Интерфейсы высокого уровня

Конечной целью этих пакетов является предоставление программ (двоичных файлов/скриптов), которые могут быть вызваны для выполнения приостановки компьютера. Фактическая привязка их к кнопкам питания, пунктам меню или событиям крышки ноутбука обычно делегируется другим инструментам. Чтобы автоматически приостановить работу при определённых событиях, таких как закрытие крышки ноутбука или снижение заряда батареи, вам может потребоваться запустить acpid.

systemd

systemd предоставляет собственные команды для ждущего, спящего и гибридного режимов сна, смотрите Управление питанием#Управление питанием для подробностей. Это интерфейс по умолчанию, используемый в Arch Linux.

Смотрите Управление питанием#Хуки для получения дополнительной информации о настройке хуков, связанных с режимами сна. Также смотрите systemctl(1), systemd-sleep(8) и systemd.special(7).

Изменение режима сна

В системах, где режим S0ix не обеспечивает такой же экономии энергии, как обычный ждущий режим S3, или когда экономия энергии предпочтительнее быстрого возобновления работы, возможно изменение режима сна, используемого по умолчанию.

Совет: S0ix призван обеспечивать такую же или лучшую экономию энергии, как и S3. Для проверки, сможете вы заставить его работать как задумано, смотрите записи в блоге Intel: How to achieve S0ix states in Linux, Linux S0ix Troubleshooting и Idling Efficiently on Linux: A Case Study.

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

$ cat /sys/power/mem_sleep
[s2idle] shallow deep

Если deep отсутствует, для начала проверьте, нет ли в UEFI каких-нибудь настроек для него, обычно в разделе Power или Sleep state или похожей формулировке, с опциями Windows 10, Windows and Linux или S3/Modern standby support для режима S0ix, и Legacy, Linux, Linux S3 или S3 enabled для режима S3. В противном случае можно продолжать использовать s2idle, рассмотрите возможность использования гибернации (спящего режима) или исправления таблицы DSDT (или найти исправленную версию в Интернете).

Примечание: Последнее решение, скорее всего, вызовет проблемы. Производители перестали исправлять ошибки режима S3 с тех пор, как системы, поставляемые с Windows, стали по умолчанию использовать «Modern standby»; если они сами не предлагают этот режим, то, вероятно, он сломан.

Убедитесь, что оборудование не испытывает проблем с режимом S3, протестировав несколько циклов сна после изменения режима:

# echo "deep" > /sys/power/mem_sleep

Если проблем не обнаружено, можно сделать изменение постоянным с помощью параметра ядра mem_sleep_default=deep.

Иногда сломанная прошивка сообщает о поддержке deep, в то время как реально поддерживается только s2idle. В этом случае альтернативный способ использования s2idle доступен через SuspendState в файле sleep.conf.d(5):

/etc/systemd/sleep.conf.d/freeze.conf
[Sleep]
SuspendState=freeze

Гибернация

Чтобы использовать спящий режим, вам нужно создать раздел или файл подкачки. Вам нужно будет указать ядру на своп, используя параметр resume=, который настраивается через загрузчик. Вам также понадобится настроить initramfs, чтобы ядро попыталось возобновить работу с указанного свопа в раннем пользовательском пространстве. Эти три этапа подробно описаны ниже.

Примечание:

Про размер раздела/файла подкачки

Даже если ваш раздел подкачки меньше ОЗУ, у вас все еще есть большая вероятность успешно перейти в спящий режим. Согласно ядерной документации:

/sys/power/image_size управляет размером образа, создаваемого механизмом приостановки на диск. Это может быть строка, представляющая неотрицательное целое число, которое будет использоваться в качестве верхнего предела размера образа в байтах. Механизм приостановки сделает все возможное, чтобы размер образа не превышал это число. Однако, если это окажется невозможным, он попытается приостановить все равно, используя наименьший возможный размер образа. В частности, если в этот файл записать «0», размер образа будет настолько мал на сколько это возможно. Чтение из этого файла отображает текущее ограничение размера образа, которое по умолчанию установлено на 2/5 доступного ОЗУ.

Вы можете либо уменьшить значение /sys/power/image_size, чтобы сделать образ как можно меньшим (для небольших разделов подкачки) или увеличить его, чтобы ускорить процесс гибернации. На системах с большим объёмом оперативной памяти меньшие значения могут существенно увеличить скорость пробуждения. Чтобы сделать изменение постоянным, можно использовать systemd-tmpfiles:

/etc/tmpfiles.d/hibernation_image_size.conf
#    Path                   Mode UID  GID  Age Argument
w    /sys/power/image_size  -    -    -    -   0

Создаваемый образ не может охватывать несколько разделов/файлов подкачки. Он должен полностью помещаться в один раздел/файл подкачки.[2]

Настройка initramfs

  • Когда используется initramfs с хуком base, а по умолчанию это так, то в файл /etc/mkinitcpio.conf также нужно добавить хук resume. Независимо от того, используется ли метка или UUID, раздел подкачки идентифицируется как устройство udev, поэтому хук resume должен идти после хука udev. Пример, основанный на стандартных параметрах хуков:
HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block filesystems resume fsck)
Не забудьте пересобрать образ initramfs чтобы эти изменения вступили в силу.
Примечание: При использовании LVM нужно добавить хук resume после хука lvm2.
  • Когда используется initramfs с хуком systemd, механизм возобновления уже есть и дополнительные хуки не нужны.

Необходимые параметры ядра

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

  • resume=UUID=4209c845-f495-4c43-8a03-5363dd433153
  • resume="PARTLABEL=Swap partition"
  • resume=/dev/archVolumeGroup/archLogicalVolume — если подкачка расположена на LVM (UUID и Label тоже должны работать)

Параметры ядра вступят в силу только после перезагрузки. Для немедленного перехода в спящий режим получите из lsblk major и minor номера устройства, на котором находится нужный том, и запишите их в формате major:minor в /sys/power/resume. Если используется файл подкачки, дополнительно запишите смещение в /sys/power/resume_offset. [3]

Например, если устройство подкачки имеет номер 8:3:

# echo 8:3 > /sys/power/resume

Или при использовании файла подкачки, если он находится на томе 8:2 и имеет смещение 38912:

# echo 8:2 > /sys/power/resume
# echo 38912 > /sys/power/resume_offset

Гибернация в файл подкачки

Для использования файла подкачки также необходимо установить параметры ядра resume=UUID=uuid_устройства_подкачки и resume_offset=смещение. Смотрите документацию ядра.

uuid_устройства_подкачки — это UUID того тома, на котором находится файл подкачки; здесь можно использовать тот же формат, что и в параметре root.

В файловых системах, отличных от Btrfs, смещение можно узнать с помощью команды filefrag -v файл_подкачки. Вывод осуществляется в виде таблицы, а искомое значение находится в первой строке столбца physical_offset.

Например:

# filefrag -v /swapfile
Filesystem type is: ef53
File size of /swapfile is 4294967296 (1048576 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       0:      38912..     38912:      1:
   1:        1..   22527:      38913..     61439:  22527:             unwritten
   2:    22528..   53247:     899072..    929791:  30720:      61440: unwritten
...

В данном примере смещение — это 38912 с двумя точками, и параметр ядра может выглядеть так: resume_offset=38912.

Для Btrfs не пытайтесь использовать filefrag, поскольку «физическое» смещение, полученное с помощью filefrag, не является реальным физическим смещением на диске; здесь используется виртуальное адресное пространство ради поддержки нескольких устройств.[4] Вместо этого используйте команду btrfs-inspect-internal(8). Например:

# btrfs inspect-internal map-swapfile -r /swap/swapfile
198122980

В данном примере смещение — это 198122980, и параметр ядра может выглядеть так: resume_offset=198122980.

{{Tip (Русский)|

  • Узнать uuid_устройства_подкачки можно командой findmnt -no UUID -T /swapfile
  • Узнать смещение на файловых системах, отличных от Btrfs, можно командой filefrag -v /swapfile | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'
Примечание:
  • Для стекового блочного устройства, такого как зашифрованный контейнер (LUKS), RAID или LVM, параметр resume должен указывать на конечное/разблокированное устройство, непосредственно содержащее файловую систему с файлом подкачки.
  • Если файл подкачки находится в /home/, systemd-logind не сможет определить его размер и тем самым откажется уводить систему в спящий режим со следующим сообщением: Failed to hibernate system via logind: Not enough swap space for hibernation. Есть два обходных пути, которые описаны в systemd issue 15354.
Совет: Возможно, стоит уменьшить swappiness, если единственной целью подкачки является возможность перехода в спящий режим, а не увеличение доступной памяти.

Гибернация в тонкий том LVM

Гибернация в тонкий том LVM (thinly-provisioned LVM volume) возможна, но необходимо убедиться, что том полностью выделен (fully allocated). В противном случае возобновление работы с него будет неудачным; смотрите FS#50703.

Вы можете полностью выделить том LVM, просто заполнив его нулями. Например:

# dd if=/dev/zero of=/dev/vg0/swap bs=1M status=progress

Для проверки того, что том полностью выделен, можно использовать:

# lvs
  LV                   VG  Attr       LSize   Pool Origin    Data%  Meta%  Move Log Cpy%Sync Convert
  swap                 vg0 Vwi-aot--- 10.00g  pool           100

Полностью выделенный том будет отображаться как использующий 100% данных.

Важно: Не используйте TRIM на тонких томах подкачки, используемых для спящего режима, то есть не используйте параметр discard в /etc/fstab и опцию -d/--discard в swapon. В противном случае используемое пространство будет деаллоцировано.

Технология Intel Rapid Start (IRST)

Intel Rapid Start Technology — это работающий на уровне прошивки метод сна, который позволяет перейти в спящий режим из ждущего через заданный интервал времени или в зависимости от состояния батареи. Он должен быть быстрее и надёжнее, чем обычный спящий режим, поскольку выполняется прошивкой, а не на уровне операционной системы. Как правило, эта функция должна быть включена в прошивке, и она же позволяет выбрать длительность ждущего режима или событие батареи, после которых будет выполнен переход в спящий режим. Однако некоторые устройства, несмотря на поддержку IRST в прошивке, позволяют настраивать его только через драйверы Intel для Windows. В таких случаях модуль ядра intel-rst должен обеспечить настройку событий в Linux.

При включенной технологии Intel Rapid Start Technology (IRST) для выхода из глубокого сна требуется «на несколько секунд больше, чем для выхода из S3, но намного меньше, чем для выхода из спящего режима».

Многие системы на базе Intel имеют встроенную поддержку IRST, но для этого требуется специальный раздел на SSD (а не на HDD). OEM-установки Windows могут иметь уже существующий раздел IRST, который можно оставить при установке Arch Linux (вместо очистки и переразметки всего SSD). Он должен отображаться как неотформатированный раздел, равный размеру ОЗУ системы.

Важно: Раздел Intel Rapid Start не зашифрован; «Intel рекомендует отключить технологию Intel Rapid Start, если вы используете программное шифрование диска». [5]

Однако если вы собираетесь стереть и переразметить весь диск (или уже сделали это), то раздел IRST необходимо создать заново, если вы планируете использовать эту технологию. Это можно сделать, создав пустой раздел, равный размеру ОЗУ системы, и установив для него тип раздела GUID D3BFE2DE-3DAF-11DF-BA40-E3A556D89593 для GPT или ID 0x84 для MBR. Вам также может потребоваться включить поддержку IRST в настройках прошивки вашей системы.

Совет: Время до срабатывания IRST (после приостановки) можно настроить в настройках прошивки системы.

Продолжительность процесса гибернации IRST (то есть копирования «всего содержимого ОЗУ в специальный раздел») зависит от размера ОЗУ системы и скорости SSD и, таким образом, может занять 20–60 секунд. Некоторые системы могут сигнализировать о завершении процесса светодиодным индикатором (LED), например, когда он перестаёт мигать.

Для настройки IRST через Linux требуется ядро, собранное с CONFIG_INTEL_RST. После загрузки модуля через modprobe intel_rst он должен создать файлы wakeup_events и wakeup_time в каталоге /sys/bus/acpi/drivers/intel_rapid_start/*/, которые можно использовать для настройки. Данный модуль имеет скудную документацию, подробности можно посмотреть в его исходном коде: drivers/platform/x86/intel/rst.c.

Смотрите также общие вопросы и ответы и руководства пользователей для технологии Intel Rapid Start.

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

ACPI_OS_NAME

Возможно, вы захотите настроить свою таблицу DSDT, чтобы заставить ее работать. Смотрите статью DSDT

Ждущий или спящий режим не работает или сбоит

Часто сообщают о том, что при переходе в ждущий или спящий режим экран становится чёрным, на нём не видно ошибок и ничего нельзя сделать. Эти проблемы наблюдались как на ноутбуках, так и на настольных компьютерах. Переход на более старое ядро, особенно на LTS-ядро, хоть и не является официальным решением, но может исправить ситуацию.

Проблема может возникнуть при использовании аппаратного сторожевого таймера (по умолчанию отключен, смотрите RuntimeWatchdogSec= в systemd-system.conf(5) § OPTIONS). Некорректная работа сторожевого таймера может привести к перезагрузке компьютера до того, как система завершит создание образа.

Иногда экран становится чёрным из-за инициализации устройств из initramfs. Удаление всех модулей из массива MODULES, удаление хука kms и пересборка образа initramfs могут решить эту проблему, в частности, с графическими драйверами для раннего запуска KMS. Инициализация таких устройств перед восстановлением состояния системы может привести к неконсистентности, что не позволит системе восстановиться. Это не влияет на пробуждение из ждущего режима. Также посмотрите статью Best practices to debug suspend issues.

Переход с видеодрайвера ATI на более новый AMDGPU также может способствовать корректной работе сна.

Для NVIDIA может помочь запрет загрузки модуля nvidiafb. [6]

На ноутбуках с процессором Intel, в которых загружен модуль intel_lpss_pci для тачпада, может случиться паника ядра при восстановлении (мигающий caps lock) [7]. Модуль нужно добавить в initramfs:

/etc/mkinitcpio.conf
MODULES=(... intel_lpss_pci ...)

После чего пересоберите образ initramfs.

Wake-on-LAN

Если функция Wake-on-LAN включена, сетевая карта будет потреблять энергию, даже если компьютер находится в спящем режиме.

Система мгновенно пробуждается из ждущего режима

Смотрите Wakeup triggers#Instantaneous wakeups from suspend.

Если вы используете ядро Linux 6.1 и выше на процессоре AMD, это также может быть вызвано проблемой политики управления в ядре, связанной с S3. Временным решением может быть отключение wakeup на соответствующих i2c-устройствах. Их можно найти так:

$ ls /sys/bus/i2c/devices/*/power/wakeup

Формат имени устройства должен быть i2c-ELAN0679:00 или i2c-MSFT0001:00. Затем проверьте, получается ли перейти в ждущий режим после отключения wakeup:

# echo disabled > /sys/bus/i2c/devices/имя_устройства/power/wakeup
# systemctl suspend

Если сработало, можно сохранить это изменение в качестве правила udev:

/etc/udev/rules.d/99-avoid-i2c-wakeup.rules
KERNEL=="имя_устройства", SUBSYSTEM=="i2c", ATTR{power/wakeup}="disabled"

Система не выключается после перехода в спящий режим

При переходе в спящий режим система должна полностью выключиться (после сохранения состояния на диск). Если вы заметили, что светодиод питания продолжает светиться, попробуйте в файле sleep.conf.d(5) установить для HibernateMode значение shutdown:

/etc/systemd/sleep.conf.d/hibernatemode.conf
[Sleep]
HibernateMode=shutdown

Если всё остальное настроено правильно, после выполнения systemctl hibernate машина должна полностью выключиться, сохранив при этом своё состояние на диск.

Операционная система не найдена (или загружается не та ОС) при загрузке после спящего режима

Это может происходить, когда загрузочным диском является внешний диск, и, по-видимому, вызвано ограничением BIOS/прошивки. Прошивка пытается загрузиться с внутреннего диска, в то время как гибернация была выполнена из ОС на внешнем (или другом) диске.

Установите HibernateMode=shutdown, как показано в разделе #Система не выключается после перехода в спящий режим, чтобы окончательно решить проблему. Если система уже заблокировалась, можно попробовать перезагрузить её 4 раза (каждый раз дожидаясь появления ошибки), что в некоторых BIOS'ах приводит к нормальной загрузке.