动态热功耗管理框架

在嵌入式领域,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 节点的功率特性