RFC-0272:唤醒源报告

RFC-0272:唤醒源报告
状态已接受
区域
  • 内核
说明

提出了 zx_system_suspend_enter 的扩展,以详细说明挂起操作最终终止的原因

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2025-05-23
审核日期(年-月-日)2025-06-24

摘要

一项提案,旨在扩展 zx_system_suspend_enter,以向用户模式提供系统调用返回的所有具体原因,包括刚刚退出挂起状态或从未进入挂起状态。

背景

作为进入低功耗状态的最后一步,在为低功耗状态配置平台专用驱动程序和组件后,用户模式目前可以通过调用 zx_system_suspend_enter 请求内核进入低功耗状态。然后,内核将执行所需的步骤来暂停调度并将 CPU 停驻在较低的功耗状态,直到以下两种情况之一发生:用户提供的截止期限到达,或系统的一个或多个“唤醒源”收到信号。

唤醒源

唤醒源是内核对象,可用于在处于适当信号状态时唤醒系统(或防止系统进入挂起状态)。目前,Zircon 内核定义的唯一唤醒源对象是使用 zx_interrupt_create 创建的物理中断对象,同时在 options 字段中传递 ZX_INTERRUPT_WAKE_VECTOR 标志。当与对象关联的硬件中断触发时,系统会向中断唤醒源发送信号,并且在它们被销毁或通过向对象发送新的异步等待操作或在对象上阻塞线程来明确确认之前,系统会一直向它们发送信号。

zx_system_suspend_enter 的当前行为。

zx_system_suspend_enter 目前接受 2 个参数。资源令牌和截止期限(在启动时间轴上指定)。请求内核进入暂停状态是一种特权操作,由对资源令牌的访问进行中介,该令牌必须是系统 CPU 资源。如果未传递有效的资源令牌,将导致错误,并且不会尝试进入暂停状态。

如果尝试使用已过的时限调用 zx_system_suspend_enter,系统会立即返回状态代码 ZX_ERR_TIMED_OUT。如果尝试调用 zx_system_suspend_enter,并指定未来的时限,并且任何唤醒源对象都已处于已发出信号的状态,则会立即返回状态代码 ZX_ERR_BAD_STATE。最后,尝试调用 zx_system_suspend_enter 并指定未来的截止期限,且没有发出信号的唤醒源,将开始挂起所有 CPU 的过程。在此过程开始期间或之后的任何时间,指定的截止期限到达或任何唤醒源发出信号都会导致 CPU 从暂停状态移出,并返回状态代码 ZX_OK

术语

  • 唤醒源:系统中的任何对象,当收到信号时,可以使系统从暂停状态恢复,或阻止系统进入暂停状态。

  • 截止期限唤醒源:一种仅存在于内核中的特殊唤醒源,可能是在用户为对 zx_system_suspend_enter 的调用提供截止期限时进入暂停状态的原因。

  • 唤醒源报告条目:特定唤醒源的相关信息,详细说明可能导致设备退出或无法进入休眠状态的活动。

  • 唤醒源报告:一组信息,包括标头和唤醒源报告条目数组,这些信息可能会从对 zx_system_suspend_enter 的调用返回,以告知用户退出或未能进入暂停状态的原因。

  • 唤醒报告/唤醒报告条目:唤醒源报告和唤醒源报告条目的简写形式。

问题陈述

目前,虽然截止期限或任何唤醒源都可以将内核踢出暂停状态,但用户模式无法确定暂停操作完成的具体原因。

这很有问题,尤其是在高度并发且异步的系统中,即使仅从调试/诊断角度来看也是如此。鉴于 Zircon 内核充当所有此类逻辑的中心点,并且始终知道系统从暂停状态释放的确切原因,因此它似乎应该在协助用户模式了解暂停状态被阻止或终止的原因方面发挥作用。

利益相关方

教员

  • jamesr@google.com

Reviewers:

  • eieio@google.com
  • fmil@google.com
  • jmatt@google.com

