LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

装 Linux 的 Thinkpad X1C 在发高烧

前话

本着对小黑和 Linux 的喜欢,在去年年中买了 Thinkpad X1C 并装上了 Gentoo,然后,就很少再见它……因为我还有一本老 Thinkpad T440s + Gentoo 和一台性能强劲的 ITX + Gentoo,各种“派”小电脑。

今年因疫情原因,终于打开我的小宝贝,发现不该有的异常高温居然出现在小本本身上,待机 65 - 70 度,回顾了我 2010 年的 Thinkpad R400,调教完可是日常使用 30 度不到,14 年我一直抱怨烫手的 Thinkpad T440s 是 45 度,而今,这 Thinkpad X1C 就让人有点情绪了,高温伴随的可不只只是性能的下降,还有续航的短暂。我打开了我的 Thinkpad T440s,服役六年,大屁股(6 芯)电池现在使用 Gnome 3 和 默认系统配置(CPU 的 Governor 是 Conservative,没有使用 tlp 或 laptop mode tools 等)还剩 6 到 7 小时,而 X1C 使用 KDE 5 和默认系统配置居然有 1.5 小时那么长……和官方宣称的 10 多小时也差太多了吧。

发热问题

Linux 下大部分都是使用 lm-sensors 来检测温度的,详细的模块需要内核支持,不同笔记本的内核配置不同,针对自己的在 XXX Wiki 上找就行,而我去年就将匹配我电脑的内核 /usr/src/linux/.config 弄好,所以直接输入 sensors 来看看各个模块的温度。

解决问题

面对笔记本产生的热浪,一波接一波,我只能一步一步尝试能否解决,解决方向不外乎 ACPI。

从 BIOS 入手(失败)

基本所有的笔电都会可以设置 CPU 和 ACPI 的,看了下,默认的 ACPI 没得多余可以设置,肯定是用 AC 时候就性能,用 Battery 就节能。CPU 唯一能做的就是关闭多线程和虚拟化。结果关闭之后温度下降 2 度左右,这不知道是误差还是其他,算了,开启回来吧……

Cpupower 工具调节(失败)

依照我之前使用 AMD Ryzen 的经验,CPU 的发热在于他的 Turbo Boost,我使用 Cpupower 限制最高频率的时候,居然会把 Ryzen 的 Turbo Boost 搞没(意思就是你最高重设为多大都没有了)……但温度真的憨憨下降 10 多度……

我这里试下,发现怎么限制频率都没用,Governor 也没用,仿佛这个工具就是个玩具一样……

这里得说下 Ryzen 的 CPU Governor 是使用 Linux Kernel 的,但是到了 Intel Sandy Bridge 后的架构都是使用 intel_pstate 来搞事情,他自身也只有 Performance 和 Powersave 两种 Governor 而已,外部工具还对他没啥用。

使用 Intel 的私货调节(失败)

/sys/devices/system/cpu/intel_pstate 可以看到 intel_pstate 的信息,而 Governor 不管是 AC 还是 Battery,都是 Powersave:

cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor

所以用其方式来关闭 Turbo Boost:

echo 1 > /sys/devices/system/cpu/intel_pstate/no_turbo

发现确实温度确实低了,而且 CPU 没法跑到 3 GHz 以上了,性能砍一刀,温度总是能够看了吧。打开了我们熟悉的 B 站看弹幕视频,哇,温度一下子就 80 多度……

回归最开始的内核控制 CPU 频率(不妥)

上面那般折腾,我在想能不能使用之前内核调节那种,不就一切迎刃而解了吗。

直接在 grub 的内核配置 intel_pstate=disable 就可以禁用 intel_pstate,使用内核的管理了,果然 Conservative 的 Governor 回来了。

可是可是可是,新问题来了!禁用 intel_pstate 后,CPU 的频率可调节范围变了,从 400MHz - 3.9GHz 变成 800MHz - 1.6GHz 了,想砸键盘了没……

寻找外挂工具(失败)

外挂工具最出名的,当有 Laptop Mode Tools 的一个位置,而不知道是不是跟 intel_pstate 有冲突,CPU 和 GPU 控制不了,风扇差点搞坏,各种设备设置很多,确实可以省电,但是我这里的电老虎和大太阳并非它们……

