关键词:NVIDIA, Arch Linux, suspend

最近好不容易迁移到了Wayland,但是小问题还是不少,其中一个关键问题就是从休眠(suspend)恢复后(此问题貌似与Wayland无关),gnome-shell中的文字和图标大多消失了,GUI只剩下骨架。

在网上搜索GNOME休眠后文字消失(google: gnome missing characters after suspend)相关问题,大多都是若干年前的讨论,经过测试,对于我的情况没有任何帮助(大多是和当初的Intel核显驱动或N卡开源驱动还有Linux内核有关)。当然最后还是找到了一定帮助的文章,才把问题定位到了NVIDIA闭源驱动上。

Fedora论坛找到了最近几个月关于此问题的讨论,才知道NVIDIA Suspend已经成为了一个标准问题。Arch Linux Wiki也有相关的解决方案,其中也指出了NVIDIA驱动的说明文档的链接(还好有NVIDIA官方解决方案)。推荐阅读一下官方提供的说明文档

Arch Wiki描述的过于简单,中间还是有一些坑的,既然坑我已经踩了,下面直接放上最终解决方案好了。

解决方案

Arch Linux上的nvidia包已经处理好systemd相关的事情,直接使用systemctl即可。其他发行版可能需要自行处理systemd添加相关service。

添加内核模块选项

这里假设你已经添加了nvidia内核模块。

新建 /etc/modprobe.d/nvidia-power-management.conf 添加 nvidia 内核模块选项

1
2
3
options nvidia NVreg_PreserveVideoMemoryAllocations=1
# (可选)更改显存临时存储位置,默认为 /tmp 。
# options nvidia NVreg_TemporaryFilePath=<TMP_PATH>

启用相关服务

1
2
3
sudo systemctl enable nvidia-suspend.service
sudo systemctl enable nvidia-hibernate.service
sudo systemctl enable nvidia-resume.service

重启后生效。

原理分析

休眠过程与计算机的电源管理方案有密切联系,一般计算机为了在休眠时提供更好的续航能力(默认情况下),会将一些设备关闭,其中包括显卡。本来显卡进入休眠状态也没有什么问题,但是独立显卡的显存却是和内存独立的,显存掉电数据会丢失。不过操作系统(驱动程序)肯定会考虑这些问题,在用户执行suspend命令时,还会执行一些准备程序(其中会保存一些必要的设备状态信息)才会进入休眠状态。当然,显卡的系列操作是驱动程序决定的。不过如上面nvidia驱动说明所述,默认状态驱动程序是很保守的,仅保存必要的显存数据(到内存或磁盘)。

这样的操作导致了显示数据的丢失,再次恢复后,由于应用程序(如gnome-shell)不知道数据的丢失(认为像字体之类的数据之前已经渲染过了,直接使用之前的显存状态,并没有重新渲染),导致了大量的UI元素丢失。

于是解决问题的方式也很简单,把所有显存都拷贝到持久的存储器,或者改变电源管理方案(这里没有写),不让显卡断电。

最后,只能说还是N卡驱动太坑了。

SO…. fuck you NVIDIA!