---
title: Ubuntu Intel 性能模式问题排查：我修复 i7-1260P 的 PPD Governor 切换
tags:
    - Ubuntu
    - Intel P-State
    - Linux 电源管理
    - power-profiles-daemon
    - 故障排查
categories:
    - Linux
date: "2026-10-09 15:39:48"
desc: 记录 Ubuntu 26.04 上 Intel i7-1260P 性能模式问题：power-profiles-daemon 只切换 EPP、CPU governor 仍为 powersave，并通过本地补丁修复 performance 与 balanced 双向切换及 EBUSY 风险。
abbrlink: ubuntu-intel-pstate-performance-governor
---
最近我在 Ubuntu 设置里选了 Intel 性能模式，回头检查 CPUFreq policy 时却发现 governor 仍是 `powersave`。这台 i7-1260P 笔记本上的 power-profiles-daemon 已经把 EPP 切到 `performance`，但没有切换 governor；我于是沿着 PPD、`intel_pstate` 和 sysfs 的状态一路查下去，也把切回均衡时可能遇到的 `EBUSY` 一并处理了。

我这台笔记本是 12 代 Intel Core i7-1260P，Ubuntu 设置里有性能、均衡、节电三档。原来的 PPD 显示已经切到性能，sysfs 里的 EPP 也显示 `performance`，但每个 CPU policy 的 governor 仍然是 `powersave`。我想要的很明确：性能档切到真正的 `performance` governor；再切回均衡时，16 个 policy 能回到 `powersave`，而且 PPD 不能卡在半路报 `EBUSY`。

<!--more-->

## 先把现场记下来

这不是一篇“调几个参数，跑分飞升”的教程。我当时碰到的是模式映射和接口切换顺序问题。开始改之前，我先把系统报告、PPD 状态和 CPUFreq policy 对在一起看。

| 项目 | 当时核对到的状态 |
| --- | --- |
| 笔记本 CPU | 12th Gen Intel Core i7-1260P，16 个逻辑 CPU |
| Ubuntu | 26.04.1 LTS（Resolute Raccoon） |
| 内核 | `7.0.0-38-generic` |
| 调频驱动 | `intel_pstate`，`status=active` |
| power-profiles-daemon | Ubuntu 原包 `0.30-2` |
| platform profile | 没有 `/sys/firmware/acpi/platform_profile_choices`，PPD 显示 `PlatformDriver: placeholder` |
| CPUFreq policy | 16 个，每个 policy 对应一个逻辑 CPU |
| 热管理 | `thermald` 以 adaptive 模式运行 |

最开始记录的两档状态是这样的：

| 档位 | `scaling_governor` | `energy_performance_preference` |
| --- | --- | --- |
| balanced | `powersave` | `balance_performance` |
| performance（原版 PPD） | `powersave` | `performance` |

所以，问题不在于 `powerprofilesctl` 完全没有做事：它确实把 EPP 调到了偏性能的一端。问题是这套设置和我对“性能档”的目标不一致——我希望它切换 `intel_pstate` 提供的 `performance` 算法，而原版 PPD 在这个配置下并不这样做。

复核时我用的命令很普通，重点是同时看 PPD、驱动状态和全部 policy，而不只盯着一个 `cpu0`：

```bash title="检查 PPD、intel_pstate 与每个 CPUFreq policy"
powerprofilesctl get
powerprofilesctl list
cat /sys/devices/system/cpu/intel_pstate/status

for p in /sys/devices/system/cpu/cpufreq/policy*; do
  printf '%s cpus=%s governor=%s epp=%s\n' \
    "${p##*/}" \
    "$(cat "$p/related_cpus")" \
    "$(cat "$p/scaling_governor")" \
    "$(cat "$p/energy_performance_preference")"
done
```

## `powersave` 这个名字很容易让人误会

