How to solve the problem of OpenSUSE not recognizing GPU after kernel update
はじめに
OpenSUSE TumbleWeedでカーネルをアップデートした際に、nvidia-smiが認識しない問題が発生しました。
グラボにHDMIを挿して、テキストベースでは起動しました。要は「ハードウェアとしては機能はしているが、NVIDIAドライバのソフトウェア層での認識や制御ができていない」ということです。
一度nvidiaのドライバーを再インストールしてみましたが、結果は同じでした。
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
環境
・OpenSUSE TumbleWeed(Linux kernel 6.12.8)
・Geforce GTX 670(NVIDIA 470.256.02)
やってみたこと
NVIDIA 470.256.02ドライバのソースコードがあるディレクトリでsudo make
を実行
cd /usr/src/kernel-modules/nvidia-470.256.02-default/
sudo make
以下のエラーがみられました。
/usr/src/kernel-modules/nvidia-470.256.02-default/nvidia-drm/nvidia-drm-drv.c:171:6: error: 'const struct drm_mode_config_funcs' has no member named 'output_poll_changed'
171 | .output_poll_changed = nv_drm_output_poll_changed,
| ^~~~~~~~~~~~~~~~~~~
/usr/src/kernel-modules/nvidia-470.256.02-default/nvidia-drm/nvidia-drm-drv.c:171:28: error: initialization of 'struct drm_atomic_state *(*)(struct drm_device *)' from incompatible pointer type 'void (*)(struct drm_device *)' [-Wincompatible-pointer-types]
171 | .output_poll_changed = nv_drm_output_poll_changed,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
エラー内容的に、Linux kernel 6.12でDRMドライバの仕様が変更され、drm_mode_config_funcs
構造体からoutput_poll_changed
メンバ構造体が削除されたことによって発生したとのことでした。
NVIDIA 470.256.02ドライバは古いカーネルの仕様に基づいて書かれているため、新しいカーネルではコンパイルできなくなったみたいです。
解決方法
/usr/src/kernel-modules/nvidia-470.256.02-default/nvidia-drm/nvidia-drm-drv.c
のエラーが出ている箇所(171行目)を修正を行っていきます。
※単純に171行目をコメントアウトするだけでも動くようにはなるとは思いますが、一応記事として書いているので()
まず、ファイル先頭に以下を追加します。
#include <linux/version.h>
問題コード部分を以下のように修正します。
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,12,0)
.output_poll_changed = nv_drm_output_poll_changed,
#endif
関数定義も同様に条件付きに修正します。
#if LINUX_VERSION_CODE < KERNEL_VERSION(6,12,0)
static void nv_drm_output_poll_changed(struct drm_device *dev) {
//中は省略
}
#endif
修正が終わりましたら、モジュールをビルドしていきます。
cd /usr/src/kernel-modules/nvidia-470.256.02-default/
sudo make
※この際にBTF生成に関する警告(”Skipping BTF generation…”)がでますが、無視して問題ありません。
ビルドしたモジュールを手動でインストールしていきます。
このときに古いnvidiaのモジュールがあれば、事前に削除をしたほうがいいです。
# 古いモジュールの削除(あれば)
sudo rm -f /lib/modules/$(uname -r)/kernel/drivers/video/nvidia*.ko
# 新しいモジュールのコピー
sudo cp nvidia.ko nvidia-modeset.ko nvidia-drm.ko nvidia-uvm.ko nvidia-peermem.ko /lib/modules/$(uname -r)/kernel/drivers/video/
# 依存関係の更新
sudo depmod -a
# モジュールのロード
sudo modprobe nvidia
ここまでエラーがみられなければ、以下のコマンドで正常にドライバがインストールされたか確認していきます。
sudo reboot
# 再起動後、ドライバーが認識されているか確認
nvidia-smi
nvidia-smi
Thu Jan 9 09:34:18 2025
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.256.02 Driver Version: 470.256.02 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 N/A | N/A |
| 30% 30C P8 N/A / N/A | 1MiB / 1995MiB | N/A Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
おわりに
カーネルのバージョンアップに伴うNVIDIAドライバの再ビルドの問題は、Linuxユーザーにとってはよくあることです。特に私が使うTumbleweedのようなローリングリリースのディストリビューションを使用している場合、カーネルの更新は頻繁に発生し、それに伴ってグラフィックドライバの調整が必要になることがあります。
今回の問題のように、カーネルAPIの変更によってドライバのビルドが失敗することは少なくないです。特に、NVIDIAの古いバージョンのドライバを使用している場合は要注意ですが、ほとんどの場合、今回のように条件分岐を追加することで解決できます。
同様の問題で悩んでいる方々の助けになれば幸いです。カーネルアップデートの後でグラフィックドライバに問題が発生した場合は、エラーメッセージをよく確認し、カーネルとドライバの互換性を意識しながら対処することをお勧めします。
おわり