と言っても、それ程気にしていなかった時期も長く、いつから悩んでいたのか覚えていません。
私のGPD WIN4はRyzen7 6800U搭載です。
さまざまなカーネルパラメータを試してはフリーズしていました。
(下記のつぶやきではGPD WINになっていますがGPD WIN4の間違いです。)
ついに見付けたのが
processor.max_cstate=1
というカーネルパラメータです。
https://gist.github.com/dlqqq/876d74d030f80dc899fc58a244b72df0
少しテストしてみたところ、確かにフリーズしないようです。
しかしバッテリーで動いている時もC1だけになってしまうのはかなり不安です。
可能であれば、
・充電中はC1のみ
・充電していない時は制限解除
というように制御したいです。
ChatGPTやMicrosoft Bingに尋ねたところcpupowerというコマンドで全てのCPUコアを一度の実行でC-Stateを変更できそうです。
また、Plamo Linuxではデフォルトで全てのACPIイベントが
/etc/acpi/handler.sh
で処理されているようなので、ここで充電開始と終了を処理する際にcpupowerコマンドを実行すれば良いのかなと考えました。
その他システム起動時に充電中であった場合は
/etc/rc.d/init.d/
以下にその状態をみて必要であればcpupowerを実行するファイルを作成し、
/etc/rc.d/rc3.d/や/etc/rc.d/rc5.d/
以下にリンクを作成すれば良さそうです。
・cpupowerの入手
まず核となるcpupowerコマンドの入手方法を探しました。Arch LinuxのPKGBUILDを探してみたり、Ubuntu Package Searchを検索してみたのですが、cpupower-guiはあるのですがcpupowerが見付かりません。
Plamo Linuxにデフォルトで入っていないか/var/log/packageを見てみましたがありません。
何気無く/vae/log/package以下でgrep検索してみたところ、カーネルソースに含まれていることが分かりました。
カーネルのPlamoBuildスクリプトに以下の部分を追加し、カーネルと一緒にパッケージを作成するようにしました。
2023/10/29追記
・充電中はC1のみにし、充電していない時は制限解除する
udevを使うとシステム起動時、充電開始/終了、スリープ中に充電開始/終了の全ての状態を見てcpupowerコマンドを実行できました。
/etc/udev/rules.d/99-disable_cstate.rulesを下記の内容で作成します。
以下はudevを使用する場合は必要ありません。
・充電開始でC1のみにし、終了時に制限解除する
/etc/acpi/handler.shの下記の部分を修正しました。
CPUPOWER="/usr/bin/cpupower"
として定義されています。
・システム起動時に充電中であればC1のみにする
まず下記のシェルスクリプト(disable_cstate)を作成しました。
次に下記のファイルを/etc/rc.d/init.d/disable_cstateとして作成しました。
あとは/etc/rc.d/init.d/disable_cstateのリンクを/etc/rc.d/rc3.d/等の下に作成しました。
その他、スリープ中に充電開始/終了した場合のテストをまだ行なっていません。
意図した処理は想定通り動いています。
さまざまなカーネルパラメータを試してはフリーズしていました。
(下記のつぶやきではGPD WINになっていますがGPD WIN4の間違いです。)
GPD WINのLinux充電したまま放置しておくと何をしても反応しなくなる。電源はついたまま。
— はなぐろ (@hanaguro) October 17, 2023
で、カーネルパラメータにdebugつけて放置していたのだけど、syslogには最後に
ACPI action undefined: PNP0C0A:00
ってあった後、次にブートするまで1時間近く何もなかった。
ついに見付けたのが
processor.max_cstate=1
というカーネルパラメータです。
https://gist.github.com/dlqqq/876d74d030f80dc899fc58a244b72df0
少しテストしてみたところ、確かにフリーズしないようです。
しかしバッテリーで動いている時もC1だけになってしまうのはかなり不安です。
可能であれば、
・充電中はC1のみ
・充電していない時は制限解除
というように制御したいです。
ChatGPTやMicrosoft Bingに尋ねたところcpupowerというコマンドで全てのCPUコアを一度の実行でC-Stateを変更できそうです。
また、Plamo Linuxではデフォルトで全てのACPIイベントが
/etc/acpi/handler.sh
で処理されているようなので、ここで充電開始と終了を処理する際にcpupowerコマンドを実行すれば良いのかなと考えました。
その他システム起動時に充電中であった場合は
/etc/rc.d/init.d/
以下にその状態をみて必要であればcpupowerを実行するファイルを作成し、
/etc/rc.d/rc3.d/や/etc/rc.d/rc5.d/
以下にリンクを作成すれば良さそうです。
・cpupowerの入手
まず核となるcpupowerコマンドの入手方法を探しました。Arch LinuxのPKGBUILDを探してみたり、Ubuntu Package Searchを検索してみたのですが、cpupower-guiはあるのですがcpupowerが見付かりません。
Plamo Linuxにデフォルトで入っていないか/var/log/packageを見てみましたがありません。
何気無く/vae/log/package以下でgrep検索してみたところ、カーネルソースに含まれていることが分かりました。
カーネルのPlamoBuildスクリプトに以下の部分を追加し、カーネルと一緒にパッケージを作成するようにしました。
echo "Building cpupower package"
rm -rf $P
mkdir $P
cd $B/tools/power/cpupower
make install DESTDIR=$P libdir=/usr/lib
install_tweak
convert_links
cd $P
/sbin/makepkg ../cpupower-${vers}-${arch}-${build}.${compress}
2023/10/29追記
・充電中はC1のみにし、充電していない時は制限解除する
udevを使うとシステム起動時、充電開始/終了、スリープ中に充電開始/終了の全ての状態を見てcpupowerコマンドを実行できました。
/etc/udev/rules.d/99-disable_cstate.rulesを下記の内容で作成します。
SUBSYSTEM=="power_supply", ATTR{online}=="0", RUN+="/usr/bin/cpupower idle-set -E"
SUBSYSTEM=="power_supply", ATTR{online}=="1", RUN+="/usr/bin/cpupower idle-set -D 2"
作成したルールを読み込ませます。# udevadm trigger
以下はudevを使用する場合は必要ありません。
・充電開始でC1のみにし、終了時に制限解除する
/etc/acpi/handler.shの下記の部分を修正しました。
CPUPOWER="/usr/bin/cpupower"
として定義されています。
ac_adapter)
case "$2" in
AC|ACAD|ADP0|ACPI0003:00)
case "$4" in
00000000)
logger 'AC unpluged'
if [ -x $CPUPOWER ];then
$CPUPOWER idle-set -E
fi
;;
00000001)
logger 'AC pluged'
if [ -x $CPUPOWER ];then
$CPUPOWER idle-set -D 2
fi
;;
esac
;;
・システム起動時に充電中であればC1のみにする
まず下記のシェルスクリプト(disable_cstate)を作成しました。
#!/bin/sh
status=$(cat /sys/class/power_supply/BATT/status)
if [ $status = "Charging" ];then
/usr/bin/cpupower idle-set -D 2
fi
次に下記のファイルを/etc/rc.d/init.d/disable_cstateとして作成しました。
#!/bin/sh
. /lib/lsb/init-functions
case $1 in
start)
log_info_msg "Starting disable cstate..."
start_daemon /usr/local/bin/disable_cstate
evaluate_retval
;;
*)
echo "usage: $0 [start]"
exit 1
;;
esac
あとは/etc/rc.d/init.d/disable_cstateのリンクを/etc/rc.d/rc3.d/等の下に作成しました。
意図した処理は想定通り動いています。
0 件のコメント:
コメントを投稿