[CUDA]サスペンドできない場合の対処
これは何か
NVIDIAプロプライエタリドライバーとCUDAライブラリーをインストールした特定条件下において、サスペンドに失敗してしまいます。うちの環境ではばっちり再現性があり困っていました。
使用環境によりサスペンドは不要という場合がほとんどだと思いますが、私の環境では必須です。
調べていくと危険な沼[1]になっていることがわかりました。また.local/share/xorg/Xorg.0.log
などいろいろなものをじっくり読む資質が自分にはありません。
そこでここでは細部の正確性を無視して、回避策を提案します。
現象
- 遭遇した現象
- システムトレイからサスペンドを選択→サスペンドに失敗したあと勝手にログアウトする
-
sudo systemctl suspend
→サスペンドに失敗したあと勝手にログアウトする
- 他の事例では
- 起動に失敗する
- ログイン画面がループする
背景
NVIDIAによる説明(バージョン510)の適当な意訳
- サスペンドの結果、ビデオメモリコンテンツが損失する可能性がある
- これはレンダリングの破損やアプリケーションのクラッシュなどを引き起こす
- だからデフォルト状態ではサスペンドさせないようにしている
- NVIDIAとしてはsystemdとの統合を試みている
- しかしながらまだ実験的
- 意図的にシステムをいじって実験的機能を使うことができる[2]
-
nvidia-sleep.sh
を配置するとか。 - カーネルをいじってしまうとか。
-
- 最終的に
sudo systemctl suspend
がうまく動けばラッキー - 結局組み合わせるシステム次第
補足
NVIDIAのドキュメントはドライバーのバージョンごとにこちらのページにまとめられています。
Index of /XFree86/Linux-x86_64
とはいえ、バージョンをまたいで同じ問題が同じ文章で載っていたりします。
多くが既知の問題として認識されていますが、NVIDIA単体ではどうにもできない苦慮がみてとれます。
私個人としてはシステムをいじくり回すよりも、簡単な回避策があるならそちらが良いです。
結論
-
nvidia-powerd.service
がfailするのは意図的。 -
解決する方法は、一応ある(意図する内容を理解しなおかつ実行しようとする人対象)
-
私のような人は**
pm-utils
のpm-suspend
を使ったほうがお手軽**$ sudo apt install -y pm-utils $ sudo pm-suspend
現在の環境
ここからは考えたことや実行したことをダラダラと書いています。
- Linux 5.13.0-39-generic #44~20.04.1-Ubuntu SMP Thu Mar 24 16:43:35 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
- 08:00.0 VGA compatible controller: NVIDIA Corporation TU116 [GeForce GTX 1660 Ti] (rev a1)
- AMD Ryzen 5 1400 Quad-Core Processor
- nvidia-smi
前提
-
UEFIの設定に不正な値がないこと(重要)
-
ubuntu-drivers autoinstall
を使用していること(重要。ディストリビューションが用意したパッケージを使うという意味です)wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600 apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /" apt update && apt upgrade -y ubuntu-drivers devices ubuntu-drivers autoinstall apt install -y cuda
主なエラー
# 前半
kernel: nvidia-gpu 0000:08:00.3: i2c timeout error e0000000
kernel: ucsi_ccg 3-0008: i2c_transfer failed -110
kernel: ucsi_ccg 3-0008: ucsi_ccg_init failed - -110
# 後半
kernel: /usr/bin/nvidia-powerd[1228]: No matching GPU found
kernel: /usr/bin/nvidia-powerd[1228]: Failed to initialize RM Client
systemd[1]: Failed to start nvidia-powerd service.
systemd[1866]: Failed to start GNOME Power management handling.
systemd[1866]: Faikernel: [drm:nv_drm_master_set [nvidia_drm]] *ERROR* [nvidia-drm] [GPU ID 0x00000800] Failed to grab modeset ownership
State: degraded
となっていたりもします。
$ systemctl status
● user-comp
State: degraded
Jobs: 0 queued
Failed: 1 units
Since: Sat 2022-04-02 09:23:46 JST; 7h ago
CGroup: /
├─368 bpfilter_umh
├─user.slice
│ ├─user-125.slice
│ │ ├─session-c2.scope
これらのエラーは気にしなければ放っておいても大丈夫です。
復帰が異様に遅かったり黒い画面のままなら対策したほうがいいかも、くらいに捉えてください。
エラーを消したい場合
スパムログから解放されたい場合、モジュールをブラックリストに入れたりサービスユニットをdisableにしたりします。これによる副作用を考慮して行ってください。[3]
前半
のエラー
kernel: nvidia-gpu 0000:08:00.3: i2c timeout error e0000000
kernel: ucsi_ccg 3-0008: i2c_transfer failed -110
kernel: ucsi_ccg 3-0008: ucsi_ccg_init failed - -110
「Type-CのUSB端子がないんだけれどどうなってるの?」という意味かと思いますがMSI GeForce GTX 1660 Ti AERO ITX 6G OC
には元々USB端子がありません。その分お買い得。
補足
Kernel driver i2c-nvidia-gpu
とは。
i2c-nvidia-gpuは、NVIDIA Turing以降のGPUに含まれるI2Cコントローラーのドライバーであり、GPU上のType-Cコントローラーとの通信に使用されます。
i2cカーネルモジュールの表示
$ modprobe -c | grep nvidia
blacklist nvidiafb
alias mbp_nvidia_bl apple_bl
alias pci:v000010DEd*sv*sd*bc03sc*i* nvidiafb
alias pci:v000010DEd*sv*sd*bc0Csc80i* i2c_nvidia_gpu ←これ。
alias typec:id0955m* typec_nvidia
[4]そもそもこのblacklistをどうにかしないといけないのかもしれません。
i2cの依存関係を表示
怖いので依存関係などを覗いています。
$ modprobe -D i2c_nvidia_gpu
insmod /lib/modules/5.13.0-37-generic/kernel/drivers/i2c/busses/i2c-nvidia-gpu.ko
ucsi_ccgカーネルモジュールの表示
$ modprobe -c | grep ucsi
alias acpi*:PNP0CA0:* ucsi_acpi
alias i2c:ccgx_ucsi ucsi_ccg ←これ。
alias symbol:ucsi_connector_change typec_ucsi
alias symbol:ucsi_create typec_ucsi
alias symbol:ucsi_destroy typec_ucsi
alias symbol:ucsi_get_drvdata typec_ucsi
alias symbol:ucsi_register typec_ucsi
alias symbol:ucsi_resume typec_ucsi
alias symbol:ucsi_send_command typec_ucsi
alias symbol:ucsi_set_drvdata typec_ucsi
alias symbol:ucsi_unregister typec_ucsi
ucsi_ccgの依存関係を表示
$ modprobe -D ucsi_ccg
insmod /lib/modules/5.13.0-37-generic/kernel/drivers/usb/typec/typec.ko
insmod /lib/modules/5.13.0-37-generic/kernel/drivers/usb/typec/ucsi/typec_ucsi.ko
insmod /lib/modules/5.13.0-37-generic/kernel/drivers/usb/typec/ucsi/ucsi_ccg.ko
lspci -v
のNvidiaの部分を抜粋
# VGAコントローラー
08:00.0 VGA compatible controller: NVIDIA Corporation TU116 [GeForce GTX 1660 Ti] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Micro-Star International Co., Ltd. [MSI] TU116 [GeForce GTX 1660 Ti]
Flags: bus master, fast devsel, latency 0, IRQ 72
Memory at f5000000 (32-bit, non-prefetchable) [size=16M]
Memory at e0000000 (64-bit, prefetchable) [size=256M]
Memory at f0000000 (64-bit, prefetchable) [size=32M]
I/O ports at e000 [size=128]
Expansion ROM at f6000000 [disabled] [size=512K]
Capabilities: <access denied>
Kernel driver in use: nouveau
Kernel modules: nvidiafb, nouveau
# Audioコントローラー
08:00.1 Audio device: NVIDIA Corporation TU116 High Definition Audio Controller (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] TU116 High Definition Audio Controller
Flags: bus master, fast devsel, latency 0, IRQ 70
Memory at f6080000 (32-bit, non-prefetchable) [size=16K]
Capabilities: <access denied>
Kernel driver in use: snd_hda_intel
Kernel modules: snd_hda_intel
# USB 3.1コントローラー ←これではないらしい
08:00.2 USB controller: NVIDIA Corporation TU116 USB 3.1 Host Controller (rev a1) (prog-if 30 [XHCI])
Subsystem: Micro-Star International Co., Ltd. [MSI] Device 8d90
Flags: fast devsel, IRQ 64
Memory at f2000000 (64-bit, prefetchable) [size=256K]
Memory at f2040000 (64-bit, prefetchable) [size=64K]
Capabilities: <access denied>
Kernel driver in use: xhci_hcd
Kernel modules: xhci_pci
# シリアルバスコントローラー ←これらしい
08:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU116 [GeForce GTX 1650 SUPER] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] TU116 [GeForce GTX 1650 SUPER]
Flags: bus master, fast devsel, latency 0, IRQ 42
Memory at f6084000 (32-bit, non-prefetchable) [size=4K]
Capabilities: <access denied>
Kernel driver in use: nvidia-gpu
Kernel modules: i2c_nvidia_gpu
ucsi
ってなに?
CONFIG_UCSI: USB Type-C Connector System Software Interface driver
USB Type-C Connector System Software Interface (UCSI)
specification for an interface that allows the Operating System to control the USB Type-C ports on a system.
Things the need controlling include the USB Data Role (host or device), and when USB Power Delivery is supported, the Power Role (source or sink).
(USBType-Cポートを制御できるようにするインターフェイスの仕様。データ送受信やUSB給電がサポートされてる場合は給電も制御します。<意訳>)
i2c_nvidia_gpu ucsi_ccg らをブラックリストに入れる
touch /etc/modprobe.d/blacklist-i2c-nvidia-gpu.conf
cat 'blacklist i2c_nvidia_gpu' > /etc/modprobe.d/blacklist-i2c-nvidia-gpu.conf
touch /etc/modprobe.d/blacklist-ucsi_ccg.conf
cat 'blacklist ucsi_ccg' > /etc/modprobe.d/blacklist-ucsi_ccg.conf
update-initramfs -u
再起動後ログをチェック。
$ journalctl -ab -p err
-- Logs begin at Fri 2022-03-25 12:25:45 JST, end at Fri 2022-04-01 23:09:06 JST. --
4月 01 23:08:48 user-comp gdm-password][1813]: gkr-pam: unable to locate daemon control file
ナイス。
後半
のエラー
nvidia-powerd.service
が起動していません。
$ systemctl status
● user-comp
State: degraded
Jobs: 0 queued
Failed: 1 units
Since: Sat 2022-04-02 09:23:46 JST; 7h ago
CGroup: /
├─368 bpfilter_umh
├─user.slice
│ ├─user-125.slice
│ │ ├─session-c2.scope
│ │ │ ├─10923 gdm-session-worker [pam/gdm-launch-environment]
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
● nvidia-powerd.service loaded failed failed nvidia-powerd service
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
1 loaded units listed.
nvidia-powerd.service
の中身を確認します。
WantedBy=multi-user.target
であることがわかります。
これってもしかしてgraphical.target
って書いてないといけないのでしょうか??
う〜ん、よくわからないしいじりたくないなぁ…。
$ systemctl show nvidia-powerd
Type=dbus
Restart=no
NotifyAccess=none
RestartUSec=100ms
...
ここにあるようにRestart=no
には意図的な意味があるのかもしれません。[5]
$ /lib/systemd/system cat ./nvidia-powerd.service
[Unit]
Description=nvidia-powerd service
[Service]
Type=dbus
BusName=nvidia.powerd.server
ExecStart=/usr/bin/nvidia-powerd
[Install]
WantedBy=multi-user.target
$ /lib/systemd/system cat ./multi-user.target
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the user of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
なぜ起動しないかは以下を確認するとわかります。
$ cat /proc/driver/nvidia/gpus/0000\:08\:00.0/power
Runtime D3 status: Not supported
Video Memory: Active
GPU Hardware Support:
Video Memory Self Refresh: Supported
Video Memory Off: Supported
Power Limits:
Default: N/A milliwatts
GPU Boost: N/A milliwatts
仕様
In addition to that, if the PCI PM Spec is implemented by the device, it must support D3hot as well as D0.
https://docs.kernel.org/power/pci.html
少なくとも電源管理したいのならばデバイス側で実装してね、ということかと思います。
Runtime D3 status: Not supported
先に書きましたが、NVIDIA的には意図を理解した上で実行してね、ということなんでしょう。
補足
PCI電源管理仕様
デバイスならD0-D3 (値が大きいほど電力使用量は小さい)(バスならB0-B3)
ACPI
S0 通常の稼働状態
S1 省電力モード (プロセッサー、チップセットは共に電源オン)
S2 省電力モード (プロセッサーは電源オフ、チップセットは電源オン)
S3 スタンバイ状態
S4 休止状態
S5 ソフトウェアによる電源オフ
systemctl disable nvidia-powerd.service
サービスをdisableします。
$ /lib/systemd/system sudo systemctl disable nvidia-powerd.service
[sudo] user のパスワード:
Removed /etc/systemd/system/multi-user.target.wants/nvidia-powerd.service.
$ /lib/systemd/system sudo reboot
再起動後ログ等のチェック。
$ journalctl -b -a -p err
-- Logs begin at Fri 2022-03-25 12:25:45 JST, end at Sat 2022-04-02 17:19:01 JST. --
4月 02 17:17:52 user-comp kernel:
4月 02 17:18:06 user-comp gdm-password][1849]: gkr-pam: unable to locate daemon control file
● user-comp
State: running
Jobs: 0 queued
Failed: 0 units
Since: Sat 2022-04-02 17:17:51 JST; 1min 52s ago
CGroup: /
├─368 bpfilter_umh
├─user.slice
│ ├─user-125.slice
$ systemctl --failed
UNIT LOAD ACTIVE SUB DESCRIPTION
0 loaded units listed.
ナイス。
pm-utils
最初に書いた回避策です。
sudo apt install -y pm-utils
sudo pm-suspend
特に不具合なく動作しています。
あとがき
NVIDIAドライバーやライブラリについてのクレーム?ですが、510は駄目だけど470ならトラブルが少ない、いや470でも全然駄目だとか、MATEだと解決法があるよ、とかかなりの量があります。起動しないパターンだと阿鼻叫喚になるのもわかります。
さてNVIDIAのドライバーダウンロードサイトに以下のように載っていました。
Updated nvidia-bug-report.sh to search the systemd journal for nvidia-powerd logs.
パッケージマネージャからのインストールですが確かに/usr/bin/nvidia-bug-report.sh
は存在します。掘り下げてみたい方はこれを使うと良いことが起こるかもしれません。
同じサイトのAdditional informationには
One of the last installation steps will offer to update your X configuration file. Either accept that offer, edit your X configuration file manually so that the NVIDIA X driver will be used, or run nvidia-xconfig (Xコンフィグファイルを手作業でいじくるか、nvidia-xconfigを実行するか選べ。)
と記載があります。確かに実行ファイルが存在しました。
$ which nvidia-xconfig
/usr/bin/nvidia-xconfig
このファイルってディストリビューションのパッケージマネージャでドライバーをインストールした人は関係ないかと思っているのですが、理解が違っているかもしれません。
こういうのは専門の人をたてて任せてしまうのが一番ですけど、そうできない環境だから辛いなぁ。
追記
2022年4月3日
journalctl -ab -p err
-- Logs begin at Fri 2022-03-25 12:25:45 JST, end at Sun 2022-04-03 17:51:21 JST. --
4月 03 15:42:33 user kernel: [drm:nv_drm_master_set [nvidia_drm]] *ERROR* [nvidia-drm] [GPU ID 0x00000800] Failed to grab modeset ownership
上記エラーが発生しました。これについてNVIDIAから「無視して大丈夫」と書かれています。
HI All,
The warning message is expected. When a client (such as the modesetting driver) attempts to open our DRM device node while modesetting permission is already acquired by something else (like the NVIDIA X driver), it has to fail, but the kernel won’t let us return a failure after v5.9-rc1, so we print this message. It won’t impact functionality of the NVIDIA X driver that already has modesetting permission. Safe to ignore as long as long as you didn’t need the other client to actually get modesetting permission. If you want to suppress the error, you would need to find which client is attempting to open the NVIDIA DRM device node and prevent it from doing so.
https://forums.developer.nvidia.com/t/ubuntu-21-10-failed-to-grab-modeset-ownership-with-495-44/193867/37
-
Device Power Management BasicsCPUだけ考えてもこれを自分が理解するのは難しい ↩︎
-
ノートPCに限った話かもしれません ↩︎
-
Fedraの記事ですがこんなことも書いてあります。
Driver 510+ requires nvidia-powerd for dynamic GPU frequency boost and other advanced performance-improving features.
It's going to make a big improvement in game framerates.
Don't uninstall it. Don't disable the service either. You need nvidia-powerd (xorg-x11-drv-nvidia-power).
If it causes any issues with suspend on your system (as I've heard from 1 or 2 people), then simply disable suspend on your system in GNOME Settings: Power: Automatic Suspend: Off.
Then wait for a fixed driver which doesn't have suspend-issues.
https://www.reddit.com/r/Fedora/comments/sy52ov/i_think_nvidia_driver_isnt_installed_properly_on/hxxe6w0/
I also don't agree with your final advice whatsoever, because disabling the service could be harmful (read on below).
https://www.reddit.com/r/Fedora/comments/sy52ov/i_think_nvidia_driver_isnt_installed_properly_on/hxzs1n5/ ↩︎ -
いつの間にか
SysV init
からsystemd
になった…という感覚の人間なのでこの機会にsystemdについて色々と読んでみました。長いなぁ…。 ↩︎ -
Maybe there isn't a better way to do it though. Systemd has a lot of startup features, but I don't think "probe the physical hardware features and only start the service if found" is one of them. I've written a few service files and don't think I've ever seen such a feature.
Here's how NVIDIA decided to achieve the "only start on hardware that needs it" ↩︎
Discussion