| 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
审核者:
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 中的额外支持,但需要单独的动机,这超出了范围,可以在后续提案中根据需要进行。