Power management (Português)/Suspend and hibernate (Português)

From ArchWiki
Status de tradução: Esse artigo é uma tradução de Power management/Suspend and hibernate. Data da última tradução: 2024-04-05. Você pode ajudar a sincronizar a tradução, se houver alterações na versão em inglês.

Existem múltiplos métodos de suspensão disponíveis, notavelmente:

Suspender para ocioso
Chamado de S0ix pela Intel, Modern Standby (antes como "Connected Standby") pela Microsoft e S2Idle pelo kernel. Projetado para ser usado ao invés do estado de sono S3 em sistemas com este suporte, de forma que fornece economia de energia idêntica, mas que reduz drasticamente o tempo exigido para acordar o sistema.
Dica: Enquanto o estado mencionado acima está sujeito a problemas com drenagem de bateria no Windows ou macOS, pelo fato que ambos os sistemas conseguem acordar dispositivos neste estado de sono para exercer atividade na rede, em contrapartida, o ecossistema de software no Linux atualmente não usa este recurso, e portanto deve permanecer inalterado.
Suspender para RAM (conhecido por suspensão padrão/normal, dormir)
Este estado de sono é definido pelo ACPI como S3. O funcionamento se baseia em cortar a energia da maior parte da máquina, exceto a RAM, da qual é necessária para restaurar o estado original. Por conta da grande economia de energia, é aconselhável que notebooks/laptops entrem automaticamente neste modo quando o computador estiver descarregando as baterias e com a tampa fechada (ou quando o usuário está inativo por um certo tempo).
Suspender para o disco (conhecido por hibernação)
O estado de sono S4, assim como foi definido pelo ACPI, salva o estado original da máquina dentro de um espaço swap e então desliga completamente a máquina. Quando a máquina volta a ligar, o estado é restaurado. Há zero consumo de energia até o momento que ocorra o retorno do sistema.
Suspensão híbrida (conhecido por sono híbrido)
É um híbrido entre suspender e hibernar, às vezes chamado de suspender para ambos. O sono híbrido salva o estado original em um espaço swap, porém não há desligamento da máquina, a suspensão invocada pelo sistema é a padrão. Se a bateria não estiver esgotada, o sistema pode retornar instantaneamente; se caso houver a perda de energia, o sistema pode retornar os dados pelo disco, que no caso é mais lento do que retornar pela RAM, mas o estado original da máquina não é perdido.

O kernel oferece funcionalidade básica, e há algumas interfaces de alto nível que proporcionam ajustes finos para lidar com drivers de hardware ou módulos de kernel problemáticos (por exemplo a reinicialização da placa de vídeo).

Interface do kernel (swsusp)

Nota: Apesar de ser possível usar a interface do kernel diretamente, do qual é mais rápida por não desempenhar nenhum manuseio extra do espaço de usuário, é aconselhável que se use uma interface de alto nível. Ao usar uma, é mais eficaz proporcionar verificações de segurança adicionais, como também os mecanismos de hook pré e pós suspensão para configurar apropriadamente o relógio de hardware, restaurar conexões sem fio, etc.

É possível informar diretamente o código interno de suspensão do software do kernel (swsusp), e com isso a máquina adentrar em um estado de suspensão; o método e estado exatos dependem do nível de suporte do hardware. Em kernels modernos, escrever apropriadamente strings para /sys/power/state é o mecanismo primário para acionar a devida suspensão.

Veja a documentação do kernel se quiser explorar os detalhes.

Interface de alto nível (systemd)

Nota: O objetivo de uma interface de alto nível é fornecer binários/scripts que podem ser chamados para efetuar suspensão/hibernação e formas de executar trabalho extra de preparação/limpeza nestes processos. Para automaticamente entrar em um estado de sono ao acionar botões de energia, ao clicar em menus, ou com eventos de abertura/fechamento de tampa em notebooks/laptops, explore mais sobre na página de Gestão de energia#Eventos ACPI.

systemd fornece comandos nativos para suspensão, hibernação e suspensão híbrida. Esta é a interface padrão usada em Arch Linux.

