AMD GPUで発生するLinuxのスリープ復帰問題を解決した方法
(nyanpasu64.gitlab.io)-
問題の発生: WindowsとLinuxをデュアルブートしているデスクトップで、Linuxで大容量のRAMを使用した状態でスリープに入ると、システムがクラッシュする問題が発生。復帰時には黒い画面が表示されたり、応答しない状態になったりする。この問題は、
amdgpuドライバの電源/メモリ管理バグによるもの。 -
問題の診断: Gigabyte B550M DS3HマザーボードとAMD RX 570 GPUを使用するシステムでArch Linuxを実行中。システムクラッシュ後に
journalctlでログを確認したところ、amdgpu_device_suspendでメモリ不足(OOM)エラーが発生していることを発見。NVMeドライバがシステム再開時の初期化に失敗し、その結果システムが停止してログも記録されなかった。 -
解決の試み: 複数のスリープモードを試すためにsystemdの設定を変更し、非同期スリープを無効化して問題の単純化を試みたが、根本的な問題は解決しなかった。
amdgpuのTTMバッファ削除処理でクラッシュが発生していることを確認。 -
問題の原因: システムがS3スリープに入るとPCIe GPUの電源が遮断され、VRAM内のデータが失われる。これを防ぐためにGPUドライバはVRAMをシステムRAMへバックアップする必要があるが、Linuxの
amdgpuドライバは十分なRAMがない場合、メモリ不足でシステムがクラッシュしてしまう。 -
解決策: Mario Limoncielloが、ディスクベースのストレージが停止する前にVRAMをバックアップするようカーネルパッチを作成。このパッチでは、VRAMバックアップを
dpm_suspend()ではなくdpm_prepare()段階で実行するよう変更し、メモリ不足時にスリープ処理を中断できるようにした。 -
追加の問題解決: ユーザーは、ユーザー空間でVRAMをバックアップするスクリプトを作成し、システムのスリープ前にVRAMをシステムRAMへ移動させた。ただし、複数の3Dアプリが実行中の場合はVRAMが継続してGPUへ移動し、クラッシュが発生する可能性があった。
-
最終的な解決: 電源管理通知APIを使い、
PM_SUSPEND_PREPARE段階でVRAMをバックアップするよう変更。これにより、スワップが無効化される前にVRAMをシステムRAMへ移動できるようになり、問題が解決した。 -
結論: この問題は複数の人の努力とさまざまな試行を通じて解決され、Linuxカーネル6.14に含まれる予定。
1件のコメント
Hacker Newsの意見
デスクトップがS3スリープモードに入ると、システムがPCIe GPUの電源を遮断するという前提に疑問がある
udevadmコマンドを使ってデバイス情報を取得できるmemreserverの作者が、Linuxのスリープ問題を解決するためにデバッグした経験を共有している
Linuxでスリープ機能を実装することが難しい理由と、デバッグの難しさを説明している
RyzenベースのThinkPadを使っているユーザーがLinuxでスリープ問題に悩まされており、6.14バージョンに期待している
「スリープ/ウェイク」問題がNP完全問題だと気づいた、という意見を共有している
Framework AMDノートPCでGPU拡張とLinux/Windowsのデュアルブートを使うユーザーにとって役立つだろう、という意見がある
AMD GPUでスリープ後にPCがほぼフリーズする問題に悩まされているユーザーが、解決に取り組んでいる
Linuxを使っている間、常にスリープ問題に悩まされてきたという意見がある
IoTハードウェアでスリープ問題をデバッグした経験を共有している
メモリ管理とOOM条件が、Linuxでは依然として難しい問題であることを説明している