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 中删除通知回调函数。
从用户空间
该基础架构公开了一个设备节点 /dev/cpu_dma_latency,用于 CPU 延迟 QoS。
只有进程可以注册 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 标志的聚合值是所有列表元素值的收集(按位 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 列表,并在设备的电源目录下创建一个 sysfs 属性 pm_qos_resume_latency_us,允许用户空间操作该请求。
- void dev_pm_qos_hide_latency_limit(device)
从设备的恢复延迟约束的 PM QoS 列表中删除由 dev_pm_qos_expose_latency_limit() 添加的请求,并从设备的电源目录中删除 sysfs 属性 pm_qos_resume_latency_us。
- int dev_pm_qos_expose_flags(device, value)
将请求添加到设备的标志的 PM QoS 列表,并在设备的电源目录下创建一个 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() 添加的请求,并从设备的电源目录中删除 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 将出现在设备的电源目录中。然后,用户空间可以使用该属性来指定其对设备的延迟容忍度要求(如果有)。写入“any”表示“无要求,但不要让硬件控制延迟容忍度”,写入“auto”允许硬件切换到自主模式,如果设备的列表中没有来自内核端的其他要求。
内核代码可以使用上面描述的函数以及 DEV_PM_QOS_LATENCY_TOLERANCE 设备 PM QoS 类型来添加、删除和更新设备的延迟容忍度要求。