已咨询

  • maniscalco@google.com
  • surajmalhotra@google.com
  • jaeheon@google.com
  • mcgrathr@google.com

社交

我们在 2024 年底分发了一份初始文档,以阐明相关要求,并收到了反馈。后来,我们发布了一份更具体的 API 提案,并经过了多轮反馈,从而获得了各利益相关方的支持,最终成为了此 RFC 的基础。

要求

需求可分为两类。功能要求(用户模式需要什么)和实现要求(内核代码需要遵循的规则)。虽然本文档不介绍特定内核实现的详细信息,但列出内核要求非常重要,因为这有助于了解某些设计决策。

功能性

1) 每当内核从对 zx_system_suspend_enter 的调用返回时,都必须提供一种机制,以便调用方了解已发出信号且阻止系统进入挂起状态或最终触发挂起状态结束的每个唤醒源(包括截止日期唤醒源)。2) 必须通知 zx_system_suspend_enter 的用户模式调用方已发出信号的唤醒源,但在报告机制生成报告时已收到确认。换句话说,系统还必须报告唤醒源收到信号并在调用展开时收到确认这一事实 3) 存在未确认的唤醒源会阻止系统进入暂停状态。对于已确认的唤醒源,等待报告的唤醒源报告条目不会阻止系统进入暂停状态。

实现

1) 系统中每个唤醒源生成唤醒报告所需的内存开销必须是常量。换句话说,在报告之前多次发出信号并确认的唤醒源不得需要无限量的存储空间。相反,唤醒源报告的存储空间要求在逻辑上是在创建唤醒源时支付的,并且不会随着时间的推移而无限增长。2) 唤醒报告的生成可以使用互斥进行序列化,并需要 O(N) 时间,其中 N 是系统中的唤醒源数量。3) 生成唤醒报告不得使中断处理或唤醒源信号延迟超过 O(1) 次。4) 典型系统中的唤醒源总数预计在 10-20 个之间。如果遇到超过 100 个的系统,则会令人惊讶。

设计

概览

zx_system_suspend_enter 将扩展,以允许用户将一对缓冲区传递给内核,这些缓冲区可用于使用典型的输出参数模式向用户模式报告唤醒事件。内核将被修改为跟踪仍处于已发信状态或仍在等待报告(或两者兼有)的唤醒源。为了防止内存需求无限增长,唤醒源将跟踪以下内容:

  • 首次收到信号的时间。
  • 上次收到信号的时间。
  • 上次确认的时间(如果有)。
  • 信号的计数次数。

这样一来,唤醒源便可任意次数收到信号并确认,并且仍可进行报告,而无需任意数量的内存来存储各个信号事件。此外,内核还会跟踪哪些唤醒报告条目已报告,并在唤醒源收到信号、报告后再次报告且未先确认时,将此情况指示给用户模式。

API 更改

对内核 API 的更改包括定义几个结构体和标志,以及更改 zx_system_suspend_enter 系统调用的定义。

结构体和标志

#define ZX_SYSTEM_SUSPEND_OPTION_DISCARD      ((uint64_t)(1u << 0))
#define ZX_SYSTEM_SUSPEND_OPTION_REPORT_ONLY  ((uint64_t)(1u << 1))

typedef struct zx_wake_source_report_header {
  zx_instant_boot_t report_time;
  zx_instant_boot_t suspend_start_time;
  uint32_t total_wake_sources;
  uint32_t unreported_wake_report_entries;
} zx_wake_source_report_header_t;

#define ZX_SYSTEM_WAKE_REPORT_ENTRY_FLAG_SIGNALED            ((uint32_t)(1u << 0))
#define ZX_SYSTEM_WAKE_REPORT_ENTRY_FLAG_PREVIOUSLY_REPORTED ((uint32_t)(1u << 1))

typedef struct zx_wake_source_report_entry {
  zx_koid_t koid;
  char name[ZX_MAX_NAME_LEN];
  zx_instant_boot_t initial_signal_time;
  zx_instant_boot_t last_signal_time;
  zx_instant_boot_t last_ack_time;
  uint32_t signal_count;
  uint32_t flags;
} zx_wake_source_report_entry_t;

