RFC-0245:VMO 预提取

RFC-0245:VMO 预取
状态已接受
区域
  • 内核
说明

在 VMO 中预提取数据以准备读取访问的操作。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2024-03-19
审核日期(年-月-日)2024-04-09

摘要

具有 ZX_VMO_OP_COMMIT 的只读模拟,用于填充即将进行的读取访问的 VMO。

设计初衷

现有的 COMMIT 操作(ZX_VMO_OP_COMMITZX_VMAR_OP_COMMIT)是面向用户的性能工具。它们允许用户指明 VMO 或 VMAR 的哪些范围将要使用,并允许内核更高效地批量分配所有页面,从而避免将来需要处理许多错误。

目前,由于 COMMIT 的目的是模拟写入,因此存在两个缺点。 首先,它需要对 VMAR 和/或 VMO 具有写入权限,但如果这是针对某些可执行数据,则可能没有这些权限。其次,它会主动执行写入时复制并分配页面,如果该范围将来仅用于读取,则这是不必要的,并且会浪费内存。

目前,Starnix 受到了第一个缺点的影响,该缺点源于其对只读分页器支持的 VMO 的使用。PREFETCH 操作可解决上述两个缺点,同时保留 COMMIT 的预期优势。

利益相关方

辅导员

cpu@google.com

审核者

adamperry@google.com, dworsham@google.com

已咨询

rashaeqbal@google.com

共同化

此功能是通过 Starnix 团队和虚拟内存团队之间的讨论而实现的。

要求

应向 VMO(如 ZX_VMO_OP_PREFETCH)和 VMAR(如 ZX_VMAR_OP_PREFETCH)添加预取操作。这些操作应仅需要对各自句柄的 READ 权限,并且应执行必要的工作,以便将来的读取操作只需执行最少的工作。因此,PREFETCH 可能会:

  • 从范围内的用户分页器请求任何缺失的页面
  • 解压缩范围内的所有网页
  • 对于 VMAR,为范围内的任何页面创建硬件页表

设计和实现

内核虚拟机内部已经具备支持此功能的大部分工具,而实现过程在很大程度上是管道化新的 API 标志。因此,这可以在一个或两个(如果 VMO 和 VMAR 实现分开)小型 CL 中实现,包括任何相关测试和文档等。

性能

此更改不应影响任何现有功能的性能,可通过现有基准进行验证。

安全注意事项

从逻辑上讲,预取相当于用户在整个范围内执行手动读取。除了需要 READ 权限而不是 WRITE 权限之外,其余要求和限制与 COMMIT 完全相同,因此这里没有新的安全注意事项。

测试

将向核心测试套件添加测试,以验证是否支持预取操作并正确触发用户寻呼器请求。

由于这些系统有意对用户保持高度透明(性能方面除外),因此很难从用户空间测试其他方面,例如预取触发的解压缩。由于基于性能的单元测试本身就不稳定,尤其是在模拟器执行时,因此将尽可能使用内核单元测试来测试这些行为。

替代方案

更改了 COMMIT 以模拟读取

与其引入 PREFETCH 操作,不如更改现有 COMMIT 操作的语义,以模拟读取。虽然这对于 Starnix 使用情形来说已足够,但其他现有用户确实希望进行写入模拟并主动分配页面,以避免在未来的写入中出现故障和分配。

继续使用 ALWAYS_NEED

Starnix 目前通过使用 ALWAYS_NEED 操作来解决缺少 PREFETCH 操作的问题。ALWAYS_NEED 执行与 PREFETCH 相同的初始操作,即引入任何缺少的页面并进行解压缩等。与 PREFETCH 不同的是,它还额外声明,应尽可能不回收此内存。这会导致系统内存压力增大,并可能会增加出现 OOM 或用户体验下降的可能性。

其他 zx_vmar_map 选项

除了支持 VMAR 操作之外,还可以在创建映射时通过额外的选项(例如 ZX_VM_MAP_RANGE_PREFETCH)支持预取。 这是一种优化,可避免在创建映射后需要发出 PREFETCH 操作。

目前尚不清楚是否需要避免额外的系统调用,此 RFC 也不希望排除 zx_vmar_map 中的额外支持,但需要单独的动机,这超出了范围,可以在后续提案中根据需要进行。