systemctl suspend já é configurado para funcionar automaticamente no sistema. Por outro lado, para systemctl hibernate funcionar você precisará seguir as instruções em #Hibernação.

Há também dois modos que integram-se com a suspensão e hibernação:

  • Suspensão híbrida: systemctl hybrid-sleep suspende o sistema com o uso de RAM e o uso de disco, portanto uma queda de energia não resulta em perda de dados. Esse modo também é chamado de suspender para ambos.
  • Suspender então hibernar: systemctl suspend-then-hibernate inicialmente suspende o sistema para RAM pelo tempo mais longo possível, então o sistema é acordado com um alarme RTC (relógio em tempo real) e hiberna. O alarme RTC é definido pelo HibernateDelaySec em systemd-sleep.conf(5). O valor padrão é programado de acordo com uma medida aproximada do descarregamento da bateria para manter o sistema com no mínimo 5% de bateria, ou com até 2 horas sem fonte de carga. A estimativa é obtida de acordo com a mudança de nível da bateria após um tempo especificado pelo SuspendEstimationSec no arquivo systemd-sleep.conf(5), para isso o sistema acordará brevemente e calculará uma estimativa (a medição também é feita se o sistema for acordado manualmente da suspensão).

Veja a seção #Hooks de sono para informações adicionais ao configurar os hooks de suspensão/hibernação. E também veja systemctl(1), systemd-sleep(8) e systemd.special(7) para detalhes.

Mudando método de suspensão

Em caso de sistemas que a suspensão S0ix não fornece a mesma economia de energia como o estado de sono S3 comum, ou quando a conservação de energia é preferida para um tempo de retorno rápido da suspensão, é possível alterar o método de suspensão padrão.

Tip: S0ix deveria supostamente fornecer economias de energia idênticas ou melhores do que o estado S3. Veja as postagens em inglês antigas do blog da Intel: Como alcançar os estados S0ix no Linux, Solução de problemas S0ix no Linux e Eficiência do modo ocioso no Linux: Um estudo de caso para verificar a possibilidade de fazer funcionar adequadamente. Usuários em sistemas sob uso de Intel podem usar S0ixSelftestTool.

Execute o seguinte comando para ver todos os métodos de suspensão que o hardware notifica ter suporte (o respectivo método é sinalizado dentro dos colchetes) [1]:

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

Se o seu hardware não notificar o status de sono deep, verifique primeiro se a sua UEFI possui alguma configuração de estados de sono; geralmente em "Power" ou "Sleep state", ou nomes semelhantes; pelas opções nomeadas como "Windows 10", "Windows and Linux" ou "S3/Modern standby support" para S0ix, e "Legacy", "Linux", "Linux S3" ou "S3 enabled" para estados de sono S3. Se ainda assim não houver correspondências, você pode manter o uso de s2idle. Considere usar hibernação ou tente corrigir as tabelas DSDT (ou procure uma versão com patch online).

Nota: A última solução acima pode causar problemas. Por conta que fabricantes pararam de corrigir bugs com o estado S3 do ACPI desde o momento que tais fabricantes regularizaram a escolha do sistema operacional Windows, e os mesmos são encorajados a usar "Modern standby" por padrão; se caso o sistema de fábrica foi propositalmente não informado, então provavelmente o hardware está de alguma forma com defeito.

Confirme que o hardware não exibe problemas com o estado de sono S3 ao testar alguns ciclos de sono com o método de sono alterado:

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

Se nenhum problema foi encontrado, então você pode fazer a mudança permanente com o parâmetro de kernel mem_sleep_default=deep.

Em contrapartida, firmwares danificados anunciam o suporte como sono deep, enquanto que apenas s2idle é suportado. Se este for o caso, um método alternativo ao usar s2idle está disponível através de SuspendState em sleep.conf.d(5):

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

Hibernação

