RFC-0203:引入了 `zx_system_energy_info`

RFC-0203:引入了 `zx_system_energy_info`
状态已接受
区域
  • 内核
  • 电源
说明

用于与内核通信以访问能耗信息的接口。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2022-11-18
审核日期(年-月-日)2022-12-15

摘要

此 RFC 提出了一种机制,通过该机制,用户空间代理可以与内核交互,以访问支持运行平均功率限制 (RAPL) 接口的平台上的一组电源域的能耗信息。

设计初衷

对于并非永久连接到电源的笔记本电脑,能效和能耗是关键的设计要素。X86 RAPL 是现代 X86 CPU 上的一个接口,它通过使用硬件性能计数器和 I/O 模型,准确估算一组电源域的能耗。如果我们有某种机制可以在内核之外访问能耗信息,那么我们就可以构建面向开发者的工具和车队跟踪工具,以符合人体工程学的方式检查设备的运行时功耗,这有助于在开发期间优化功耗,并识别整个车队的功耗回归。

设计

背景

Intel x86 RAPL MSR

在 RAPL 中,平台分为多个网域,以便生成精细的报告和控制。RAPL 网域是具有实际意义的电源管理网域。 平台中可用的具体 RAPL 域因处理器系列/型号而异,包括:

  • PSys:整个 SoC。
  • 封装:处理器芯片(所有核心、集成显卡、缓存、内存控制器)。
  • 电源平面 PP0:所有处理器核心和专用缓存。
  • 电源平面 PP1:非核心中特定设备的电源平面,通常是集成 GPU。
  • 内存:连接到集成内存控制器的 DRAM。

RAPL 接口由非架构 MSR 组成。每个 RAPL 网域都支持以下功能集,其中一些是可选的,如下所述:

  • Power Limit:用于指定功率限制、时间窗口、锁定位、钳制位等的 MSR 接口。
  • Energy Status:提供能耗信息的功率计量接口。
  • Perf Status(可选):用于提供有关因功率限制而导致的性能影响(回归)的信息的接口。它是一种时长指标,用于衡量相应网域中的功率限制效应。时长的含义因领域而异。
  • Power Info(可选):提供有关给定网域的参数范围、最小功率、最大功率等信息。
  • Policy(可选):4 位优先级信息,用于提示硬件在父网域中的子网域之间分配预算。

上述每项功能都需要使用特定单位来描述。单位在只读 MSR_RAPL_POWER_UNIT MSR 中公开。系统会为每个单位提供缩放比例,以便在有限的位数内呈现有意义的信息。

用于存储不同能耗信息的 MSR 是只读 Energy Status MSR:

  • MSR_PLATFORM_ENERGY_STATUS (0x0000064d)
  • MSR_PKG_ENERGY_STATUS (0x00000611)
  • MSR_DRAM_ENERGY_STATUS (0x00000619)
  • MSR_PP0_ENERGY_STATUS (0x00000639)
  • MSR_PP1_ENERGY_STATUS (0x00000641)

上述 MSR 的能耗单位由 MSR_RAPL_POWER_UNITEnergy Status Units 字段指定。

Energy Status MSR 仅支持有限范围的处理器系列/型号。访问非架构 MSR 且在不支持该 MSR 的处理器上执行的代码会生成异常。以下是支持每种 MSR 的处理器型号(非详尽列表):

MSR_PLATFORM_ENERGY_STATUS 适用于以下处理器:

  • Skylake,系列:6,型号:0x4e、0x5e
  • Kaby Lake,系列:6,型号:0x8e、0x9e
  • Cannon Lake,系列:6,型号:0x66

MSR_PKG_ENERGY_STATUS 适用于以下处理器:

  • Sandy Bridge,系列:6,型号:0x2a、0x2d
  • Ivy Bridge,系列:6,型号:0x3a、0x3e
  • Haswell,系列:6,型号:0x3c、0x3f、0x45、0x46
  • Broadwell,系列:6,型号:0x3d、0x47、0x56、0x4f
  • Skylake,系列:6,型号:0x4e、0x5e
  • Kaby Lake,系列:6,型号:0x8e、0x9e
  • Skylake X/SP,系列:6,型号:0x55
  • Cannon Lake,系列:6,型号:0x66
  • Ice Lake-SP,系列:6,型号:0x6a

MSR_DRAM_ENERGY_STATUS 适用于以下处理器:

  • Haswell,系列:6,型号:0x3c、0x3f、0x45、0x46
  • Broadwell,系列:6,型号:0x3d、0x47、0x56、0x4f
  • Skylake,系列:6,型号:0x4e、0x5e
  • Kaby Lake,系列:6,型号:0x8e、0x9e
  • Skylake X/SP,系列:6,型号:0x55
  • Cannon Lake,系列:6,型号:0x66
  • Ice Lake-SP,系列:6,型号:0x6a

MSR_PP0_ENERGY_STATUS 适用于以下处理器:

  • Sandy Bridge,系列:6,型号:0x2a、0x2d
  • Ivy Bridge,系列:6,型号:0x3a、0x3e
  • Haswell,系列:6,型号:0x3c、0x3f、0x45、0x46
  • Broadwell,系列:6,型号:0x3d、0x47、0x56、0x4f
  • Skylake,系列:6,型号:0x4e、0x5e
  • Kaby Lake,系列:6,型号:0x8e、0x9e
  • Skylake X/SP,系列:6,型号:0x55
  • Cannon Lake,系列:6,型号:0x66
  • Ice Lake-SP,系列:6,型号:0x6a