系统调用变更

zx_system_suspend_enter 的定义将从以下内容更改为:

zx_status_t zx_system_suspend_enter(zx_handle_t resource,
                                    zx_instant_boot_t resume_deadline);

收件人

zx_status_t zx_system_suspend_enter(zx_handle_t resource,
                                    zx_instant_boot_t resume_deadline,
                                    uint64_t options,
                                    zx_wake_source_report_header_t* out_header,
                                    zx_wake_source_report_entry_t* out_entries,
                                    uint32_t num_entries,
                                    uint32_t* actual_entries);

此外,状态代码报告行为也将发生变化。目前,如果在挂起操作开始时传递给调用的 resume_deadline 已过时,则返回 ZX_ERR_TIMED_OUT;但如果在系统挂起过程中或挂起完成后超出时限,则返回 ZX_OK。此外,如果在挂起操作开始时有任何已发出信号的唤醒源,则返回 ZX_ERR_BAD_STATE;如果在系统挂起过程中或系统完全挂起后有唤醒源发出信号,则返回 ZX_OK

今后,在所有情况下都会返回 ZX_OK。报告标题中会返回一个时间戳 (suspend_start_time),以告知用户实际开始暂停的时间(在所有参数检查都完成之后)。用户可以根据报告中是否存在内部截止期限唤醒源的唤醒事件来检测是否发生了超时,还可以通过将用户提供的截止期限值与 suspend_start_time 进行比较来确定截止期限是否已过。同样,用户可以通过检查来源的唤醒报告条目的 last_signaled_timelast_ack_time(如果已定义)并将其与返回的 suspend_start_time 进行比较,了解在暂停操作开始之前是否已向唤醒源发送信号。

请求报告

请求内核进入暂停状态时,用户可以通过 out_header 参数传递包含唤醒报告标头的缓冲区,请求生成唤醒报告。用户还可以传递一个缓冲区,以包含要由内核填充的一组唤醒源报告条目,但没有义务这样做;如果只需要标头,则只需传递标头缓冲区。

目前,您需要提供以下三个参数才能接收报告条目:

  • out_entries:指向条目存储空间的指针。
  • num_entries:一个数字,表示条目存储空间的大小。
  • actual_entries:指向缓冲区中实际填充的条目数的输出参数指针。

虽然传递包含唤醒报告条目的缓冲区是可选的,但传递不一致的参数进行此操作是非法的。换句话说,用户必须为 out_entriesactual_entries 传递有效的指针,并为 num_entries 传递非零值;或者,他们必须为 out_entriesactual_entries 传递 nullptr,并为 num_entries 传递零值。最后,虽然用户只能请求标头(通过传递非 null 的 out_headerout_entries, num_entries, actual_entries(nullptr, 0, nullptr)),但如果不传递 out_header 的有效指针,则不允许传递有效的参数来存储报告条目。如果未遵循这些规则,状态代码将为 ZX_ERR_INVALID_ARGS,系统不会尝试进入暂停状态,也不会生成报告。

当用户请求唤醒报告时,报告标题中会显示两个计数。首先,total_wake_sources 会报告系统中存在的唤醒源(包括内部截止期限唤醒源)的总数,无论这些唤醒源在报告生成时的状态如何。

当用户传递缓冲区来存储已报告的唤醒报告条目时,报告仅限于在用户缓冲区中报告最多 num_entries 个条目。报告的实际数量将存储在 actual_entries out 参数中。用户可以通过检查标头中的第二个计数器 unreported_wake_report_entries,了解是否还有其他事件仍在等待报告(由于用户缓冲区中没有足够的空间来存储事件)。

unreported_wake_report_entries 会报告在报告生成开始时需要报告但无法放入用户缓冲区而未报告的唤醒报告条目数量。您可以通过对 zx_system_suspend_enter 的后续调用检索这些条目(请参阅下文中的“在不暂停的情况下请求报告”)。

