动态热功耗管理框架

在嵌入式领域,SoC 的复杂性导致需要监控和缓解的热点数量不断增加,以便防止温度超过规范和法律规定的“皮肤温度”。

另一个方面是在给定的功耗预算下维持性能,例如虚拟现实,如果当一个大的 CPU 在处理其他事情时性能受到限制,用户会感到头晕。或者减少电池充电,因为与其他设备消耗的功率相比,耗散的功率太高。

用户空间是最适合通过限制不同设备的功率来根据应用程序配置文件动态操作这些设备的地方:它了解平台的知识。

动态热功耗管理 (DTPM) 是一种通过限制和/或平衡不同设备之间的功耗预算来作用于设备功耗的技术。

DTPM 框架提供了一个统一的接口来作用于设备功耗。

概述

DTPM 框架依赖于 powercap 框架在 sysfs 目录中创建 powercap 条目,并实现后端驱动程序以进行与电源可管理设备的连接。

DTPM 是一种树状表示,描述了设备之间共享的功率约束,而不是它们的物理位置。

树的节点是一个虚拟描述,它聚合了子节点的功率特性及其功率限制。

树的叶子是真正的功率可管理设备。

例如

SoC
 |
 `-- pkg
      |
      |-- pd0 (cpu0-3)
      |
      `-- pd1 (cpu4-5)

pkg 功率将是 pd0 和 pd1 功率数值的总和

SoC (400mW - 3100mW)
 |
 `-- pkg (400mW - 3100mW)
      |
      |-- pd0 (100mW - 700mW)
      |
      `-- pd1 (300mW - 2400mW)

当节点插入到树中时,它们的功率特性会传播到父节点

SoC (600mW - 5900mW)
 |
 |-- pkg (400mW - 3100mW)
 |    |
 |    |-- pd0 (100mW - 700mW)
 |    |
 |    `-- pd1 (300mW - 2400mW)
 |
 `-- pd2 (200mW - 2800mW)

每个节点都有一个以 2^10 为基数的权重,反映了兄弟节点之间功率消耗的百分比

SoC (w=1024)
 |
 |-- pkg (w=538)
 |    |
 |    |-- pd0 (w=231)
 |    |
 |    `-- pd1 (w=794)
 |
 `-- pd2 (w=486)

 Note the sum of weights at the same level are equal to 1024.

当对节点应用功率限制时,它会根据子节点的权重在子节点之间分配。例如,如果我们在“SoC”根节点上设置 3200mW 的功率限制,则生成的树将是

SoC (w=1024) <--- power_limit = 3200mW
 |
 |-- pkg (w=538) --> power_limit = 1681mW
 |    |
 |    |-- pd0 (w=231) --> power_limit = 378mW
 |    |
 |    `-- pd1 (w=794) --> power_limit = 1303mW
 |
 `-- pd2 (w=486) --> power_limit = 1519mW

平面描述

创建一个根节点,它是所有节点的父节点。此描述是最简单的,它应该为用户空间提供所有支持功率限制的设备的平面表示,而无需任何功率限制分配。

分层描述

支持功率限制的不同设备以分层方式表示。有一个根节点,所有中间节点都将子节点分组,这些子节点也可以是中间节点或真实设备。

中间节点聚合功率信息并允许根据节点的权重设置功率限制。

用户空间 API

如概述中所述,DTPM 框架建立在 powercap 框架之上。因此 sysfs 接口是相同的,有关更多详细信息,请参阅 powercap 文档。

  • power_uw: 瞬时功耗。如果节点是中间节点,则功耗将是所有子节点功耗的总和。

  • max_power_range_uw: 最大功率减去最小功率得到的功率范围。

  • name: 节点的名称。这取决于实现。即使不建议用户空间这样做,多个节点也可以具有相同的名称。

  • constraint_X_name: 约束的名称。

  • constraint_X_max_power_uw: 可应用于节点的最大功率限制。

  • constraint_X_power_limit_uw: 要应用于节点的功率限制。如果设置了 constraint_X_max_power_uw 中包含的值,则将删除约束。

  • constraint_X_time_window_us: 此文件的含义将取决于约束编号。

约束

  • 约束 0:功率限制立即应用,没有时间限制。

内核 API

概述

DTPM 框架没有功率限制后端支持。它是通用的,并提供了一组 API,允许不同的驱动程序实现功率限制的后端部分并创建功率约束树。

由平台提供初始化函数来分配和链接树的不同节点。

一个特殊的宏的作用是通过描述结构声明一个节点和相应的初始化函数。此结构包含一个可选的父字段,允许在启动时将不同的设备挂接到已存在的树上。

例如

struct dtpm_descr my_descr = {
        .name = "my_name",
        .init = my_init_func,
};

DTPM_DECLARE(my_descr);

DTPM 树的节点用 dtpm 结构描述。添加新的可功率限制设备的步骤分三个步骤完成

  • 分配 dtpm 节点

  • 设置 dtpm 节点的功率数值

  • 注册 dtpm 节点

dtpm 节点的注册通过 powercap ops 完成。基本上,它必须实现回调函数来获取和设置功率和限制。

或者,如果要插入的节点是一个中间节点,则可以使用一个简单的函数将其作为未来的父节点插入。

如果设备的功率特性发生变化,则必须使用新的功率数值和权重更新树。

命名法

  • dtpm_alloc() : 分配和初始化 dtpm 结构

  • dtpm_register() : 将 dtpm 节点添加到树中

  • dtpm_unregister() : 从树中删除 dtpm 节点

  • dtpm_update_power() : 更新 dtpm 节点的功率特性