寻找外挂工具二(勉强)

在 Gentoo Wiki 上有看到推荐的 Thermald,是 Intel 那帮人专门搞冷却 CPU 的。安装是特别简单,但是配置就头大了。基本网络上和官网都没有详细的参数说明,唯一给出的是帮助手册:

man thermal-conf.xml

但是可以发现里面参数说明缺失严重。

配置可以通过 dptfxtract 来自动检测生成,在 github 上拉下来就可以用了。

开启 Thermald 后,基本温度都是在机器自己风扇启动的阀值内,Thinkpad X1C 2019 是 63 度。没开启的续航是 1.5 小时不到,开启后则是 4 个多小时。

不过开启后,为了冷却,CPU 的频率经常是 1GHz 以下,越是占资源,频率越低,所以我打开个 Emacs + Java Lsp 卡得都写不了代码,频率经常是在 400MHz - 800MHz 之间跳。看电影有解码就很流畅,轻量办公的续航还是不错的。

但回归下,Battery 模式为了节能没毛病,AC 模式肯定不能有那么卡顿的体验,Thermald 的官网说开启和关闭是这么来的:

[root]: systemctl start thermald  # turn on
[root]: systemctl stop thermald   # turn off

但实际上,假如你开启了,关闭后怎么样也回不了性能状态了……

Thermald 其实还支持动态修改配置,通过 --enable-dbus 来开启对 dbus 消息的支持,那么这里是不是我们就可以不关闭,而直接动态设定一个温度墙来保证性能和节能呢?

很遗憾,不管在 thermal-conf.xml 还是 dbus 来通知 thermald 温度墙多少,他都不会变的,我的 Thinkpad X1C 永远就是 63 度……

在多种尝试后,我发现现在的 Thermald 是通过 PPCC 的电源表来控制的,假如 thermal-conf.xml 文件有 PPCC 配置,就会实现冷却功能,若无,就会回归原始状态,不知道是不是 bug,从 1.9.1 到 2.1 版本皆如此。

对于最后 Thermal 虽然有些不完美,但是我们可以去完善它。我的期望,简单如述:AC 下性能模式,Battery 下节能模式。

我们先创建一个目录,用来跑电源管理脚本的:

mkdir ~/.myacpi

然后呢,我们将之前自动生成的 /etc/thermald/thermal-conf.xml.auto 拷贝两份到该目录下:

cp /etc/thermald/thermal-conf.xml.auto ~/.myacpi/thermal-conf.xml.ac
cp /etc/thermald/thermal-conf.xml.auto ~/.myacpi/thermal-conf.xml.battery

紧接着,我们 battery 保留 PPCC 配置,ac 去掉:

<!--<PPCC>
    <PowerLimitIndex>0</PowerLimitIndex>
    <PowerLimitMinimum>5000</PowerLimitMinimum>
    <PowerLimitMaximum>5000</PowerLimitMaximum>
    <TimeWindowMinimum>28000</TimeWindowMinimum>
    <TimeWindowMaximum>32000</TimeWindowMaximum>
    <StepSize>500</StepSize>
</PPCC>-->

再者就是编写两个 Shell 脚本,ac 和 battery,而在这之前,需要我们的用户有 thermalddbus-sendsudo nopasswd 权限,当然这是因为这里我使用的是 KDE 的电源管理,针对用户的。

#! /usr/bin/env bash
## file: ac
sudo thermald --dbus-enable --config-file ~/.myacpi/thermal-conf.xml.ac && sudo dbus-send --system --dest=org.freedesktop.thermald /org/freedesktop/thermald org.freedesktop.thermald.Terminate && echo "[`date +'%F %T'`] ac thermald" >> ~/.myacpi/log
#! /usr/bin/env bash
## file: battery
sudo thermald --dbus-enable --config-file ~/.myacpi/thermal-conf.xml.battery && sudo dbus-send --system --dest=org.freedesktop.thermald /org/freedesktop/thermald org.freedesktop.thermald.Terminate && echo "[`date +'%F %T'`] battery thermald" >> ~/.myacpi/log