MSR_PP1_ENERGY_STATUS 适用于以下处理器:

  • Skylake,系列:6,型号:0x4e、0x5e
  • Kaby Lake,系列:6,型号:0x8e、0x9e
  • Cannon Lake,系列:6,型号:0x66

AMD x86 RAPL MSR

近期的 AMD 处理器支持与 Intel RAPL MSR 半兼容的 MSR 接口。支持的 RAPL MSR 具有相同的内容,但 MSR 编号不同。具体而言,AMD Zen(系列:0x17、0x19)处理器支持以下 Energy Status MSR:

  • MSR_AMD_CORE_ENERGY_STATUS (0xc001029a)

    • 相当于 Power Plane PP0 网域的 Intel MSR_PP0_ENERGY_STATUS
  • MSR_AMD_PKG_ENERGY_STATUS (0xc001029b)

    • 相当于 Package 网域的 Intel MSR_PKG_ENERGY_STATUS

系统调用:zx_system_energy_info

签名

此系统调用允许用户空间代理访问存储在指定电源域的 RAPL MSR 中的能耗信息:

zx_status_t zx_system_energy_info(
    zx_handle_t resource,
    uint32_t domain,
    uint64_t* energy_uj
);

其参数如下:

resource:向此调用授予权限的资源。必须为 ZX_RSRC_SYSTEM_ENERGY_INFO_BASE,即专门为此 API 引入的新资源,否则调用将失败。

domain:相应调用所引用的 RAPL 网域。它接受以下任一值来指定 RAPL 网域:

  • ZX_ENERGY_X64_PLATFORM_DOMAIN
  • ZX_ENERGY_X64_PKG_DOMAIN
  • ZX_ENERGY_X64_DRAM_DOMAIN
  • ZX_ENERGY_X64_PP0_DOMAIN
  • ZX_ENERGY_X64_PP1_DOMAIN

上述网域将在提案实施后定义。网域决定写入 energy_uj 的内容,如下所述。

energy_uj:如果调用成功,则返回时 energy_uj 包含以 uj 为单位的能耗值。能耗值由指定网域的 Energy Status MSR 中存储的值以及 MSR_RAPL_POWER_UNITEnergy Status Units 字段中存储的单位确定。如果调用失败,则其值未指定。

错误情况

ZX_ERR_NOT_SUPPORTED

  • 处理器不是受支持的 x86-64 处理器

  • 处理器是受支持的 x86-64 处理器,但指定网域的 Energy Status MSR 在此处理器上不可用。

  • 处理器是受支持的 x86-64 处理器,并且指定网域的 Energy Status MSR 在此处理器上可用,但读取操作未启用。

ZX_ERR_BAD_HANDLE

  • 资源不是有效的句柄。

ZX_ERR_WRONG_TYPE

  • 资源不是有效的资源句柄,或者不是 ZX_RSRC_KIND_SYSTEM 类型。

ZX_ERR_INVALID_ARGS

  • domain 不是以下值之一:

    • ZX_ENERGY_X64_PLATFORM_DOMAIN
    • ZX_ENERGY_X64_PKG_DOMAIN
    • ZX_ENERGY_X64_DRAM_DOMAIN
    • ZX_ENERGY_X64_PP0_DOMAIN
    • ZX_ENERGY_X64_PP1_DOMAIN
  • energy_uj 是无效的指针。

ZX_ERR_OUT_OF_RANGE

  • 资源类型为 ZX_RSRC_KIND_SYSTEM,但不等于 ZX_RSRC_SYSTEM_ENERGY_INFO_BASE

实现

内核

必须实现新的系统调用,并由新的资源 ZX_RSRC_SYSTEM_ENERGY_INFO_BASE 进行门控。 Fuchsia 内核已具有使用 CPUID 查询制造商 ID 和处理器签名/ID 的 API。DisplayFamily 和 DisplayModel 已映射到各种 x86 处理器的处理器 ID,可用于确定 MSR 的可用性。

组件管理器

必须定义新的协议 EnergyInfoResource,并且必须由组件管理器实现该协议,以提供 ZX_RSRC_SYSTEM_ENERGY_INFO_BASE 资源。这遵循了用于控制系统调用的资源的现有模式。

性能

对性能没有已知的影响。由于新系统调用仅触及少量数据,因此执行时间可以忽略不计。

安全注意事项

系统调用由新的资源句柄 ZX_RSRC_SYSTEM_ENERGY_INFO_BASE 控制。此保护措施可解决恶意干扰内核的问题。

隐私注意事项

此提案对隐私权没有有意义的影响。

测试

  • 可以添加单元测试来验证返回的 energy_uj 是否已从 MSR 中存储的值正确转换。

文档

Zircon 系统调用文档将更新,以包含新的 API。

缺点、替代方案和未知因素

我们考虑过使用更通用的接口,例如 zx_get_msr 系统调用,该调用可用于分派其他有用的 MSR 功能。不过,非架构 MSR 访问需要受处理器上可用性的限制。更通用接口的要求和范围目前很大程度上是猜测。 最终,我们选择了一个窄接口,以确保实现起来相当简单,并且未来对提议的接口进行更改的成本相对较低。

在先技术和参考资料

使用 cmd ZX_SYSTEM_POWERCTL_X86_SET_PKG_PL1 调用的 zx_system_powerctl 系统调用通过 RAPL Power LimitPower Info MSR 来操纵 CPU 功率级别。用于验证此系统调用的资源具有资源种类 ZX_RSRC_KIND_SYSTEM,基本资源为 ZX_RSRC_SYSTEM_POWER_BASE