PM 服务质量接口¶
此接口为驱动程序、子系统和用户空间应用程序在其中一个参数上注册性能期望提供内核和用户模式接口。
- 有两种不同的 PM QoS 框架可用
CPU 延迟 QoS。
每个设备的 PM QoS 框架提供了管理每个设备的延迟约束和 PM QoS 标志的 API。
PM QoS 框架中使用的延迟单位是微秒(usec)。
1. PM QoS 框架¶
维护一个全局 CPU 延迟 QoS 请求列表以及一个聚合(有效)目标值。 聚合目标值会随着请求列表或列表元素的变化而更新。 对于 CPU 延迟 QoS,聚合目标值只是列表中元素中保存的请求值的最小值。
注意:聚合目标值被实现为一个原子变量,因此读取聚合值不需要任何锁定机制。
从内核空间使用此接口很简单
- void cpu_latency_qos_add_request(handle, target_value)
将带有目标值的元素插入到 CPU 延迟 QoS 列表中。 在此列表更改后,将重新计算新目标,并且仅当目标值现在不同时才调用任何已注册的通知器。 PM QoS 的客户端需要保存返回的句柄,以便将来在其他 PM QoS API 函数中使用。
- void cpu_latency_qos_update_request(handle, new_target_value)
将使用新目标值更新句柄指向的列表元素,并重新计算新的聚合目标,如果目标已更改,则调用通知树。
- void cpu_latency_qos_remove_request(handle)
将删除该元素。 删除后,它将更新聚合目标,如果删除请求导致目标更改,则调用通知树。
- int cpu_latency_qos_limit()
返回 CPU 延迟 QoS 的聚合值。
- int cpu_latency_qos_request_active(handle)
返回请求是否仍处于活动状态,即是否已从 CPU 延迟 QoS 列表中删除。
- int cpu_latency_qos_add_notifier(notifier)
将通知回调函数添加到 CPU 延迟 QoS。 当 CPU 延迟 QoS 的聚合值更改时,将调用回调。
- int cpu_latency_qos_remove_notifier(notifier)
从 CPU 延迟 QoS 中删除通知回调函数。
从用户空间
该基础设施为 CPU 延迟 QoS 公开一个设备节点,/dev/cpu_dma_latency。
只有进程可以注册 PM QoS 请求。 为了提供进程的自动清理,该接口要求进程按如下方式注册其参数请求。
要注册 CPU 延迟 QoS 的默认 PM QoS 目标,该进程必须打开 /dev/cpu_dma_latency。
只要该设备节点保持打开状态,该进程就对该参数注册了一个请求。
要更改请求的目标值,该进程需要将 s32 值写入打开的设备节点。 或者,它可以写入十六进制字符串作为值,使用 10 个字符长的格式,例如“0x12345678”。 这会转换为 cpu_latency_qos_update_request() 调用。
要删除用户模式对目标值的请求,只需关闭设备节点即可。
2. PM QoS 每个设备的延迟和标志框架¶
对于每个设备,有三个 PM QoS 请求列表。 其中两个列表与恢复延迟和活动状态延迟容差(以微秒为单位)的聚合目标一起维护,第三个列表用于 PM QoS 标志。 值会响应请求列表的更改而更新。
恢复延迟和活动状态延迟容差的目标值只是参数列表元素中保存的请求值的最小值。 PM QoS 标志聚合值是所有列表元素的按位或(bitwise OR)。 当前定义了一个设备 PM QoS 标志:PM_QOS_FLAG_NO_POWER_OFF。
注意:聚合目标值是以这样一种方式实现的,即读取聚合值不需要任何锁定机制。
从内核模式使用此接口如下
- int dev_pm_qos_add_request(device, handle, type, value)
将带有目标值的元素插入到该标识设备的列表中。 在此列表更改后,将重新计算新目标,并且仅当目标值现在不同时才调用任何已注册的通知器。 dev_pm_qos 的客户端需要保存句柄,以便将来在其他 dev_pm_qos API 函数中使用。
- int dev_pm_qos_update_request(handle, new_value)
将使用新目标值更新句柄指向的列表元素,并重新计算新的聚合目标,如果目标已更改,则调用通知树。
- int dev_pm_qos_remove_request(handle)
将删除该元素。 删除后,它将更新聚合目标,如果删除请求导致目标更改,则调用通知树。
- s32 dev_pm_qos_read_value(device, type)
返回给定设备的约束列表的聚合值。
- enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
根据给定的标志掩码检查给定设备的 PM QoS 标志。 返回值的含义如下
- PM_QOS_FLAGS_ALL
设置了掩码中的所有标志
- PM_QOS_FLAGS_SOME
设置了掩码中的一些标志
- PM_QOS_FLAGS_NONE
未设置掩码中的任何标志
- PM_QOS_FLAGS_UNDEFINED
设备的 PM QoS 结构尚未初始化或请求列表为空。
- int dev_pm_qos_add_ancestor_request(dev, handle, type, value)
为给定设备的第一个直接祖先添加 PM QoS 请求,该祖先的 power.ignore_children 标志未设置(对于 DEV_PM_QOS_RESUME_LATENCY 请求)或其 power.set_latency_tolerance 回调指针不为 NULL(对于 DEV_PM_QOS_LATENCY_TOLERANCE 请求)。
- int dev_pm_qos_expose_latency_limit(device, value)
将请求添加到设备的恢复延迟约束的 PM QoS 列表中,并在设备的 power 目录下创建一个 sysfs 属性 pm_qos_resume_latency_us,允许用户空间操作该请求。
- void dev_pm_qos_hide_latency_limit(device)
从设备的恢复延迟约束的 PM QoS 列表中删除 dev_pm_qos_expose_latency_limit() 添加的请求,并从设备的 power 目录中删除 sysfs 属性 pm_qos_resume_latency_us。
- int dev_pm_qos_expose_flags(device, value)
将请求添加到设备的标志的 PM QoS 列表中,并在设备的 power 目录下创建一个 sysfs 属性 pm_qos_no_power_off,允许用户空间更改 PM_QOS_FLAG_NO_POWER_OFF 标志的值。
- void dev_pm_qos_hide_flags(device)
从设备的标志的 PM QoS 列表中删除 dev_pm_qos_expose_flags() 添加的请求,并从设备的 power 目录中删除 sysfs 属性 pm_qos_no_power_off。
通知机制
每个设备的 PM QoS 框架都有一个每个设备的通知树。
- int dev_pm_qos_add_notifier(device, notifier, type)
为特定请求类型的设备添加通知回调函数。
当设备约束列表的聚合值更改时,将调用回调。
- int dev_pm_qos_remove_notifier(device, notifier, type)
删除设备的通知回调函数。
活动状态延迟容差¶
此设备 PM QoS 类型用于支持硬件可能会即时切换到节能运行模式的系统。 在这些系统中,如果硬件选择的运行模式试图以过于激进的方式节省能量,可能会导致软件看到过多的延迟,从而导致软件错过某些协议要求或目标帧或采样率等。
如果软件可以使用给定设备的延迟容差控制机制,则应填充该设备的 dev_pm_info 结构中的 .set_latency_tolerance 回调。 它指向的例程应该实现将有效需求值传输到硬件所需的任何操作。
每当设备的有效延迟容差更改时,将执行其 .set_latency_tolerance() 回调,并且有效值将传递给它。 如果该值为负数,则表示设备的延迟容差需求列表为空,则如果可用,则回调应将底层硬件延迟容差控制机制切换到自主模式。 反过来,如果该值是 PM_QOS_LATENCY_ANY,并且硬件支持特殊的“无需求”设置,则回调应使用它。 这允许软件阻止硬件自动更新设备的延迟容差以响应其电源状态更改(例如,在从 D3cold 到 D0 的转换期间),这通常可以在自主延迟容差控制模式下完成。
如果设备存在 .set_latency_tolerance(),则 sysfs 属性 pm_qos_latency_tolerance_us 将存在于设备的 power 目录中。 然后,用户空间可以使用该属性来指定其对设备的延迟容差要求(如果有)。 向其写入“any”表示“无需求,但不要让硬件控制延迟容差”,而向其写入“auto”允许在设备的列表中没有来自内核端的其他需求时将硬件切换到自主模式。
内核代码可以使用上述函数以及 DEV_PM_QOS_LATENCY_TOLERANCE 设备 PM QoS 类型来添加、删除和更新设备的延迟容差要求。