请注意,在报告生成后,系统可能会创建或销毁唤醒源,因为挂起调用会展开,这意味着在调用返回时,total_wake_sources 可能不再反映系统级唤醒源的确切计数。同样,唤醒源在展开期间也可能会收到信号(或重新收到信号),这会导致等待报告的唤醒报告条目数量超过 unreported_wake_report_entries 在进程中指示的数量。

在不暂停的情况下请求报告。

用户还可以通过在选项中传递 ZX_SYSTEM_SUSPEND_OPTION_REPORT_ONLY 标志,请求仅生成报告。传递此标志后,系统不会尝试暂停,并且标头中返回的 suspend_start_time 将为 ZX_TIME_INFINITE。此外,传递此标志时,用户至少需要传递一个缓冲区来存储报告标题。否则,系统会返回 ZX_ERR_INVALID_ARGS 错误。另请注意,即使只请求报告,中介系统 CPU 资源仍是必需的。

此标志的主要用途之一是支持以下情况:调用方可能为其事件缓冲区分配有限或固定的内存量,并且需要报告的事件数量超出了缓冲区空间。假设系统的缓冲区中只有 2 个事件的空间。它会调用挂起,并且在挂起调用展开时,10 个来源会收到信号并得到确认。系统会生成报告,并将 10 个事件中的 2 个返回给用户。为了耗尽剩余事件,用户需要多次回调挂起操作。没有任何主动发出信号的唤醒源来阻止系统进入暂停状态,因此用户过去只能通过延长截止期限来防止系统意外重新进入暂停状态。每次发生这种情况时,系统都会发出截止期限唤醒源信号并进行确认,最终可能会或可能不会重新报告(具体取决于事件的枚举顺序,未指定)。

在极端情况下,如果用户的缓冲区中只有一个事件的空间,他们可能甚至无法继续前进,因为截止日期来源的事件最终可能会被反复报告。

报告标题时间戳

报告标题将包含启动时间轴上的两个时间戳。report_time 是报告在系统调用展开并即将返回用户模式时实际生成的时间(在启动时间轴上)。suspend_start_time 表示系统调用提交到挂起操作的时间。如果唤醒事件表明某个来源上次发出信号的时间在该时间之后,或者表明某个来源上次发出信号的时间在该时间之前,但确认时间在该时间之后,则表示该来源必须在唤醒系统或阻止系统进入休眠状态方面发挥了一定作用。

如果 syscall 因任何原因生成报告,但完全不尝试进入暂停状态,则 suspend_start_time 将为 ZX_TIME_INFINITE

舍弃已确认的事件。

如果用户不想接收在调用 zx_system_suspend_enter 之前已收到信号但已确认的来源的唤醒报告条目,则可以在调用 zx_system_suspend_enter 时在 options 字段中传递 ZX_SYSTEM_SUSPEND_OPTION_DISCARD 位。在暂停操作开始时,如果某个唤醒源尚未报告,但目前未收到信号(例如已确认),则系统会舍弃该唤醒源的所有唤醒报告条目,就像该唤醒源已报告一样。

请注意,舍弃条目不会将当前已发出信号(无论之前是否已确认)的来源的条目标记为“已报告”。发出信号的来源将阻止系统进入挂起状态,并且即使来源在尝试进入挂起状态后但在生成报告之前收到确认,系统也会将其报告给用户(如果有足够的空间)。

在正常运行过程中,在系统尝试挂起之前,某些唤醒源可能会多次收到信号并确认。选择在操作开始时舍弃这些事件可能会有助于减少需要报告的事件数量,但这并非强制性要求。

报告的每次唤醒事件信息。