Para usar a hibernação você deve criar uma partição ou arquivo swap, configurar o initramfs, desta forma o processo de retorno será inicializado pelo espaço de usuário, e por fim especificar a localização do espaço swap de acordo com a disponibilidade de opções do initramfs. Pode ser feito, por exemplo, com a variável EFI HibernateLocation definida pelo systemd ou pelo parâmetro de kernel resume. Estas três etapas estão detalhadas abaixo.

Nota:

Sobre tamanho de partição/arquivo swap

Mesmo que sua partição swap seja menor que a RAM, você ainda terá uma boa chance de hibernar de forma bem sucedida. Veja "image_size" na documentação do kernel para mais informações sobre este pseudo-arquivo image_size em sysfs(5).

Por um lado, você pode diminuir o valor de /sys/power/image_size, e desta forma a imagem de suspensão pode ser a menor possível (para pequenas partições de swap), ou por outro, você pode aumentar o valor e possivelmente acelerar o processo de hibernação. Para sistemas com uma grande quantidade de RAM, pequenos valores podem drasticamente aumentar a velocidade de volta da hibernação. É possível manter as alterações persistentes ao configurar por um arquivo temporário no systemd, como demonstrado em systemd#systemd-tmpfiles - arquivos temporários:

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

A imagem de suspensão não pode gerar múltiplas partições e/ou arquivos de swap, a mesma deve caber completamente em uma partição de swap ou em um único arquivo swap. [2]

Configure o initramfs

  • Quando um initramfs baseado em busybox é usado, cujo é o padrão, a definição do hook resume é um requisito, e o mesmo deve ser escrito em /etc/mkinitcpio.conf. Independente da partição swap ser chamada pelo label (rótulo de disco) ou pelo UUID, a partição usa o nó de dispositivo referenciado pelo udev, e portanto o hook resume deve ser colocado depois do hook udev. O exemplo a seguir foi feito a partir da configuração de hooks pré-definida:
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block filesystems resume fsck)
Lembre-se de gerar novamente o initramfs para as mudanças terem efeito.
Nota: Se o armazenamento usado para o espaço swap for em camadas (stacked), como em dispositivos criptografados, RAID ou LVM, o dispositivo mapeado, ou seja, na camada final, deve estar disponível no início do espaço de usuário e antes do processo de retorno ser inicializado. Sendo assim, nestes determinados setups o hook resume deve ser colocado logo após de hooks como encrypt, lvm2, etc.
  • Quando um initramfs com o hook systemd é usado o mecanismo de retorno já é proporcionado, em vista disso não é necessário adicionar outros hooks.

Definindo o local de hibernação para o initramfs

Quando o sistema hiberna a imagem da memória, e incluindo o estado dos sistema de arquivos montados, é direcionada para um espaço swap. A localização para hibernar, portanto, deve estar disponível a partir do initramfs, isto é, o local deve estar definido antes que o sistema de arquivos do root seja montado para que o sistema consiga retornar da hibernação adequadamente.

Desde a versão 255 do systemd e da versão 38 de mkinitcpio, quando o sistema está rodando em modo UEFI, systemd-sleep(8) irá automaticamente escolher um espaço swap apropriado para hibernar. A informação do espaço swap usado é armazenada na variável EFI HibernateLocation, e na próxima inicialização do sistema o systemd-hibernate-resume(8) faz a leitura da localização na variável EFI, realizando, então, o retorno do sistema. Significa que os passos abaixo só são necessários se o sistema estiver pelo modo legado (legacy), ou BIOS, ou se caso você quiser escolher um espaço swap diferente do que é automaticamente selecionado.

Especificando o local de hibernação manualmente

O parâmetro de kernel resume=dispositivo_swap pode ser usado quando o dispositivo_swap seguir a nomeação persistente de dispositivo de bloco. Por exemplo:

  • resume=UUID=4209c845-f495-4c43-8a03-5363dd433153
  • resume="PARTLABEL=Swap partition"
  • resume=/dev/archGrupoVolume/archVolumeLogico - usado se o swap estiver em um volume lógico LVM (configurar por UUID e Label devem funcionar da mesma forma).

