ThinkPad T495s (AMD Ryzen) で Linux が頻繁にフリーズするときの一対策

## はじめに

AMD Ryzen 5を積んだThinkPad T495sにLinuxを導入してみたのですが、使用中にたびたびフリーズして使い物になりませんでした。発生タイミングはよく分からず、起動後すぐに止まることもあれば数時間経って忘れた頃にフリーズすることも。Ubuntu 20.04, Ubuntu 20.10, Manjaro, Regolith, Pop!\_OS 20.04のいずれでも発生しました。CentOS等は試していません。少し調べてみたところどうやらGPUが怪しい。完全には解決できていませんが、緩和策を見つけたので共有します。緩和策についてはPop!\_OS 20.04でしか試していません。

## 環境

以下の環境で確認しました。

```
             /////////////                x@pop-os 
         /////////////////////            ------------- 
      ///////*767////////////////         OS: Pop!_OS 20.04 LTS x86_64 
    //////7676767676*//////////////       Host: 20QJS06X00 ThinkPad T495s 
   /////76767//7676767//////////////      Kernel: 5.8.0-7642-generic 
  /////767676///*76767///////////////     Uptime: x mins 
 ///////767676///76767.///7676*///////    Packages: 1728 (dpkg), 6 (flatpak) 
/////////767676//76767///767676////////   Shell: bash 5.0.17 
//////////76767676767////76767/////////   Resolution: 1920x1080, 1920x1080 
///////////76767676//////7676//////////   DE: GNOME 
////////////,7676,///////767///////////   WM: Mutter 
/////////////*7676///////76////////////   WM Theme: Pop 
///////////////7676////////////////////   Theme: Pop-dark [GTK2/3] 
 ///////////////7676///767////////////    Icons: Pop [GTK2/3] 
  //////////////////////'////////////     Terminal: gnome-terminal 
   //////.7676767676767676767,//////      CPU: AMD Ryzen 5 PRO 3500U w/ Radeon Vega Mobile Gfx (8) @ 2.100GHz 
    /////767676767676767676767/////       GPU: AMD ATI 05:00.0 Picasso 
      ///////////////////////////         Memory: 2716MiB / 13933MiB 
         /////////////////////
             /////////////                                        
```

## 問題

作業内容によらず突然フリーズします。何も入力を受け付けなくなり、画面の出力も完全に停止。唯一`Fn+Space`でキーボードのバックライトon/offのみ可能でした。

Ubuntu 20.04, Ubuntu 20.10, Manjaro KDE, Manjaro i3, Regolith 20.04, Pop!\_OS 20.04での発生を確認しました。

`radeontop`を使うと10秒ほどで必ずフリーズします。ちょっと様子を見に行っただけなのに、無理してフル稼働して燃え尽きてしまったように見えます。

![Screenshot from 2021-02-14 15-12-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696715/b99fccd8-c9d3-6f49-2623-222211763a62.png)

## 対策

[Arch LinuxでRadeon RX5500XT(Navi14)をいい感じに動かす設定 - プログラミングとかLinuxとかの備忘録](https://vild.hatenablog.com/entry/2020/06/06/161925)を読むと、AMDGPUのDPM(Dynamic Power Management)機能が怪しいとのこと。カーネルパラメータに`radeon.dpm=0`を追加すると無効化できるらしいですが、私の環境ではうまくいきませんでした。

上の記事からも参照されている[ArchWiki](https://wiki.archlinux.org/index.php/ATI#Dynamic_power_management)や、ググって見つけた [109955 – amdgpu [RX Vega 64] system freeze while gaming (VSYNC enabled)](https://bugs.freedesktop.org/show_bug.cgi?id=109955)等を参考にいろいろ試してみたところ`power_dpm_force_performance_level`を`auto`から`manual`に変えるのが最も効果的でした。

```shell-session
$ cat /sys/class/drm/card0/device/power_dpm_force_performance_level
auto

$ sudo su -
# echo manual > /sys/class/drm/card0/device/power_dpm_force_performance_level
# exit

$ cat /sys/class/drm/card0/device/power_dpm_force_performance_level
manual
```

これで`radeontop`すると...

![Screenshot from 2021-02-14 16-03-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696715/d39497bb-d820-b7b6-07db-406b5effda8f.png)

明らかにGPUの頑張り具合が減りました。`radeontop`を動かし続けてもフリーズしません。やった！！！

### 設定永続化(1)

上記の設定はリブートすると元に戻ってしまうので、以下のようなudevルールを作って永続化しておきます。

```text:/etc/udev/rules.d/30-radeon-pm.rules
KERNEL=="card0", SUBSYSTEM=="drm", DRIVERS=="amdgpu", ATTR{device/power_dpm_force_performance_level}="manual"
```

[[Solved] Startup script help / Newbie Corner / Arch Linux Forums](https://bbs.archlinux.org/viewtopic.php?id=220074)を参考にしました。`KERNEL`や`DRIVERS`は環境によって違いがあるようです。

~~2,3行目でmclkとsclkを最低レベルに下げましたが、これが効果的なのか逆効果なのかはまだ分かっていません。~~ **追記**: そもそもudevルールで`pp_dpm_mclk`や`pp_dpm_sclk`のセットはできませんでした。

### 設定永続化(2)

(効果があるのか分かりませんが)mclkとsclkを最低レベルにしたい場合は、[Fix AMD Vega GPU resets – Psy-Q's Braindump](https://blog.psy-q.ch/blog/2019/11/10/fix-amd-vega-gpu-resets/)を参考に以下の手順で進めます。

まず以下のような`amdgpu_workaround.sh`を用意します。

```sh:amdgpu_workaround.sh
#!/bin/sh
echo "manual" > /sys/class/drm/card0/device/power_dpm_force_performance_level
echo 0 > /sys/class/drm/card0/device/pp_dpm_mclk
echo 0 > /sys/class/drm/card0/device/pp_dpm_sclk
```

これを`/opt`に置いてrootで実行可能にします。

```shell-session
$ sudo cp amdgpu_workaround.sh /opt
$ sudo chmod +x /opt/amdgpu_workaround.sh
$ sudo chown root:root /opt/amdgpu_workaround.sh
```

起動時に上のスクリプトを自動実行するため、サービス定義`/etc/systemd/system/amdgpu_workaround.service`を用意します。

```systemd:/etc/systemd/system/amdgpu_workaround.service
 [Unit]
Description=workaround for AMD GPU

[Service]
User=root
Group=root
ExecStart=/opt/amdgpu_workaround.sh

[Install]
WantedBy=multi-user.target
```

サービスを有効化して、試しに実行もしてみます。

```shell-session
$ sudo systemctl enable amdgpu_workaround.service
$ sudo systemctl start amdgpu_workaround.service
```

これで起動時に`power_dpm_force_performance_level`が`manual`に変更されるとともに、mclkとsclkが最低レベルにセットされます。効果があるのかはしばらく様子を見てみます。

## その後

頻度は随分と下がりましたが、その後も作業中に二度ほどフリーズしました。まだしばらく様子を見ます。少なくとも`radeontop`でフリーズしなくなったのは進歩だと思っています。