向用户报告的每个唤醒事件都将包含以下字段:

  • koid - 这是配置为唤醒源的内核对象的 KOID,该对象已收到信号。作为 KOID,它可在系统生命周期内唯一标识特定对象。
  • name - 一个 ZX_MAX_NAME_LEN 字符数组,其中包含一个直观易懂的字符串,用于协助调试。名称的具体格式未指定,生产逻辑绝不应使用该名称。它仅用于内部开发和调试。由于 Zircon 中断对象目前无法重命名,因此中断对象的名称将由系统自动生成。
  • initial_signal_time - 启动时间轴上,此唤醒源首次收到信号的时间。如果来源在报告之前被确认并重新发送信号多次,initial_signal_time 将保持不变,并记录首次发送信号事件的时间。
  • last_signal_time - 在启动时间轴上,此唤醒源在报告之前收到信号的最新时间。如果在报告之前,系统多次确认并重新发送了来源信号,则每次都会更新 last_signal_time,始终记录最近一次发送唤醒源信号的时间。
  • last_ack_time - 启动时间轴上最近一次确认此唤醒源的时间。如果来源在报告之前从未确认,则此值将为 ZX_TIME_INFINITE。如果唤醒源被多次发出信号并确认,然后在报告之前再发出一次信号,则 last_ack_time 可能会小于 last_signal_time,但始终大于或等于 initial_signal_time
  • signal_count - 包含唤醒源在初始信号时间和最后信号时间之间收到信号的次数。signal_count 始终至少为 1,如果 signal_count 恰好为 1,则初始信号时间和最后信号时间将具有相同的值。
  • flags - 包含两个当前定义的标志的组合。

    • ZX_SYSTEM_WAKE_REPORT_ENTRY_FLAG_SIGNALED - 表示在包含此条目的唤醒报告生成时,此唤醒报告条目的唤醒来源仍在发出信号(尚未确认)。
    • ZX_SYSTEM_WAKE_REPORT_ENTRY_FLAG_PREVIOUSLY_REPORTED - 表示此唤醒报告条目已出现在之前的报告中。请注意,您无法看到之前报告过但目前未发出信号的条目。如需加入等待报告的一组唤醒报告条目,必须对唤醒信号进行信号传递;一旦唤醒报告条目的唤醒源同时获得确认(清除已发出信号的位)和报告(设置已报告的位),便会从该组中移除。

报告截止期限唤醒源。

日后,如果使用 resume_deadline 调用 zx_system_suspend_enter,并且系统进入暂停状态,但仅由截止期限计时器唤醒,系统会以特殊唤醒报告条目的形式向用户报告这一情况。此条目的 koid 字段将包含值 ZX_KOID_KERNEL。内核会自动确认此唤醒源;无需执行任何特殊的用户模式操作即可管理截止期限唤醒源。

销毁唤醒源。

当由用户模式创建的唤醒源被销毁时,系统会隐式确认该唤醒源,因此该唤醒源无法阻止系统进入挂起状态。此外,如果有待报告的唤醒源唤醒报告条目,系统会立即将其从待报告的唤醒报告条目集中移除。

测试

唤醒报告生成测试将在核心测试环境中使用单元测试进行。这些单元测试只能作为核心测试可靠地运行,因为如果存在以物理中断形式的平台专用唤醒源,则可能会导致报告生成结果不可确定。

除了在核心测试环境中运行之外,我们还需要添加一项内容来简化测试;即可由测试代码发出信号并确认的非平台专用唤醒源。实体中断不符合这些要求。系统中是否存在物理中断是平台专用细节,我们无法依赖于任意平台存在的任何特定集。此外,物理中断对象不是可由用户模式强制触发的内容。它们只能由关联的硬件触发。

由于无法使用物理中断,并且目前系统中未定义任何其他类型的唤醒源(除了截止期限唤醒源的特殊情况),因此我们计划引入一种专门用于测试的新类型唤醒源。

虚拟中断唤醒源。

除了物理中断对象之外,Zircon 还支持“虚拟”中断对象。虚拟中断对象会参与与物理中断相同的特殊情况信号传递,通常用于以下情况:当一个驱动程序拥有中断块,而其他几个不相关的驱动程序使用该块中的中断时,需要解复中断块以维护进程隔离。目前,配置为中断的 GPIO 块是最常见的这种情况,但不一定是唯一的情况(例如,USB 中断也可能会使用这些对象)。