Os parâmetros de kernel só irão ter efeito após reiniciar a máquina. Para hibernar de forma imediata obtenha os números maior e menor de volume do dispositivo pelo comando lsblk e ajuste (com echo) os valores de acordo com o mesmo formato maior:menor em /sys/power/resume.

Por exemplo, se o dispositivo swap for 8:3:

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

Se estiver usando um arquivo swap, adicionalmente siga os processos em #Adquirindo o offset de um arquivo swap.

Adquirindo o offset de um arquivo swap

Ao usar um arquivo swap para hibernação, o dispositivo em bloco do qual o sistema de arquivos está deve ser especificado em resume=, com a adição do offset físico do arquivo swap através do parâmetro de kernel resume_offset=. [3].

Em sistemas de arquivos que não são Btrfs, o valor de resume_offset= pode ser obtido executando filefrag -v arquivo_swap. A saída é por um formato em tabela e o determinado valor exigido está na primeira linha da coluna physical_offset.

Por exemplo:

# 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
...

Na demonstração acima o resume_offset= é o primeiro valor: 38912.

Alternativamente, para adquirir diretamente o valor do offset:

# filefrag -v arquivo_swap | awk '$1=="0:" {print substr($4, 1, length($4)-2)}'

Em sistemas de arquivos Btrfs, não tente usar a ferramenta filefrag, pois o offset "físico" obtido por filefrag não é o valor real do physical offset fornecido pelo disco. Ao invés disto existe um espaço de endereçamento virtual no disco, com o objetivo de dar suporte a múltiplos dispositivos [4]. Nesta situação use o comando btrfs-inspect-internal(8). Como por exemplo:

# btrfs inspect-internal map-swapfile -r arquivo_swap
198122980

Para aplicar a mudança de maneira imediata (sem reiniciar o sistema), use echo para definir o resume offset em /sys/power/resume_offset. Por exemplo, se o offset for 38912:

# echo 38912 > /sys/power/resume_offset
Dica: O comando a seguir poderá ser útil para identificar o dispositivo do qual retém o arquivo swap: findmnt -no UUID -T arquivo_swap
Nota: Em blocos de dispositivos stacked (em camadas), como no caso de um armazenamento criptografado (LUKS), em RAID ou em LVM, o parâmetro resume deve apontar para o dispositivo desbloqueado/mapeado que contém o sistema de arquivos com o arquivo swap.

Preservando arquivo swap para hibernação com zram

Dica: Ao invés do setup a seguir, que envolve múltiplos espaços swap, Zswap pode ser usado para estabelecer um comportamento similar.

É possível resolver o problema de hibernação com compressão em RAM (zram) ao gerenciar dois ou mais espaços swap ao mesmo tempo. systemd sempre irá ignorar dispositivos de bloco zram antes de acionar a hibernação, portanto manter os dois espaços ativados deve funcionar sem mais intervenções.

Depois de configurado o arquivo swap, siga a página do zram. Garanta que o zram tenha a maior prioridade de swap (por exemplo, pri=100).

Nota:

Hibernação em volume LVM de provisionamento fino

A hibernação dentro de um volume LVM de provisionamento fino é possível, mas é necessário ter certeza que o volume está totalmente alocado. Se caso não estiver, retornar o sistema por este volume falhará, veja em FS#50703.

Você pode alocar por completo o volume LVM ao simplesmente encher o mesmo com diversos zeros. Como por exemplo:

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

Para verificar se o volume está totalmente alocado use:

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

Um volume com a plena distribuição de armazenamento irá mostrar que possui o uso de dados (Data%) em 100%.

Atenção: Não use TRIM em volumes de provisionamento fino que são designados para hibernação, isto é, não use discard em /etc/fstab e não atribua a opção -d/--discard em swapon. Caso contrário o espaço usado será desalocado.

Hooks de sono

Units do systemd customizáveis

systemd inicia respectivamente suspend.target, hibernate.target, hybrid-sleep.target ou suspend-then-hibernate.target para cada estado de sono. Todos os targets mencionados são puxados pelo sleep.target e qualquer um dos targets pode ser usado para invocar units personalizadas antes ou depois da suspensão/hibernação. Arquivos separados devem ser criados para ações de usuários e ações de root/sistema. Exemplos:

