Ubuntu x Ryzen 7環境での「BUG: soft lockup - CPU#NN stuck」を解消したい

Ubuntu x Ryzen 7環境での「BUG: soft lockup - CPU#NN stuck」を解消したい
Page content

M75q 2台目

自宅デスクトップPCをLenovoの小型PC「ThinkCentre M75q Tiny Gen2」へ入れ替えました。購入物は次の通りで、プレインストールのWindowsは使わずにUbuntuをインストールしています。

分類メーカー・機種名価格(円)備考
PC本体Lenovo ThinkCentre M75q Tiny Gen2 11JJCTO1WW (Ryzen 7 PRO 4750GE, 8GB メモリ, 128GB SSD, Wi-Fi)51,000Y!オークション
メモリCrucial 16GB DDR4-3200 SODIMM CT16G4SFRA32A x 214,000メルカリ
SSDWestern Digital WD Blue SN570 NVMe™ SSD (500GB) WDS500G3B0C6,880ドスパラ
合計71,880

※本構成の結果、M75q Gen2本体に付属していた次のパーツが余る: 8GBメモリ, 128GB SSD (NVMe M.2 2242)

ちなみに新デスクトップPCは旧PCと比較すると筐体サイズは同じで、Ryzen 5から7への変化によりCPU Markのスコアは約2倍。他方、過去に詳細を下記記事に書いた旧デスクトップPCは、これからは仮想環境のホストへと鞍替えして活用する予定です。

Crucial 16GB*2枚 ノートPC向けメモリ DDR4 3200 MT/s(PC4-25600) CL22 SODIMM 260pin 無期限保証 CT2K16G4SFRA32A

Crucial 16GB*2枚 ノートPC向けメモリ DDR4 3200 MT/s(PC4-25600) CL22 SODIMM 260pin 無期限保証 CT2K16G4SFRA32A

Crucial(クルーシャル)

Western Digital ウエスタンデジタル 内蔵SSD 500GB WD Blue SN570 (読取り最大 3,500MB/秒) M.2-2280 NVMe WDS500G3B0C-EC 【国内正規代理店品】

Western Digital ウエスタンデジタル 内蔵SSD 500GB WD Blue SN570 (読取り最大 3,500MB/秒) M.2-2280 NVMe WDS500G3B0C-EC 【国内正規代理店品】

ウエスタンデジタル(Western Digital)

kernel「BUG: soft lockup - CPU#NN stuck」って何?

さて。M75q Gen2 (物理マシン) にUbuntu Desktopをインストールして使い始めると、基本的には反応良くて快適なのですが次の不具合に気づきました。

  1. GUIログイン後にしばらく放置しておくと、意図している省エネ動作としてデスクトップ画面が消える
  2. その後にマシンを使おうとするも、画面が点かない。SSHログインは可能だが反応がどこか緩慢で、syslogには次のログが吐かれている。topコマンドでのプロセス状況としてはXorgが刺さっているように見える
$ grep CPU /var/log/syslog
Apr  1 21:52:10 m75q2 kernel: [11473.338919] watchdog: BUG: soft lockup - CPU#14 stuck for 26s! [Xorg:1942]
Apr  1 21:52:10 m75q2 kernel: [11473.339030] CPU: 14 PID: 1942 Comm: Xorg Tainted: G           O      5.13.0-39-generic #44~20.04.1-Ubuntu
Apr  1 21:52:38 m75q2 kernel: [11501.696730] watchdog: BUG: soft lockup - CPU#14 stuck for 52s! [Xorg:1942]
Apr  1 21:52:38 m75q2 kernel: [11501.696816] CPU: 14 PID: 1942 Comm: Xorg Tainted: G           O L    5.13.0-39-generic #44~20.04.1-Ubuntu
  1. 私には復旧方法がわからず再起動や電源OFFをするしかない

画面が起きてこない原因を調べてみると、LinuxとRyzen (今回の場合はUbuntuとRyzen 7 PRO 4750GE) にはカーネルが関係する相性問題があるのかも?とわかります。

この不具合はカーネル更新等でいつか治るのかもしれませんが、現時点での応急処置 (ワークアラウンド) としては「AMD Ryzen CPUのC6 Stateを無効化せよ」らしいので、C6 Stateの無効化設定を次の環境で実施してみます。はたしてこれで問題は解決するのか、しばらく様子見です。

項目内容
ModelLenovo ThinkCentre M75q Gen2 (11JJCTO1WW)
BIOS Revision LevelM3CKT32A (2022-04-04時点での最新版)
CPUAMD Ryzen 7 PRO 4750GE
OSUbuntu 20.04.4 LTS
uname -aLinux m75q2 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