与实体中断不同,虚拟中断只能由用户模式代码以编程方式触发(通过调用 zx_interrupt_trigger)。它们的创建方式与实体中断 (zx_interrupt_create) 相同,但目前不需要有效的系统 IRQ 资源句柄即可创建(实体中断需要),并且系统会明确禁止将其创建为唤醒源。

今后,我们将更改这些限制。具体而言,用户将被允许创建虚拟中断对象作为唤醒源,但前提是他们提供对系统 IRQ 资源的有效句柄。换句话说,创建虚拟中断唤醒源将被视为由控制创建物理中断对象能力的同一系统资源中介的特权操作。无唤醒源虚拟中断将继续可构建,无需任何特殊权限。

这样,您就可以在核心测试环境中编写并运行一整套确定性单元测试

性能

对性能的影响预计会很轻微。在极少数情况下,报告在唤醒源收到信号的同时生成,导致导致唤醒源收到信号的中断需要与锁争用,但报告生成绝不会将锁保持 O(N) 的时间,只会保持足够长的时间来评估各个关联的唤醒报告条目的状态,并将内容复制到本地缓冲区,然后再释放锁并尝试复制到用户提供的缓冲区。

报告生成本身(必然)需要 O(N) 时间,在此期间,系统中无法创建或销毁新的唤醒源。这预计不会导致任何重大性能问题,因为预计大多数唤醒源将在系统初始化期间创建,并在系统生命周期内存在。

向后兼容性

此方法会直接修改现有的系统调用,因此从 ABI 角度来看,它不向后兼容。不过,要修改的系统调用目前是 @next 的成员,并且仍处于开发阶段,这意味着不需要使用显式废弃周期来处理任何外部依赖项。

代码库中的现有调用站点可能会被修改为将 0, nullptr, nullptr, 0, nullptr 作为调用的默认值传递,这将保留系统的当前行为(返回的状态代码行为除外)。唤醒报告条目将在内部累积,但不会产生巨大的开销。

安全注意事项

预计不会有重大安全问题。虚拟唤醒源中断的引入由与实体唤醒源中断创建相同的资源令牌进行中介。此外,对 zx_system_suspend_enter 的所有调用都已通过访问系统 CPU 令牌进行中介,因此系统会自动通过相同的令牌生成唤醒源报告。

隐私注意事项

在暂停系统或报告系统从暂停状态恢复的原因时,不会涉及任何个人身份信息 (PII),因此没有任何已知的隐私问题。如果知道唤醒源的触发时间和确认时间被视为“私密”信息,用户可以放心,因为生成报告的能力是通过资源令牌中介的特权操作。

文档

目前,zx_system_suspend_enter 是一个处于开发阶段的 API,位于 @next 下。因此,不存在正式的公开文档。短期内,唤醒源报告的内部用户将能够使用内部设计文档、此 RFC 和单元测试作为指定行为和使用示例的参考。

在 Zircon 对进入/退出暂停状态和报告特定唤醒原因的支持稳定下来后,我们将编写该子系统最终形式的正式公开文档。假设此唤醒源报告机制在该时间点仍然存在,预计将编写文档来反映此 RFC 中阐明的规则,以及在此期间所做的任何更改。

考虑的替代方案

计时器唤醒源

除了中断之外,能够创建也配置为唤醒源的 Zircon 计时器对象也非常有用。用户可以在启动时间轴上安排截止期限,当其计时器对象收到信号时,唤醒源将被视为收到信号,并保持这种状态,直到计时器在未来通过取消或重新调度得到确认。