/etc/systemd/system/suspend@.service
[Unit]
Description="Descrição de ações de suspensão do usuário"
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="Descrição de ações de retorno do usuário"
After=suspend.target

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

[Install]
WantedBy=suspend.target

Ative user-suspend@usuario.service e/ou user-resume@usuario.service para as mudanças terem efeito.

Nota: Como os bloqueadores de tela podem retornar antes da tela estar "bloqueada", a tela pode piscar ao retornar da suspensão. Adicionar um pequeno tempo de espera via ExecStartPost=/usr/bin/sleep 1 previne que isto ocorra.

Para ações de root/sistema:

/etc/systemd/system/root-suspend.service
[Unit]
Description="Ações de suspensão do sistema local"
Before=sleep.target

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

[Install]
WantedBy=sleep.target
/etc/systemd/system/root-resume.service
[Unit]
Description="Ações de retorno do sistema local"
After=suspend.target

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

[Install]
WantedBy=suspend.target

Unit de suspensão/retorno agregado

Com o arquivo unit que junta os estados um único hook faz todo o trabalho para diferentes fases (suspensão/retorno) e para diferentes targets.

Exemplo e explicação:

/etc/systemd/system/wicd-sleep.service
[Unit]
Description="Hook de sono Wicd"
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: Logo que iniciado o serviço é considerado ativo até que seja explicitamente pedido o encerramento. O termo significa "Continuar-Depois-de-Saída".
  • StopWhenUnneeded=yes: O serviço ativo será parado se nenhum outro serviço ativo necessitar dele. No exemplo acima em específico, o mesmo será finalizado depois que sleep.target parar. O termo significa "Parar-Quando-Desnecessário".
  • Por conta de sleep.target ser puxado pelos suspend.target, hibernate.target e hybrid-sleep.target, além do fato que o próprio sleep.target é um serviço StopWhenUnneeded, é garantido que o hook inicie/pare apropriadamente para diferentes tarefas.

Hooks em /usr/lib/systemd/system-sleep

Nota: Este método é considerado um hack do systemd de acordo com systemd-sleep(8). systemd-sleep irá sempre executar esses hooks simultaneamente ao invés de sequencialmente. Se quiser uma interface, que já foi claramente descrita, com suporte para ordenação de execução, veja a seção #Units do systemd customizáveis.

systemd-sleep inicia todos os executáveis em /usr/lib/systemd/system-sleep/, e passa dois argumentos para cada um deles:

  1. Tanto pre quanto post, dependendo se a máquina estará suspendendo (a dormir) ou retornando da suspensão (a acordar).
  2. suspend, hibernate ou hybrid-sleep, dependendo de qual está sendo invocado.

A saída de qualquer script personalizado terá o registro em log feito pelo systemd-suspend.service, systemd-hibernate.service ou systemd-hybrid-sleep.service. Você poderá ver a saída no próprio sistema de registro do systemd, em journalctl:

# journalctl -b -u systemd-suspend.service

Um exemplo de um script personalizado para o sono seria:

/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

Lembre-se de marcar o script como executável.

Dicas e truques

Desabilitando o sono completamente

Ao usar um dispositivo com a função de, por exemplo, ser um servidor, suspender pode não ser necessário ou até mesmo indesejável. Cada estado de sono pode ser desabilitado através do arquivo systemd-sleep.conf(5):

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

Tecnologia Intel Rapid Start (IRST)

A Tecnologia Intel Rapid Start é um método firmware de hibernação que permite hibernar a partir do sono e logo após um intervalo pré-definido ou de acordo com o estado de bateria. Este método pode ser mais rápido e mais confiável do que a hibernação regular, por conta de ser feito pelo firmware ao invés de ser feito a nível de sistema operacional. Geralmente é necessário habilitar pelo firmware e o mesmo precisa fornecer o suporte para configurar a duração após o evento de suspender/bateria acionar a hibernação. Entretanto em alguns dispositivos, apesar de terem o suporte IRST, o firmware por si só permite configurar pelos drivers Intel do Windows. Nestes casos o módulo de kernel intel-rst descrito abaixo deverá permitir configurar eventos pelo Linux.

