Сон и пробуждение
Питание и ACPI #acpi #linux #notebook #power #suspend
Сон и пробуждение
Ноутбук закрыли — он уснул. Открыли — вернулся рабочий стол. Обычно это работает незаметно, но иногда система не просыпается: экран застыл, клавиатура и мышь не отвечают. Эта статья — про то, какие бывают состояния сна, чем отличается s2idle от deep и как понять, что случилось, если ноутбук завис при пробуждении.
Состояния системы
ACPI описывает состояния питания всей системы, обозначая их буквой S. В документации ядра Linux они сопоставлены так:
| Состояние | Что происходит | В Linux |
|---|---|---|
| S0 | система работает | обычный режим |
| S1 | лёгкий сон, контекст сохраняется | standby (shallow) |
| S2 | в ACPI есть, на практике почти не используется | — |
| S3 | сон в оперативную память (Suspend-to-RAM) | mem с вариантом deep |
| S4 | гибернация: образ памяти на диск | disk |
| S5 | выключено, питание остаётся на кнопку | выключение |
В Linux интерфейс один — каталог /sys/power/:
cat /sys/power/state # freeze mem disk
cat /sys/power/mem_sleep # s2idle [deep]
state — какие состояния поддерживает ядро. mem_sleep — какой вариант используется для mem; текущий выделен квадратными скобками.
s2idle и deep
Это два разных способа «уснуть» под одним именем mem.
Suspend-to-Idle (s2idle) — чисто программный сон. Ядро замораживает пользовательские процессы, останавливает учёт времени, переводит устройства в состояния низкого потребления, а процессоры проводят время в самых глубоких idle-состояниях. Система формально остаётся в рабочем состоянии S0, поэтому проснуться может от любого прерывания. Этот вариант работает почти на любом железе.
Suspend-to-RAM (deep, S3) — настоящий сон: содержимое памяти сохраняется за счёт self-refresh, почти всё остальное питание отключается, а последний шаг делает прошивка. Энергии тратится существенно меньше, но и просыпается система дольше.
Что важно на практике:
- по умолчанию ядро выбирает
deepна большинстве систем, где S3 поддерживается, но на части ACPI-платформ —s2idle, даже если S3 есть; - выбор можно переопределить параметром ядра
mem_sleep_default=deep(илиs2idle); - включить/выключить прямо сейчас, без перезагрузки:
cat /sys/power/mem_sleep # s2idle [deep]
echo s2idle | sudo tee /sys/power/mem_sleep
На современных платформах Intel у s2idle есть «железная» основа — состояния низкого энергопотребления S0ix: процессорный пакет уходит в PKG C10, а хаб (PCH) — в SLP_S0. Ядро умеет показывать, сколько времени система провела в этих состояниях:
cat /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us
cat /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us
Если S0ix на конкретной машине работает плохо, s2idle может как расходовать батарею, так и зависать при пробуждении. Тогда разумная альтернатива — deep.
Кто инициирует сон
В обычной системе решение принимает systemd-logind. Его настройки — в /etc/systemd/logind.conf и logind.conf.d/:
HandleLidSwitch=— что делать при закрытии крышки; по умолчаниюsuspend;HandleLidSwitchExternalPower=— то же на внешнем питании; по умолчанию значение не задано и игнорируется (используетсяHandleLidSwitch);HandleLidSwitchDocked=— когда ноутбук в док-станции или подключено несколько мониторов; по умолчаниюignore;HandlePowerKey=,HandleSuspendKey=,HandleHibernateKey=— кнопки.
Само усыпление выполняет systemd-suspend.service: он пишет строку mem в /sys/power/state. Что именно писать — настраивается в /etc/systemd/sleep.conf (SuspendState=, а с systemd 256 — ещё и MemorySleepMode=).
Непосредственно перед сном и сразу после пробуждения systemd выполняет все программы из /usr/lib/systemd/system-sleep/, передавая им два аргумента: pre или post и тип операции (suspend, hibernate, …). Важная деталь: во время их работы user.slice заморожен, поэтому хуки не могут общаться с пользовательскими процессами. Сама документация systemd называет такие хуки «хаками» и советует приложениям использовать inhibitor-локи.
Inhibitors: кто запрещает спать
Программа может попросить не уходить в сон или не выключаться. Список держателей:
systemd-inhibit --list
Инхибиторы бывают двух видов: delay (подождать немного) и block (запретить). Типичный пример block — несохранённый документ в текстовом редакторе: GNOME не даёт выключить компьютер, пока вы не сохраните работу.
Как проверить, что сон действительно был
Самый надёжный след — сообщения ядра:
journalctl -b 0 -k | grep -E 'PM: suspend (entry|exit)'
Здоровая картина на машине с S3 выглядит так (наш замер, 8 ноября 2026):
16:43:31 PM: suspend entry (deep)
ACPI: PM: Preparing to enter system sleep state S3
...
16:48:51 PM: suspend exit
ACPI: PM: Low-level resume complete
После suspend exit в журнале должны появиться NetworkManager, fprintd (если включён вход по отпечатку), оболочка — всё это за секунды. Если журнал обрывается сразу после выхода из сна, система зависла.
Если ноутбук завис при пробуждении
По логам такое зависание выглядит как обрыв: последние строки — середина пробуждения, дальше ничего, а при следующей загрузке journald сообщает, что журнал не был корректно закрыт.
Что делать по шагам:
- Убедиться, что система вообще работала. Если после сбоя на диск не записалось ни одного файла, значит, система встала именно в этот момент (а не была выключена раньше):
find / -xdev -newermt '2026-11-06 15:10' ! -newermt '2026-11-08 15:47' -type f | head
- Посмотреть хвост журнала прошлой загрузки — он покажет, на каком шаге оборвалось:
journalctl -b -1 --no-pager | tail -40
journalctl -b -1 -k --no-pager | tail -40
- Проверить дамп паники, если он есть (нужен root):
sudo ls -la /sys/fs/pstore
-
Попробовать другой режим сна. Если стоит
s2idle, переключиться наdeepи понаблюдать несколько циклов. Если не помогло — следующий подозреваемый обычно графика: на Intel отключают Panel Self Refresh параметром ядраi915.enable_psr=0. -
Для отладки железа у ядра есть
/sys/power/pm_trace: при значении1метка последнего шага сна/пробуждения пишется в память RTC и переживает жёсткую перезагрузку. Это позволяет найти драйвер, на котором система встала.
Наш случай
6 ноября 2026 ноутбук (Dell Latitude 7400, UHD 620, Ubuntu 26.04) уснул 4 ноября и проснулся 6-го в 15:09:25. Через 0,4 секунды после PM: suspend exit журнал оборвался: система замерла на экране блокировки, пароль не вводился. На диск после этого не записалось ничего — ноутбук простоял так двое суток, пока его не выключили кнопкой.
Причина — зависание на выходе из s2idle. Лечение: переключение на deep параметром ядра mem_sleep_default=deep и обновление системы. Первое пробуждение на S3 прошло штатно: 5 минут сна, выход без ошибок. Точную подсистему, которая заклинила, по логам установить нельзя — в момент зависания перестают писаться и journald, и rsyslog.
Источники
- Ядро Linux, «System Sleep States»: https://docs.kernel.org/admin-guide/pm/sleep-states.html.
- Ядро Linux, «Low Power Idle Table (LPIT)» — про S0ix и счётчики резиденции: https://docs.kernel.org/firmware-guide/acpi/lpit.html.
- systemd,
systemd-sleep.conf(5): https://www.freedesktop.org/software/systemd/man/latest/systemd-sleep.conf.html. - systemd,
systemd-suspend.service(8)— хуки и заморозкаuser.slice: https://www.freedesktop.org/software/systemd/man/latest/systemd-suspend.service.html. - systemd,
logind.conf(5)—HandleLidSwitchи значения по умолчанию: https://www.freedesktop.org/software/systemd/man/latest/logind.conf.html. - Локальные измерения: Dell Latitude 7400, Ubuntu 26.04, ядро 7.0.0-43 (ноябрь 2026).
Комментарии
Пока комментариев нет.