我一开始也把 `powersave` 直接理解成“CPU 被压在低频”。但在 `intel_pstate` 的 active 模式下，sysfs 中的 `powersave` 和 `performance` 是这个驱动提供的 P-state 选择算法名称，不是可以不看驱动就照字面理解的通用结论。内核文档特别说明了 active 模式下 `intel_pstate` 会提供自己的选择算法；其中 `powersave` 不等同于通用 governor 的同名实现。[Linux 内核 `intel_pstate` 文档](https://docs.kernel.org/admin-guide/pm/intel_pstate.html)

在支持 HWP 的 active 模式里，硬件负责具体 P-state 选择，`intel_pstate` 仍会提供性能提示。使用 `performance` 算法时，内核把 EPP 设到性能端，并拒绝通过 sysfs 把 EPP 改成其他偏好；使用 `powersave` 时，EPP 才作为可调提示保留下来。换句话说，`performance` governor 和 `balance_performance` EPP 不能由两个控制者想写什么就同时写什么。

这也解释了为什么我踩到了回切风险：假设外部脚本先把 governor 强制改成 `performance`，之后 PPD 收到“回 balanced”的请求并尝试写 `balance_performance`，内核就可能以 `EBUSY` 拒绝这个 EPP 写入。最终看到的就可能是 profile 状态和 CPU 设置不一致，或者整段模式切换失败。

这里有两个层次要分开：内核对 active `intel_pstate` 的行为是接口约束；原版 PPD 在这个驱动路径上选择保持 `powersave`、通过 EPP 应用 profile，则是它的实现策略。PPD 0.30 的 Intel 驱动探测阶段会确保 EPP 可写的 governor 为 `powersave`，各 profile 再映射到 `power`、`balance_performance` 或 `performance` 等 EPP 值。可对照 [Ubuntu Resolute 的 PPD 0.30-2 源码包索引](https://packages.ubuntu.com/source/resolute/admin/power-profiles-daemon)、[PPD 0.30 Intel P-State 驱动源码](https://sources.debian.org/src/power-profiles-daemon/0.30-1.1/src/ppd-driver-intel-pstate.c/) 和 [PPD 项目说明](https://upower.pages.freedesktop.org/power-profiles-daemon/)。

## 为什么不再加一个监听服务

我不想让 GNOME/PPD 和另一个常驻脚本同时争着写 governor、EPP。通过 D-Bus 监视 profile 变化再抢写 sysfs，会让两个控制者的先后顺序依赖时序；我此前已经把这类 `systemd` 服务加 `busctl monitor` 的做法列为必须避开的坑。它没有解决所有者冲突，只是多放了一个竞争者进去。

把 `intel_pstate` 切 passive 也不是这次要走的路线。此前试过后，performance 档仍没有得到我想要的 governor 行为；而且这次目标是在当前 active 配置下修正 profile 的应用逻辑。仅把 EPP 写成 `performance` 也不是修复，因为原版 performance profile 已经这么做了，实际 governor 仍是 `powersave`。

所以最后选的是改 PPD 自己的 Intel 驱动：同一个 daemon、同一次 profile activation 里完成 governor 和 EPP 的顺序控制，不让另一个服务在旁边猜用户切了什么档。

## 补丁改了什么

我基于 Ubuntu 的 PPD `0.30-2` 源码构建了一个本地包，版本号是 `0.30-2xing1`。核心改动分两步：先把 EPP policy 对应的 governor 一起切到目标状态；再决定是否写 EPP。完整补丁、构建包、回滚用原包和校验和已放在我的[公开 GitHub 仓库](https://github.com/xingwangzhe/ubuntu-intel-pstate-performance-governor)，Debian 包可从 [`v0.30-2xing1` Release](https://github.com/xingwangzhe/ubuntu-intel-pstate-performance-governor/releases/tag/v0.30-2xing1) 下载；仓库 README 记录了适用型号和系统版本、验证边界与回滚命令。

### 先逐个设置 policy 的 governor

下面是实际补丁中的 helper。PPD 已经保存了可写 EPP 的 policy 路径，因此从每个 EPP 路径取出 policy 目录，再写对应的 `scaling_governor`：

```c title="按每个 EPP policy 设置 governor"
static gboolean
set_epp_governor (PpdDriverIntelPstate *pstate,
                  const char           *governor,
                  GError              **error)
{
  guint i;

  for (i = 0; pstate->epp_devices && i < pstate->epp_devices->len; i++) {
    const char *epp_path = g_ptr_array_index (pstate->epp_devices, i);
    g_autofree char *policy_dir = g_path_get_dirname (epp_path);
    g_autofree char *gov_path =
      g_build_filename (policy_dir, "scaling_governor", NULL);

    if (!ppd_utils_write (gov_path, governor, error))
      return FALSE;
  }

  return TRUE;
}
```

### 再按 profile 决定是否写 EPP

profile 应用时，performance 档设 governor 后跳过 EPP 写入；离开 performance 时则先恢复 `powersave`，之后才写 balanced 或 power-saver 对应的 EPP：

```c title="避免在 performance governor 下写入非 performance EPP"
if (pstate->epp_devices) {
  if (profile == PPD_PROFILE_PERFORMANCE) {
    if (!set_epp_governor (pstate, "performance", error))
      return FALSE;
  } else {
    if (!set_epp_governor (pstate, DEFAULT_CPU_FREQ_SCALING_GOV, error))
      return FALSE;
  }

  if (profile != PPD_PROFILE_PERFORMANCE) {
    const char *epp_pref = profile_to_epp_pref (profile, pstate->on_battery);

    if (!ppd_utils_write_files (pstate->epp_devices, epp_pref, error))
      return FALSE;
  }
}
```

压缩成切换顺序就是：

| 要切换到 | PPD 的执行顺序 | 结果 |
| --- | --- | --- |
| performance | 所有 EPP policy 的 governor → `performance`；不再写 EPP | governor 进入性能算法，EPP 由该算法维持在性能端 |
| balanced | governor → `powersave`；再写 `balance_performance`（电池策略会按 PPD 原有映射选择） | EPP 写入时已经离开会锁定它的 governor |
| power-saver | governor → `powersave`；再写 `power` | 继续沿用 PPD 的省电 EPP 映射 |

这项补丁针对本机当前走到的 active Intel EPP 路径。代码保留 PPD 自身的 profile 管理和 AC/电池映射，没有增加轮询、D-Bus 监听或常驻 helper。`power-saver` 的映射在代码中保留，但这次实际往返验收重点放在 performance 与 balanced，不能把没有单独执行的 power-saver 实机切换写成已验证结果。

## 构建和切换验证

构建过程中我也碰到过测试和新行为不一致：原测试假定 Intel performance profile 应把 EPP 文件写成 `performance`。补丁改为以 governor 实现性能档后，这些断言需要改成检查 governor；我还加了 performance 回 balanced 的断言，确认 `powersave` 与 balanced EPP 都回来。中间一轮测试又因为后续热降级用例仍假设当前 profile 是 performance 而失败，我把测试顺序补回对应状态后再完整运行。

最终 PPD 自带的测试套件为 **127 项通过、0 项失败**。然后安装本地包并实际走了 `balanced → performance → balanced`：

| 阶段 | `powerprofilesctl get` | 16 个 governor | 16 个 EPP |
| --- | --- | --- | --- |
| 切到 balanced | `balanced` | 全部 `powersave` | 全部 `balance_performance`（接 AC） |
| 切到 performance | `performance` | 全部 `performance` | 全部 `performance` |
| 再切回 balanced | `balanced` | 全部 `powersave` | 全部 `balance_performance`（接 AC） |

我在每次切换后都统计了 16 个 policy 的值，并查 PPD journal 的 `busy`、`failed`、`error` 和 `warning`。这轮检查没有匹配到错误。之后我又核对了一次本机的性能档状态：profile 是 `performance`，16 个 governor 全部为 `performance`，PPD 服务保持 active。

以下是以后复查时可以用的短命令：

```bash title="核对全部 policy 的 governor 与 EPP"
printf 'profile='; powerprofilesctl get
printf 'governors: '
for p in /sys/devices/system/cpu/cpufreq/policy*; do
  cat "$p/scaling_governor"
done | sort | uniq -c
printf 'EPPs: '
for p in /sys/devices/system/cpu/cpufreq/policy*; do
  cat "$p/energy_performance_preference"
done | sort | uniq -c

journalctl -u power-profiles-daemon --since '10 minutes ago' --no-pager \
  | grep -Ei 'busy|failed|error|warning'
```

最后一条 grep 没有匹配输出表示这个时间范围内没有这些关键词，不代表系统日志中永远没有错误；profile/EPP/governor 数量也只证明接口状态，不是跑分结果。

## 它修好模式切换，不会拆掉功耗墙

这台机器的热和功耗限制另有其因。我此前记录过空载 thermal zone 在约 66–73°C，以及 `package_throttle_count` 超过 16.7 万；这里把它们当作旧测量背景，不冒充本轮重新测量。本轮重点核对的是 PPD profile、16 个 governor/EPP 值和服务日志。

`performance` governor 表示选择 `intel_pstate` 的性能算法，不表示处理器永远运行在标称最高频率，更不保证持续维持 turbo。内核的可用 P-state 边界、固件功耗策略、散热和温度仍会限制实际频率。此前的热节流计数也不会因为这份软件补丁被清零或消失。这次没有做同负载、同温度下的 benchmark，所以我不能写“性能提升了多少”。

我也没有证据把问题归到某个 i7-1260P 批次。我们能确认的是这台机器的接口状态和这个版本的 PPD 代码路径；其他机型是否支持相同组合，要看它们的 CPU、固件、内核、驱动模式与平台 profile 暴露情况。

对我来说，这次的收获不是“把频率钉死”，而是设置里选性能后，PPD 确实把它映射到我想要的 governor；离开性能档时又先回到可写 EPP 的状态，再完成均衡切换。少一个抢写的常驻服务，状态也能被一组可重复的 sysfs 和 journal 命令核对。至于性能究竟快了多少，下一次要另做控制变量测试，不能拿 governor 名字当 benchmark。

> **AI 辅助声明**：本次排查、PPD 补丁实现、测试与系统切换由作者和 AI 协作完成；AI 协助整理命令、源码说明与文章初稿。环境状态、测试结果和切换输出来自本机实际核验；此前热节流读数明确标注为作者先前提供，未将其描述为本轮复测。


---

**作者：**xingwangzhe

**本文链接：**[https://xingwangzhe.fun/posts/ubuntu-intel-pstate-performance-governor/](https://xingwangzhe.fun/posts/ubuntu-intel-pstate-performance-governor/)

本文采用[知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议](https://creativecommons.org/licenses/by-nc-sa/4.0/)进行许可。