目前,出于一些原因,我们决定不这样做。 1) 唤醒源是强大的对象,可能会阻止系统进入挂起状态,因此很有可能被滥用。与中断不同,目前无需提供任何显式 capability 即可创建计时器,这意味着无法立即将计时器唤醒源的构建视为由以句柄形式提供的 capability 中介的一种特权操作。2) zx_system_suspend_enter 调用已支持截止期限。如果用户模式需要支持可使系统从暂停状态恢复的任意数量的计时器,则可以在具有调用 zx_system_suspend_enter 功能的组件级别实现简单的计时器队列。这还将对任何所需功能模型的控制完全交给了用户模式中的电源管理子系统。3) 最后,我们可以稍后再回来执行此操作。我们需要编写新的 RFC 来解决如何协调唤醒源计时器的创建问题,但这里提供的唤醒报告条目报告结构应该足以报告由计时器触发的唤醒源,就像报告中断一样。

基于联合或 TLV 的唤醒报告条目。

唤醒报告条目的建议结构目前是固定的。假设系统中存在许多不同类型的唤醒源,每种唤醒源都有一组非常不同的重要详细信息,那么我们可以想象一个世界,其中需要为系统中的不同类型的唤醒源报告一组不重叠的信息。

在这样的环境中,唤醒报告条目对象会是什么样的?一种可能的方法是将结构定义为具有类型枚举和各种不重叠数据集的联合。本质上,是 std::variant 的 C ABI 版本。虽然这样做是可行的,但会很不方便。目前,系统中只有一种可由用户构建的唤醒源,因此无需使用联合体。

如果我们想为未来的(未知)唤醒源类型做好准备,则需要将联合体扩展到尽可能大的大小(也未知),以便在最终添加新的唤醒报告条目类型时,希望能使联合体的大小保持不变。但当那一天到来时,我们可能没有预留足够的空间,并且无论如何都不得不升级接口,而在此之前,预留的空间只会被浪费。

同样,我们可以采用类型-长度-值 (TLV) 方法来编码唤醒报告条目。这种方法无需猜测“编码唤醒事件的可能最大大小”,但会引入使用可变长度对象源的 kernel ABI,从而复杂化了序列化报告所需的 kernel 代码和处理报告所需的用户模式代码。

归根结底,当前的固定唤醒报告条目定义既适用于现有用例(中断唤醒报告条目),也适用于唯一确定的未来潜在用例(计时器唤醒源),因此目前没有强有力的理由采用更复杂的方法来使事情变得复杂。

其他用户模式信息。

根据用户模式计划如何使用报告的唤醒报告条目,允许用户模式将二进制 blob(固定最大大小)与唤醒源相关联可能很有帮助,然后在报告生成期间在唤醒报告条目中报告该 blob。这样,用户模式就可以通过唤醒源对象将任意记账“隧道化”到报告的唤醒报告条目中。

虽然这项功能可能很有用,但使用唤醒报告功能的现有客户表示他们不需要这样做。报告的 KOID 已足够;它可以用作唯一键,可在必要时用于查找用户模式记账信息。

不这样做还意味着,我们不必担心设计用于控制此类信息的功能模型,也不必担心恶意行为者通过唤醒源报告访问私密会计信息所带来的潜在安全风险。

报告已销毁唤醒源的唤醒事件。

如前所述,销毁唤醒源后,等待报告的任何关联唤醒报告条目信息都会立即销毁,并且永远不会报告。我们是否应该坚持报告已销毁的唤醒源的唤醒报告条目?

虽然所提行为意味着在技术上可能会无法向用户模式报告唤醒报告条目,但在典型用例场景中,这预计不会造成任何严重问题。目前,唤醒源始终是系统启动期间分配的早期中断,并且在整个系统的生命周期内有效,这意味着它们不会在正常运行期间被销毁。选择立即移除所有等待报告的唤醒报告条目是一种简单的方法,可确保如果系统中某些内容开始:

创建唤醒源 + 向其发送信号。 + 销毁它。 + 永久重复。

今后,如果引入了在常规操作期间经常创建和销毁的新类型唤醒源,并且可能会丢失已销毁源的唤醒报告条目信息,则可以重新考虑此决定。