运行时电源管理

Xe PM 实现了系统级挂起状态和机会性运行时挂起状态的主要例程。

系统级挂起(S 状态)- 通常这是由 ACPI 驱动的操作系统发起的挂起,用于实现 S0ix(又名 S2idle、冻结)、S3(挂起到 RAM)、S4(挂起到磁盘)。这里的主要函数是 xe_pm_suspendxe_pm_resume。它们是挂起到这些状态和从这些状态恢复的主要入口点。

PCI 设备挂起(D 状态)- 这是机会性 PCIe 设备低功耗状态 D3,由 PCI 子系统和 ACPI 在 runtime_pm 基础设施的帮助下控制。PCI D3 很特殊,可以表示 D3hot,其中 Vcc 电源开启以保持内存活动并快速低延迟恢复;也可以表示 D3Cold,其中 Vcc 电源关闭以实现更好的节能。PCI 层级的 Vcc 控制只能在 PCI 根端口级别进行控制,而设备驱动程序可以位于多个桥接器/交换机之后,并与其他设备配对。因此,PCI 子系统无法执行向 D3Cold 的转换。PCI 子系统可能的最低运行时 PM 是 D3hot。然后,如果同一根端口中的所有这些配对设备都处于 D3hot 状态,ACPI 将在此处提供帮助并运行其自身的方法(_PR3 和 _OFF)以执行从 D3hot 到 D3cold 的转换。Xe 可能会通过在进入运行时挂起之前调用 pci_d3cold_disable(root_pdev) 来禁止这种转换。它将基于运行时条件,例如 VRAM 使用情况,以便实现快速和低延迟恢复。

运行时 PM - Linux 内核提供的此基础设施允许设备驱动程序指示何时可以运行时挂起,以便可以将设备置于 D3(如果支持),或允许更深的包睡眠状态(PC 状态),和/或其他低级功耗状态。Xe PM 组件提供 xe_pm_runtime_suspendxe_pm_runtime_resume 函数,PCI 子系统将在转换到/从运行时挂起之前调用这些函数。

此外,Xe PM 提供了 get 和 put 函数,Xe 驱动程序将使用这些函数来指示活动。为了避免与内存管理相关的锁定复杂性,在可能的情况下,这些 get 和 put 函数需要从更高/更外层的级别调用。需要从外部级别保护的主要情况是:IOCTL、sysfs、debugfs、dma-buf 共享、GPU 执行。

此组件不负责 GT 空闲 (RC6) 或 GT 频率管理 (RPS)。

内部 API

bool xe_rpm_reclaim_safe(const struct xe_device *xe)

是否可以从回收上下文执行运行时恢复

参数

const struct xe_device *xe

xe 设备。

返回

如果可以从回收上下文中安全地进行运行时恢复,则返回 true。否则返回 false。

int xe_pm_suspend(struct xe_device *xe)

系统挂起的助手,即 S0->S3 / S0->S2idle

参数

struct xe_device *xe

xe 设备实例

返回

成功返回 0

int xe_pm_resume(struct xe_device *xe)

系统恢复的助手 S3->S0 / S2idle->S0

参数

struct xe_device *xe

xe 设备实例

返回

成功返回 0

int xe_pm_init(struct xe_device *xe)

初始化 Xe 电源管理

参数

struct xe_device *xe

xe 设备实例

描述

此组件负责系统和设备睡眠状态。

成功返回 0,否则返回负错误代码。

void xe_pm_runtime_fini(struct xe_device *xe)

完成运行时 PM

参数

struct xe_device *xe

xe 设备实例

bool xe_pm_runtime_suspended(struct xe_device *xe)

检查 runtime_pm 状态是否挂起

参数

struct xe_device *xe

xe 设备实例

描述

这不能保证设备将保持挂起状态,因为它可能与运行时状态转换竞争。它只能用作不可靠的断言,以确保我们在尝试访问某些内存时不会处于睡眠状态。

如果 PCI 设备挂起,则返回 true,否则返回 false。

int xe_pm_runtime_suspend(struct xe_device *xe)

准备我们的设备以进入 D3hot/D3Cold

参数

struct xe_device *xe

xe 设备实例

描述

成功返回 0,否则返回负错误代码。

int xe_pm_runtime_resume(struct xe_device *xe)

从 D3hot/D3Cold 唤醒

参数

struct xe_device *xe

xe 设备实例

描述

成功返回 0,否则返回负错误代码。

void xe_pm_runtime_get(struct xe_device *xe)

获取 runtime_pm 引用并同步恢复

参数

struct xe_device *xe

xe 设备实例

void xe_pm_runtime_put(struct xe_device *xe)

将 runtime_pm 引用放回并标记为空闲

参数

struct xe_device *xe

xe 设备实例

int xe_pm_runtime_get_ioctl(struct xe_device *xe)

在 ioctl 之前获取 runtime_pm 引用

参数

struct xe_device *xe

xe 设备实例

返回

成功返回任何大于或等于 0 的数字,否则返回负错误代码。

bool xe_pm_runtime_get_if_active(struct xe_device *xe)

如果设备处于活动状态,则获取 runtime_pm 引用

参数

struct xe_device *xe

xe 设备实例

返回

如果设备已唤醒(无论之前的引用次数如何)并且已获取新引用,则返回 True,否则返回 false。

bool xe_pm_runtime_get_if_in_use(struct xe_device *xe)

如果设备处于活动状态且已获取之前的引用,则获取新引用

参数

struct xe_device *xe

xe 设备实例

返回

如果设备已唤醒,之前已获取引用,并且现在已获取新引用,则返回 True,否则返回 false。

void xe_pm_runtime_get_noresume(struct xe_device *xe)

在不恢复设备的情况下,增加运行时 PM 使用计数器。

参数

struct xe_device *xe

xe 设备实例

描述

此函数应在内部调用,这些内部调用已受到外部 xe_pm_runtime_get 调用者的保护。如果未受保护,则会发出警告。无论如何,此函数之后应放回引用,因为它始终会增加使用计数器。

bool xe_pm_runtime_resume_and_get(struct xe_device *xe)

恢复设备,然后在唤醒时获取 runtime_pm 引用。

参数

struct xe_device *xe

xe 设备实例

返回

如果设备已唤醒并且已获取引用,则返回 true,否则返回 false。

void xe_pm_assert_unbounded_bridge(struct xe_device *xe)

在无界 PCIe 父桥上禁用 PM。

参数

struct xe_device *xe

xe 设备实例

int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)

设置允许/阻止 D3Cold 的 VRAM 阈值。

参数

struct xe_device *xe

xe 设备实例

u32 threshold

D3cold 阈值的 VRAM 大小(以字节为单位)。

描述

成功返回 0,否则返回负错误代码。

void xe_pm_d3cold_allowed_toggle(struct xe_device *xe)

检查切换 d3cold.allowed 的条件。

参数

struct xe_device *xe

xe 设备实例

描述

在 runtime_pm 空闲回调期间调用。检查 runtime suspend 之前的所有 D3Cold 条件。

int xe_pm_module_init(void)

执行 xe_pm 特定模块的初始化。

参数

void

无参数。

返回

成功时返回 0。目前不会失败。