发挥NVIDIA PRIME的全部功力:真·自动切换(四)
Tofloor
poster avatar
risez
deepin
2020-10-03 03:53
Author
本帖最后由 risez 于 2020-10-2 22:37 编辑

通用电源管理:只要使用PRIME方案即可生效,无需真自动切换功能
无论你的独显是否支持真自动切换功能,只要PRIME方案在你的机器上可以用就应该做本节要讲述的操作。如果不做,将导致电脑在挂起/休眠并恢复、或者挂起/休眠失败并紧急恢复之后PRIME失效,表现为:无法在nvidia-smi找到Xorg进程;无法调用独显跑应用程序;如果已经有应用程序在独显上跑,恢复后应用程序工作异常甚至崩溃。解决方法:重启Xorg,包括注销、杀死Xorg进程两种方法。

那种解决方法治标不治本,所以需要用到本节所提到的方法,而且使用该方法还可以更好地配合PRIME的自动切换功能进行电源管理。依次输入下面的命令:
  1. sudo systemctl enable nvidia-suspend.service
  2. sudo systemctl enable nvidia-hibernate.service
  3. sudo systemctl enable nvidia-resume.service
Copy the Code

没有这些服务?尝试:
  1. ls /usr/share/doc/NVIDIA_GLX-1.0/samples/systemd/
Copy the Code

如果有输出,执行下列命令:
  1. sudo install /usr/share/doc/NVIDIA_GLX-1.0/samples/systemd/nvidia-suspend.service /etc/systemd/system
  2. sudo install /usr/share/doc/NVIDIA_GLX-1.0/samples/systemd/nvidia-hibernate.service /etc/systemd/system
  3. sudo install /usr/share/doc/NVIDIA_GLX-1.0/samples/systemd/nvidia-resume.service /etc/systemd/system
  4. sudo install /usr/share/doc/NVIDIA_GLX-1.0/samples/systemd/nvidia /lib/systemd/system-sleep
  5. sudo install /usr/share/doc/NVIDIA_GLX-1.0/samples/systemd/nvidia-sleep.sh /usr/bin
Copy the Code

如果还没有,使用find命令查找服务文件是否存在:
  1. sudo find / -iname "服务文件名"
Copy the Code

还没有?来硬核的:
  1. cd /usr/lib/systemd/system/
  2. sudo nano nvidia-suspend.service
Copy the Code

添加以下内容:
  1. [Unit]
  2. Description=NVIDIA system suspend actions
  3. Before=systemd-suspend.service

  4. [Service]
  5. Type=oneshot
  6. ExecStart=/usr/bin/logger -t suspend -s "nvidia-suspend.service"
  7. ExecStart=/usr/bin/nvidia-sleep.sh "suspend"

  8. [Install]
  9. RequiredBy=systemd-suspend.service
Copy the Code

继续创建新文件nvidia-hibernate.service:
  1. [Unit]
  2. Description=NVIDIA system hibernate actions
  3. Before=systemd-hibernate.service

  4. [Service]
  5. Type=oneshot
  6. ExecStart=/usr/bin/logger -t hibernate -s "nvidia-hibernate.service"
  7. ExecStart=/usr/bin/nvidia-sleep.sh "hibernate"

  8. [Install]
  9. RequiredBy=systemd-hibernate.service
Copy the Code

再创建nvidia-resume.service:
  1. [Unit]
  2. Description=NVIDIA system resume actions
  3. After=systemd-suspend.service
  4. After=systemd-hibernate.service

  5. [Service]
  6. Type=oneshot
  7. ExecStart=/usr/bin/logger -t suspend -s "nvidia-resume.service"
  8. ExecStart=/usr/bin/nvidia-sleep.sh "resume"

  9. [Install]
  10. RequiredBy=systemd-suspend.service
  11. RequiredBy=systemd-hibernate.service
Copy the Code

再创建/usr/bin/nvidia-sleep.sh:
  1. #!/bin/bash

  2. if [ ! -f /proc/driver/nvidia/suspend ]; then
  3.     exit 0
  4. fi

  5. RUN_DIR="/var/run/nvidia-sleep"
  6. XORG_VT_FILE="${RUN_DIR}"/Xorg.vt_number

  7. PATH="/bin:/usr/bin"

  8. case "$1" in
  9.     suspend|hibernate)
  10.         mkdir -p "${RUN_DIR}"
  11.         fgconsole > "${XORG_VT_FILE}"
  12.         chvt 63
  13.         if [[ $? -ne 0 ]]; then
  14.             exit $?
  15.         fi
  16.         echo "$1" > /proc/driver/nvidia/suspend
  17.         exit $?
  18.         ;;
  19.     resume)
  20.         echo "$1" > /proc/driver/nvidia/suspend
  21.         #
  22.         # Check if Xorg was determined to be running at the time
  23.         # of suspend, and whether its VT was recorded.  If so,
  24.         # attempt to switch back to this VT.
  25.         #
  26.         if [[ -f "${XORG_VT_FILE}" ]]; then
  27.             XORG_PID=$(cat "${XORG_VT_FILE}")
  28.             rm "${XORG_VT_FILE}"
  29.             chvt "${XORG_PID}"
  30.         fi
  31.         exit 0
  32.         ;;
  33.     *)
  34.         exit 1
  35. esac
Copy the Code

最后创建/lib/systemd/system-sleep/nvidia:
  1. #!/bin/sh

  2. case "$1" in
  3.     post)
  4.         /usr/bin/nvidia-sleep.sh "resume"
  5.         ;;
  6. esac
Copy the Code

更改这些文件的权限:
  1. sudo chmod 644 nvidia-suspend.service
  2. sudo chmod 644 nvidia-hibernate.service
  3. sudo chmod 644 nvidia-resume.service
  4. sudo chmod 755 /usr/bin/nvidia-sleep.sh
  5. sudo chmod 755 /lib/systemd/system-sleep/nvidia
Copy the Code

编辑/etc/modprobe.d/nvidia.conf,追加如下内容:
  1. options nvidia "NVreg_PreserveVideoMemoryAllocations=1"
Copy the Code

检查你的挂起模式:
  1. cat /sys/power/mem_sleep
Copy the Code

如果输出:
  1. s2idle [deep]
Copy the Code

那就是设置好了,如果不是,且在之后的测试中电源管理不起效,则需要添加内核参数,以grub的添加方式为例,编辑/etc/default/grub,在GRUB_CMDLINE_LINUX_DEFAULT=后的参数中追加mem_sleep_default=deep,类似于下面这样,注意我的配置仅供参考,切勿直接复制粘贴:
  1. GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet nouveau.modeset=0 mem_sleep_default=deep"
Copy the Code

刷新grub:
  1. grub-mkconfig -o /boot/grub/grub.cfg #等价于update-grub
Copy the Code

重启你的电脑使配置生效。
注意:如果重启后卡在启动lightdm进程上,请自行想办法修改/lib/udev/rules.d/80-nvidia-pm.rules,注释除function 0外的其它设备的启用代码并删除设备。

本文所有部分链接:
一:https://bbs.deepin.org/post/203224#=1##pid786085
二:https://bbs.deepin.org/post/203225#=1##pid786087
三:https://bbs.deepin.org/post/203226#=1##pid786088
四:https://bbs.deepin.org/post/203227#=1##pid786089
五:https://bbs.deepin.org/post/203228#=1##pid786090
Reply Favorite View the author
All Replies

No replies yet