Com a Tecnologia Intel Rapid Start (IRST) ativada, retornar da suspensão deep sleep demora cerca de "alguns segundos a mais do que retornar pelo estado S3, porém é muito mais rápido do que voltar através da hibernação".

Muitos sistemas com base na Intel possuem o suporte para IRST no firmware, todavia estes sistemas requerem uma partição especial ou um SSD (ao invés de um HDD). As implantações OEM do Windows podem já ter uma partição IRST pré-criada, da qual pode ser mantida durante o processo de instalação do Arch Linux (uma melhor opção ao contrário de limpar e reparticionar todo o SSD). A partição deve aparecer como não formatada e com tamanho igual a capacidade de RAM do sistema.

Atenção: A partição que pertence a Tecnologia Intel Rapid Start não é criptografada. "A Intel recomenda desabilitar a Tecnologia Intel Rapid Start se você está usando criptografia de disco baseada em software". [5]

Se você pretende limpar e reparticionar todo o armazenamento (ou se você já fez isso) e planeja usar a tecnologia, então a partição IRST precisa ser recriada; isto pode ser feito ao definir uma nova partição vazia com o mesmo tamanho da RAM e ao configurar o tipo de partição para GUID D3BFE2DE-3DAF-11DF-BA40-E3A556D89593 em caso de uma partição GPT, ou para ID 0x84 em caso de uma partição MBR. Há também a possibilidade de ser preciso ativar o suporte para IRST nas configurações de firmware do sistema.

Dica: O tempo de duração antes do IRST ter efeito (e que é depois da suspensão) pode ser ajustado nas configurações de firmware do sistema.

A duração do processo de hibernação IRST (ou seja, para copiar "todo o conteúdo da RAM para uma partição especial") depende da capacidade total de RAM no sistema e da velocidade do SSD, então o processo pode durar entre 20 a 60 segundos. Alguns sistemas podem indicar o processo concluído com uma indicação por LED, por exemplo a luz pode parar de piscar para indicar a conclusão.

