TL;DR: все идеально работает, но нужно прописать параметр и создать скрипт.
Шаг 1: Параметр драйвера
По умолчанию драйвер не сохраняет видеопамять, что приводит к ужасным артефактам при пробуждении, это можно исправить, указав параметр через GRUB в файле /etc/default/grub
:
GRUB_CMDLINE_LINUX_DEFAULT="nvidia.NVreg_PreserveVideoMemoryAllocations=1"
sudo grub-mkconfig -o /boot/grub/grub.cfg
grep PreserveVideoMemoryAllocations /proc/driver/nvidia/params
Если используется lilo или elilo вместо GRUB, то нужно добавить этот параметр в строчку append
для вашего ядра, вот пример:
image = /boot/vmlinuz-3.12-1-generic
label = "Linux"
read-only
initrd = /boot/initrd.img-3.12-1-generic
append="nvidia.NVreg_PreserveVideoMemoryAllocations=1"
Шаг 2: Настройка хука
NVidia предоставляет файл /usr/bin/nvidia-sleep.sh, который нужно правильно вызвать при входе и выходе из ждущего режима. Если используется elogind как в Slackware, то нужно создать файл /lib64/elogind/system-sleep/nvidia
:
#!/bin/sh
NVSLEEP="/usr/bin/nvidia-sleep.sh"
logger -t "elogind/system-sleep" -s "nvidia $1 $2"
case "$1" in
pre)
case "$2" in
suspend|hibernate)
"${NVSLEEP}" "$2"
;;
esac
;;
post)
case "$2" in
suspend|hibernate)
sleep 1
"${NVSLEEP}" resume &
;;
esac
;;
esac
Место где располагается файл nvidia-sleep.sh, может быть другим на очень старых версиях драйвера, лучше проверить и поправить переменную NVSLEEP в скрипте.
Шаг 3: Перезагрузка WM
После предыдущих шагов я видел только черный экран в XFCE4, но нельзя сдаваться. Я заметил, что это происходит только если включен композитинг, поэтому решения два, либо выключить композитинг, либо перезапустить WM после выходе из suspend, что всегда помогает. Приложения перезапускать не надо.
Для XFWM4, я просто дополнил скрипт (который приложил выше) такими вот строками:
#!/bin/sh
NVSLEEP="/usr/bin/nvidia-sleep.sh"
logger -t "elogind/system-sleep" -s "nvidia $1 $2"
case "$1" in
pre)
case "$2" in
suspend|hibernate)
"${NVSLEEP}" "$2"
;;
esac
;;
post)
case "$2" in
suspend|hibernate)
sleep 1
"${NVSLEEP}" resume &
;;
esac
user=ТУТ_ДОЛЖНО_БЫТЬ_ИМЯ_ПОЛЬЗОВАТЕЛЯ
PID=$(pgrep -u $user xfce4-panel)
DBUS=$(grep -z DBUS_SESSION_BUS_ADDRESS /proc/$PID/environ | tr '\0' '\n' | sed 's/DBUS_SESSION_BUS_ADDRESS=//')
export DBUS_SESSION_BUS_ADDRESS=$DBUS
# Убийство XFWM4
killall -9 xfwm4
# Запуск нового XFWM4
sudo -u $user DISPLAY=':0' DBUS_SESSION_BUS_ADDRESS=$DBUS /usr/bin/xfwm4 -r &
;;
esac