最后,就是在 KDE 的电源管理的 AC 和 Battery 选项卡里面加入各自的运行脚本。

寻找外挂工具三(失败)

顺藤摸瓜,就 Thermald 摸到另一个 Intel 的官方工具 intel-undervolt。想着给电脑减减压,也许是他压力太大了!但更改电压着实是个冒险的做法,在尝试过程中,笔电各种崩溃,睡眠各种唤不醒……

调节出合适的电压,每一种电脑都是不太一样的,所以要小心尝试,别步伐迈得过大,我的 Thinkpad X1C Carbon 2019 这里可以达到 -120mV,这是个比较大胆的值,所以还是提醒下,要千万小心,修改 /etc/intel-undervolt.conf 配置:

undervolt 0 'CPU' -120
undervolt 1 'GPU' -120
undervolt 2 'CPU Cache' -120
undervolt 3 'System Agent' -120
undervolt 4 'Analog I/O' 0

这里的 I/O 我是没有更改,因为之前 USB 和 Type-C 因为各种电压不足没法连接外设。

intel-undervolt read  # 查看当前值
intel-undervolt apply # 更改为配置值

在观查功耗时,我能看到大概是下降了 2W 到 3W,那么我 51W 电池(实际可用感觉应该是 45W),大概也只能多出 30 分钟,但换来的可能是损坏硬件和系统不稳定。

尝试从功耗解决(还算 OK)

既然主要是关注续航,那么在 AC 下就让它继续发热,Battery 下就通过限制功耗来解决,这时性能低下,也就让它低下吧。这里刚好可以利用之前的 intel-undervolt 来检测功耗:

intel-undervolt measure

内核配置 powercap 后,是可以直接可以动态修改 /sys/class/powercap/intel-rapl/ 目录里面的配置来实现功耗限制。在该目录下面可能有类似 intel-rapl:0 或 intel-rapl:1 的目录,我们只能更改类型为 package0,不能是 psys 的,具体在这对应目录下的 name 可以分辨类型。功耗墙的设定是在 constraint_0_power_limit_uw 和 constraint_1_power_limit_uw 文件中,一个是 long term 一个是 short term。

为了方便,我随便写了一个简单脚本放到 /sbin 下,并且给 sudo 无密权限

#! /usr/bin/env bash
### file: my-acpi-mode
orginal_value=51000000
min_value=3500000
mid_value=5000000
value="$1"
if [ "$value" == "min" ]; then
  value=$min_value
fi
if [ "$value" == "max" ] || [ -z "$value" ]; then
  value=$orginal_value
fi
if [ "$value" == "mid" ]; then
  value=$mid_value
fi
if (( value >= min_value && value <= orginal_value )); then
  echo $value > /sys/class/powercap/intel-rapl/intel-rapl\:0/constraint_0_power_limit_uw
  echo $value > /sys/class/powercap/intel-rapl/intel-rapl\:0/constraint_1_power_limit_uw
else
  echo "Error Value"
fi

最后,将之前 KDE 触发的 ac 和 battery 脚本改成:

#! /usr/bin/env bash
## file: ac
sudo my-acpi-mode max &&  echo "[`date +'%F %T'`] ac mode" >> ~/.myacpi/log
#! /usr/bin/env bash
## file: battery
sudo my-acpi-mode mid &&  echo "[`date +'%F %T'`] battery mode" >> ~/.myacpi/log

在外出的时候,可能还会运行:

sudo my-acpi-mode min

来保证更长的续航。

后话

在使用 powertop 检测耗电的时候,发现发热和耗电的原因其实是 Intel kaby GPU在 Kernel 是 5.5 以下 RC6 是不起作用,而现在的 5.5 以上 GPU 是经常会 hang 的 bug,这种情况持续了 7 到 8 个月了,所以只能期待 5.6+ 以上的内核能够不 hang 让 GPU 的 RC6 生效。

但本子总要使用起来,Intel 的 GPU 是在 CPU 结构的 Package 里的,所以降压和降低功耗,是现在能够缓解下续航短的压力的,且等到 GPU RC6 解决了,减少功耗的脚本依然能够适用,将续航变得更长。