C6 Stateの無効化手順 〜一時的版〜

  1. M75q Gen2のBIOSで「Secure Boot」をEnableDisableへ変更する (Enableのままだと後述のmsrモジュールが読み込まれない)
  2. sudo modprobe msrしてみてエラーが出ないことを確認する
  3. sudo vim /etc/modulesして最終行にmsrを書き加える
$ cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
msr
  1. Ubuntuを再起動する
  2. 再起動後にmsrモジュールが読み込まれていることを確認する
$ lsmod | grep msr
intel_rapl_msr         20480  0
intel_rapl_common      24576  1 intel_rapl_msr
msr                    16384  0
  1. GitHubの r4m0n/ZenStates-Linux: Dynamically edit AMD Ryzen processor P-States https://github.com/r4m0n/ZenStates-Linux を手元にgit cloneする
  2. 次の操作でC6 StateがDisableへ変更できることを確認する
$ sudo python3 ./zenstates.py -l
P0 - Enabled - FID = 7C - DID = 8 - VID = 35 - Ratio = 31.00 - vCore = 1.21875
P1 - Enabled - FID = 66 - DID = C - VID = 60 - Ratio = 17.00 - vCore = 0.95000
P2 - Enabled - FID = 62 - DID = E - VID = 66 - Ratio = 14.00 - vCore = 0.91250
P3 - Disabled
P4 - Disabled
P5 - Disabled
P6 - Disabled
P7 - Disabled
C6 State - Package - Enabled
C6 State - Core - Enabled

$ sudo python3 ./zenstates.py --c6-disable
Disabling C6 state

$ sudo python3 ./zenstates.py -l
P0 - Enabled - FID = 7C - DID = 8 - VID = 35 - Ratio = 31.00 - vCore = 1.21875
P1 - Enabled - FID = 66 - DID = C - VID = 60 - Ratio = 17.00 - vCore = 0.95000
P2 - Enabled - FID = 62 - DID = E - VID = 66 - Ratio = 14.00 - vCore = 0.91250
P3 - Disabled
P4 - Disabled
P5 - Disabled
P6 - Disabled
P7 - Disabled
C6 State - Package - Disabled
C6 State - Core - Disabled

C6 Stateの無効化手順 〜サービス化版〜

  1. 上記の「一時的版」が一通り正常に行える状態にする
  2. zenstates.py/usr/local/bin/にcpしてownerなどを設定する
sudo cp -a ./zenstates.py /usr/local/bin/
sudo chown root.root /usr/local/bin/zenstates.py
sudo chmod 755 /usr/local/bin/zenstates.py
  1. sudo vim /etc/systemd/system/disable-c6.serviceで次の内容のサービスファイルを作成する
[Unit]
Description=Ryzen Disable C6
DefaultDependencies=no
After=sysinit.target local-fs.target suspend.target hibernate.target
Before=basic.target

[Service]
Type=oneshot
ExecStart=python3 /usr/local/bin/zenstates.py --c6-disable

[Install]
WantedBy=basic.target suspend.target hibernate.target

# Ref: https://gure-it-memo.com/amd-linux/#disable-c6
  1. 次の操作でサービスdisable-c6.serviceを有効化する
sudo systemctl daemon-reload
sudo systemctl enable disable-c6.service
  1. Ubuntuを再起動した後、C6 StateがDisableに変更されていることを確認する
sudo python3 /usr/local/bin/zenstates.py -l

追記 (AMDGPU firmwareも最新化) [2022-04-06]

C6 Stateの無効化を先日行った環境にて、PCを数十分使っていない間に「BUG: soft lockup - CPU#NN stuck」がまた発生してしまいました。

となると、応急処置としてC6 Stateの無効化だけでは駄目なのかもしれないので、さらなる試行錯誤として https://gure-it-memo.com/amd-linux/#amdgpu で紹介されているAMDGPU firmwareの最新化も行ってみます (もはや御呪い)。具体的な手順は次の通りです。

cd ~/tmp/
git clone --depth=1 https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git

# 内容更新されるファイルがどれぐらいあるかを概算
rsync -n -av ./linux-firmware/amdgpu/* /lib/firmware/amdgpu/ | wc -l
482 # コピーされるファイル数はこれぐらい (そもそもタイムスタンプが違っている)
rsync -n -av --checksum ./linux-firmware/amdgpu/* /lib/firmware/amdgpu/ | wc -l
178 # 実際に内容更新されるファイル数はこれぐらい

# 念のため上書き前にファイルを手元にバックアップ
tar czvf ./amdgpu_`date +'%Y%m%d'`.tar.gz /lib/firmware/amdgpu/

# ファイルコピーとinitramfsの更新を行った後に、再起動
sudo rsync -av ./linux-firmware/amdgpu/* /lib/firmware/amdgpu/
sudo update-initramfs -k all -u -v
sudo reboot

参考リンク