RFC-0245:VMO 预提取 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 用于预提取 VMO 中数据以准备读取访问的操作。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2024-03-19 |
审核日期(年-月-日) | 2024-04-09 |
摘要
拥有 ZX_VMO_OP_COMMIT
的只读类似项,用于填充 VMO 以进行即时读取访问。
设计初衷
现有的 COMMIT 操作 ZX_VMO_OP_COMMIT
和 ZX_VMAR_OP_COMMIT
是面向用户的性能工具。借助这些标记,用户可以指明要使用 VMO 或 VMAR 的范围,并允许内核更高效地批量分配所有页面,从而避免日后需要处理许多故障。
由于 COMMIT 旨在模拟写入,因此目前存在两个缺点。首先,它需要对 VMAR 和/或 VMO 拥有写入权限,如果是某些可执行数据,则可能没有此权限。其次,它会主动执行写时复制并分配页面,如果该范围日后只会被读取,则这两项操作都是不必要的,并且会浪费内存。
目前,Starnix 受到了第一个缺点的影响,该缺点源自其使用由只读分页器支持的 VMO。PREFETCH 操作可以解决这两个缺点,同时保留 COMMIT 的预期优势。
利益相关方
教员:
cpu@google.com
Reviewers:
adamperry@google.com、dworsham@google.com
咨询了:
rashaeqbal@google.com
社交:
此功能是 Starnix 团队和虚拟内存团队之间讨论的结果。
要求
应将 PREFETCH 操作添加到 VMO(作为 ZX_VMO_OP_PREFETCH
)和 VMAR(作为 ZX_VMAR_OP_PREFETCH
)。这些操作应仅需要对其各自的句柄拥有读取权限,并且应执行必要的工作,以便日后执行的读取操作的工作量降到最低。因此,预提取可能:
- 请求用户分页器中范围内的所有缺失页面
- 解压缩该范围内的所有页面
- 对于 VMAR,为范围内的所有页面创建硬件页表
设计和实现
内核虚拟机内部已经拥有支持此功能的大多数工具,实现方式主要是布置新的 API 标志。因此,这可以通过一个或两个小型 CL(如果 VMO 和 VMAR 实现分开)来实现,包括任何相关测试和文档等。
性能
这项更改不应影响任何现有功能的性能,我们将通过现有基准进行验证。
安全注意事项
预提取在逻辑上等同于用户在整个范围内执行手动读取。除了需要 READ 权限(而非 WRITE 权限)之外,其余要求和限制与 COMMIT 完全相同,因此这里没有新的安全注意事项。
测试
我们将在核心测试套件中添加测试,以验证系统是否支持 PREFETCH 操作并正确触发用户分页器请求。
由于这些系统在性能方面有意向于对用户保持高度透明,因此很难从用户空间测试其他方面,例如 PREFETCH 触发的解压缩。由于基于性能的单元测试本身就不可靠(尤其是由于模拟器执行),因此我们将尽可能使用内核单元测试来测试这些行为。
替代方案
更改 COMMIT 以模拟读取
可以更改现有 COMMIT 操作的语义,以模拟读取,而不是引入 PREFETCH 操作。虽然这对于 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
中提供额外支持的可能性,但需要单独的动机,这超出了本文档的范围,可在需要时在后续提案中进行。