Configurar os eventos de hibernação IRST no kernel Linux requer o CONFIG_INTEL_RST, que pode estar integrado ao kernel (built-in) ou deve estar por meio de módulo. Ao carregar via modprobe intel_rst, já é esperado que haja a criação por conta própria dos arquivos wakeup_events e wakeup_time dentro de /sys/bus/acpi/drivers/intel_rapid_start/*/, e demais configurações podem ser igualmente ajustadas neste mesmo local.

Este módulo foi documentado de maneira sucinta, veja a fonte do código drivers/platform/x86/intel/rst.c para mais detalhes. Veja também as perguntas frequentes e o guia de usuários para a Tecnologia Intel Rapid Start.

Solução de problemas

ACPI_OS_NAME

Você talvez precise aplicar ajustes finos na sua tabela DSDT para fazer funcionar adequadamente. Veja em DSDT.

Suspensão/hibernação não funcionam, ou não de forma consistente

Existem vários relatos sobre a imensa dificuldade de diagnosticar/visualizar erros quando a tela fica totalmente escura ou de fazer qualquer coisa quando o sistema retorna da suspensão e/ou hibernação; estes problemas foram vistos tanto em notebooks/laptops quanto em desktops. Não é uma solução oficial, mas trocar para um kernel mais antigo, especialmente para o kernel LTS, provavelmente restaura o funcionamento.

O problema pode surgir quando há o uso do temporizador watchdog pelo hardware (desabilitado por padrão, veja RuntimeWatchdogSec= em systemd-system.conf(5) § OPTIONS). Um temporizador bugado pode reiniciar o computador antes do sistema terminar de criar a imagem de hibernação.

Às vezes a tela pode ficar escura devido a inicialização do dispositivo a partir do initramfs. Remover qualquer módulo que talvez esteja em Mkinitcpio#MODULES, remover o hook kms e reconstruir o initramfs possivelmente soluciona o problema, em especial com drivers gráficos que iniciam com o KMS. Inicializar tais dispositivos antes do sistema retornar pode causar inconsistências que previnem o sistema de voltar da hibernação; isto, no entanto, não afeta a volta pela RAM. Além do que foi mencionado aqui, dê uma olhada no artigo do blog a seguir: As melhores práticas para depurar problemas de suspensão.

Mover o driver de vídeo ATI para o novo driver AMDGPU pode também ajudar a solucionar transtornos com o processo do sistema ao hibernar ou ao acordar, e com isso o processo ser bem sucedido.

Para usuários de NVIDIA, adicionar à lista negra o módulo nvidiafb talvez ajude. [6]

Notebooks/laptops com uma CPU Intel e que carregam o módulo intel_lpss_pci para touchpad podem se deparar com pânicos de kernel ao retornar o sistema (tecla Caps Lock pisca incessantemente) [7]. O módulo precisa ser adicionado ao initramfs desta forma:

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

E então gere novamente o initramfs.

Wake-on-LAN

Se o Wake-on-LAN está ativo, a interface da placa de rede irá consumir energia mesmo se o computador estiver em hibernação.

Sistema acorda instantaneamente da suspensão

Veja a página em inglês: Wakeup triggers#Instantaneous wakeups from suspend.

Se você estiver usando a versão 6.1, ou acima, do kernel Linux com uma CPU da AMD, há chance de ocorrer mal funcionamento por conta de problemas com o controle de protocolo relacionado ao estado de sono S3 no kernel. Uma solução temporária seria desligar o retorno (wakeup) de dispositivos que estejam envolvidos com o i2c. Você pode encontrá-los por:

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

O formato de nome dos dispositivos será algo como i2c-ELAN0679:00 ou i2c-MSFT0001:00. Por fim, ajuste para desabilitar e teste se o comando abaixo resulta na suspensão do sistema apropriadamente:

# echo disabled > /sys/bus/i2c/devices/nome_dispositivo/power/wakeup
# systemctl suspend

Se funcionar, você pode fazer a configuração persistente ao adicioná-la a uma regra udev:

/etc/udev/rules.d/99-avoid-i2c-wakeup.rules
KERNEL=="nome_dispositivo", SUBSYSTEM=="i2c", ATTR{power/wakeup}="disabled"

Sistema não desliga quando em hibernação

Ao hibernar o seu sistema, ele precisa desligar (logo depois de salvo o estado da máquina para o disco). Em certas ocasiões talvez você perceba o LED do botão power ainda acesso; se isto ocorrer, é instruído que você defina o HibernateMode para shutdown em sleep.conf.d(5):

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

A configuração acima, e se demais configurações estiverem corretas, fará com que a invocação por systemctl hibernate desligue a máquina adequadamente, incluindo o salvamento do estado original para o disco antes de desligar.

Sistema operacional não encontrado (ou iniciando errado) ao dar boot depois da hibernação

Isto pode ocorrer quando o disco de iniciação (de boot) é um disco externo; a situação é aparentemente causada por uma limitação própria da BIOS ou do próprio firmware. A BIOS ou o firmware tenta iniciar o sistema por um disco interno, contudo a hibernação foi feita por um sistema operacional em um disco externo (ou em outro dispositivo).

Defina HibernateMode=shutdown como mostrado em #Sistema não desliga quando em hibernação para resolver o problema permanentemente. Se você já deslogou do seu sistema, você pode tentar reiniciar o sistema 4 vezes (espere até a mensagem de erro aparecer em cada uma das vezes), em algumas BIOS isto força um processo de boot normal, ou seja, logo em seguida de várias tentativas falhas o sistema volta para o estado padrão de boot.

Arquivo swap em /home

Se o arquivo swap estiver em /home/, systemd-logind não conseguirá acessá-lo; será retornada uma mensagem com o aviso Call to Hibernate failed: No such file or directory, ou de forma traduzida: Chamada para Hibernação falhou: Não há arquivo ou diretório, e isto requer que o comando systemctl hibernate seja executado com autenticação. Este tipo de configuração precisa ser evitada, pois não há suporte no upstream. Veja a issue do systemd 15354 para conhecer duas formas de contornar a situação.

Computador não acorda do sono em placas-mãe A520I e B550I

Em placas-mãe com chipsets A520i e B550i, o sistema não irá adentrar completamente no estado de sono ou sequer retornar. Sintomas incluem o sistema entrar no sono e o monitor desligar enquanto LEDs internos da placa-mãe ou LED do botão power continuam acessos. Consequentemente o sistema não irá conseguir trocar de estado e requer desligamento forçado. Se você estiver com um problema similar na AMD, primeiro tenha certeza que seu sistema está totalmente atualizado e verifique se o pacote microcode da AMD está instalado.

Verifique se a linha que começa com GPP0 possui o status ativo (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

Se estiver ativado, você pode executar o comando abaixo para desativar:

# echo GPP0 > /proc/acpi/wakeup

Agora teste com systemctl suspend e deixe o sistema dormir. Depois de alguns segundos acorde o sistema. Se funcionou, você pode deixar o ajuste permanente ao criar um arquivo unit do systemd:

/etc/systemd/system/aciona-gpp0-para-corrigir-retorno.service
[Unit]
Description="Desabilita GPP0 para resolver problema de suspensão"

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

[Install]
WantedBy=multi-user.target

Recarregue o sistema pelo daemon-reload e inicie/habilite a unit recém criada.

Alternativamente, você pode criar uma regra udev. Supondo que node em sysfs de GPP0 é pci:0000:00:01.1, como é neste exemplo, execute udevadm info -a -p /sys/bus/pci/devices/0000\:00\:01.1 para que exiba-se as informações relevantes, e então crie uma regra udev como esta:

/etc/udev/rules.d/10-gpp0-acpi-fix.rules
KERNEL=="0000:00:01.1", SUBSYSTEM=="pci", DRIVERS=="pcieport", ATTR{vendor}=="0x1022", ATTR{device}=="0x1483", ATTR{power/wakeup}="disabled"

O daemon do udev já estará monitorando as mudanças no seu sistema por padrão. Se necessário, você poderá recarregar as regras manualmente.

Suspender a partir da tecla Fn correspondente em notebooks/laptops não funciona

Se apesar de configurado não funcionar o botão para acionar o evento de sono em logind.conf, e nem mesmo ao pressionar é emitido mensagens em syslog, então provavelmente logind não está monitorando o teclado [8]. Para resolver use:

# journalctl --grep="Watching system buttons"

Você provavelmente verá algo parecido com:

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)

Note que não há nenhum dispositivo de teclado sendo monitorado. Liste os dispositivos de teclado com:

 # stat -c%N /dev/input/by-id/*-kbd
...
/dev/input/by-id/usb-SIGMACHIP_USB_Keyboard-event-kbd -> ../event6
...

Agora obtenha o ATTRS{name}, parte do dispositivo pai do teclado [9]. Como um exemplo, na listagem acima o dispositivo está com o evento da entrada como /event6, o mesmo pode ser usado para buscar o nome do respectivo atributo:

# udevadm info -a /dev/input/event6
...
KERNEL=="event6"
...
ATTRS{name}=="SIGMACHIP USB Keyboard"

Escreva uma regra personalizada para adicionar a tag "power-switch":

/etc/udev/rules.d/70-power-switch-my.rules
ACTION=="remove", GOTO="power_switch_my_end"
SUBSYSTEM=="input", KERNEL=="event*", ATTRS{name}=="SIGMACHIP USB Keyboard", TAG+="power-switch"
LABEL="power_switch_my_end"

Depois de recarregar as regras udev e reiniciar systemd-logind.service, você agora deverá ver o registro do evento sendo monitorado: Watching system buttons on /dev/input/event6, pelo journal do logind.