RFC-0236:VMO 快照修改克隆 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 我们的目标是引入一个新的 VMO 子类型,它支持截取快照,以捕获基于分页器的 VMO 中任何已修改的页面。 |
问题 | |
Gerrit 更改 | |
作者 | |
审核人 | |
提交日期(年-月-日) | 2023-07-20 |
审核日期(年-月-日) | 2023-12-12 |
摘要
目标是引入一种新的 VMO 子类型,支持快照 从由分页器支持的 VMO 的子级中修改的任何页面获取。
设计初衷
内核目前支持两种类型的 VMO 克隆(也称为子 VMO): 真实快照,其中 VMO 在克隆后均看不到彼此的更改 写入快照时创建快照, 可以在操作完成后看到父 VMO 上的更改,但 子文件上已被写入的网页。
可以在 VMO 克隆上重复克隆操作,从而创建一个 子级 VMO 的层次结构。为了便于实现,Zircon 内核不支持 允许混合层次结构;您可以创建真实快照的层次结构 写入时快照 VMO 的层次结构。
随着 Starnix 的发明,Fachsia 必须有效支持 fork()。 创建分支需要将父进程的整个地址空间克隆到 子进程,其中包括匿名内存,以及分页器支持的数据和 代码 VMO
由于内核仅支持匿名快照的真实快照, 而对于分页器支持的 VMO,它仅支持写入时快照克隆。 因此,通过克隆无法满足 fork() 协定:因此强制 Starnix 实现即时复制和/或其他 CPU 和内存密集型解决方法。
利益相关方
谁对是否接受此 RFC 有影响?(此部分为可选内容, encouraged.)
csuter@google.com、jamesr@google.com
教员:
davemoore@google.com
审核者:
rashaeqbal@google.com、jamesr@google.com
已咨询:
列出应审查 RFC 但无需批准的人员。
csuter@google.com、adanis@google.com、cpu@google.com、mvanotti@google.com、 lindkvist@google.com
社交化:
与 Zircon 团队和一些 Starnix 与利益相关方分享了一项正在进行的工作,以进行基准化分析。
要求
- 有效支持克隆同时具有分页器支持的 VMO 的地址空间 和匿名 VMO
- 在进程无法访问 VMO 后,应该不会浪费内存 (最后一个句柄关闭)父 VMO 或子 VMO,换言之, 以下两种情况:
vmo = create_vmo();
loop {
child = create_snapshot_modified(vmo)
child.write(...)
vmo = child // old vmo is dropped
}
vmo = create_vmo();
loop {
vmo.write(...)
child = create_snapshot_modified(vmo)
// child is dropped
}
设计
ZX_VMO_CHILD_SNAPSHOT_MODIFIED
是一种新型 VMO 克隆,允许
创建快照修改的子类型。
此标志会创建一个子级,该子级会保留所有 由分页器支持的 VMO 的子级修改。从语义上讲,这就好像是 在父级中不受寻呼机支持的任何网页上执行复制。中的网页 由分页器支持的父级将至少具有写入时复制 注入到克隆中。这与原始快照语义不同 其行为就像在 VMO 中的所有页面上都创建了即时副本一样。
首次在由分页器支持的 VMO 上使用时,语义的行为如同
不过使用了 SNAPSHOT_AT_LEAST_ON_WRITE
。已创建克隆的句柄
它最初与父级相同,但您可以在
这使得克隆存在分歧
当针对任何匿名 VMO 使用时,SNAPSHOT_MODIFIED
克隆将
升级为具有快照语义,类似于现有的克隆类型升级
由 SNAPSHOT_AT_LEAST_ON_WRITE
使用的语义定义。
此标志不适用于使用固定区域、切片或 VMO 克隆 VMO
继承自 zx_vmo_create_physical()
或 zx_vmo_create_contiguous()
。
病例数量
在由分页器支持的 VMO 上通过快照修改
为由分页器支持的 VMO 创建单个 SNAPSHOT_MODIFIED
克隆将行为
就像创建了一个 SNAPSHOT_AT_LEAST_ON_WRITE
克隆一样。当前时间
执行克隆时,新的 VMO 将与父 VMO 相同。
在克隆上执行另一个 SNAPSHOT_MODIFIED
之前,它仍然可以
。克隆中任何未经修改的页面都至少设置有写入时复制。
语义信息。
快照修改于写入至少写入时或快照修改后
由分页器支持的 VMO 的
由于 SNAPSHOT_MODIFIED
和 SNAPSHOT_AT_LEAST_ON_WRITE
的行为相同
在分页器支持的 VMO 上,这两种情况都是在克隆上调用 SNAPSHOT_MODIFIED
将产生相同的语义。任何
再由分页器支持的网页的快照,
租用“写入时复制”语义。
在快照创建之后修改快照
在这种情况下,语义将升级为快照,类似于 snapshot-at-least-on-write.
不支持的案例
目前不支持以下情况,并且如果 SNAPSHOT_MODIFIED
尝试进行克隆,将返回 ZX_ERR_NOT_SUPPORTED
。
写入快照时快照修改的快照链尾
根据快照修改的脚本可以展开,以便在 写入时快照链中的快照。这可能会造成令人困惑的结果,不过, 克隆的 VMO 中的未分支页面可以看到整个过程中的修改 单向 VMO 链,最接近的亲属链 阅读。这会与声明的最初 promise 的不一致 可以为任何修改过的网页创建快照。
通过快照修改了写入时至少快照链的中间位置
基于快照的修改永远不能用于有子级的 VMO(即 位于写入时至少快照链的中间),因为这可能会导致不一致 层次结构。
术语
zx_vmo_create_child()
中克隆类型标志的现有命名惯例
旨在以一种可描述所提供的语义的方式命名标志。当前
此标志的名称为 SNAPSHOT_MODIFIED
,因为它总结了
克隆中修改后的页面是快照。类似的选项是
SNAPSHOT_MODIFICATIONS
。其他一些考虑的标志是 SNAPSHOT_MIXED
它确实描述了相关语义,
SNAPSHOT_PAGER_MODIFICATIONS
是另一个考虑因素,但并不理想
将 VMO 与分页器相结合
实现
快照修改会影响 Zircon 中的一些文件,但可以细分为 在 选项标志添加到系统调用。
将添加一些内核内测试,以验证新 结构,并且将包含更复杂的核心测试 添加选项标记。
性能
在大多数情况下,新添加的代码仅在创建新的
快照修改的克隆,使现有代码的性能超出预期
更改。但有一种例外情况,那就是在创建 SNAPSHOT_AT_LEAST_ON_WRITE
时
即这种简单方法包括额外获取 VMO 锁定,
如果这会带来性能下降,那么重构
请克隆选择代码以避免这种情况。
安全注意事项
基于快照的修改在构建时不太可能引入任何漏洞 使用现有的 Zircon 基元,并且未引入任何新功能。
测试
内核单元测试和核心测试将包含在相关 CL 中。
文档
我们将发布一份面向 Zircon 开发者的详细设计文档。它 将概述新的数据结构、支持和不支持的情况、更改 包括代码、挑战和替代方案。
系统将向 zx_vmo_create_child()
中添加一个新标志,该标志的
说明:
ZX_VMO_CHILD_SNAPSHOT_MODIFIED
- 创建一个行为类似于
Eager 复制在父级中的任何页面执行,这些页面不受寻呼机支持,即
由分页器支持的 VMO 的子级修改过的网页。由分页器支持
页面至少具有写入时复制语义。此标志不可用于
使用 zx_vmo_create_physical()、zx_vmo_create_contiguous()、VMO 创建的 VMO
包含固定的页面,或者此类 VMO 的后代。此标志也不
使用 SNAPSHOT_AT_LEAST_ON_WRITE
创建且具有
非切片子项,或者不是分页器支持的 VMO 的子项。
缺点、替代方案和未知问题
为分页器支持的 VMO 创建快照语义非常重要, 现有的 Zircon VMO 基元。用户寻呼机通过服务页面来运行 向单个 VMO 发出多个请求,目前其子项构成单个 具有写入时复制语义的单向链。
可用于匿名 VMO 的快照标志会创建一个隐藏的 VmCowPages(目标 VMO 及其新快照的共同祖先实体)。如 因为没有指向隐藏的 VmCowPages 的内容, 则它是不可变的。这个隐藏的 VmCowPage 会保留 目标 VMO,则子项中的修改具有写入时复制语义。 因此,搜索此层次结构中的页面涉及遍历树 且以隐藏的根结尾。
现有快照数据结构很难 分页器,因为根 VMO 始终会隐藏起来,并且带有原始 VMO 就会成为左边孩子。如果分页器仍指向原始 VMO (它现在具有隐藏的父项),则必须在 直到隐藏的根,以便应其子项的请求提供页面。这个 页面添加到未被操作的节点时会导致不一致 。
最简单的解决方案是创建一个混合层次结构,其中根为 可见且具有一个隐藏子项,该子项充当快照的隐藏根 树。
您可以通过多种方式向用户描述所提供的语义。通过 中的描述概述了提供的与 换言之,还有一种取景方式,即修改和克隆 页面。示例如下:
“此标志将创建一个子级,并保留所有修改过的页面的快照 来自父级的如果根 vmo 在 快照修改后的子级将会看到更改。这个 与原始快照语义不同,原始快照语义的行为类似于 已创建副本。”
此说明是正确的,但需要对 请注意,此行为需要使用分页器,因为标记将升级为 快照语义(在匿名 VMO 上使用)。
SNAPSHOT_MODIFIED 可以替换 SNAPSHOT_AT_LEAST_ON_WRITE 吗?
逐步淘汰快照-at-least-on-write 并取代它可能非常重要。 快照修改为两个克隆类型的语义不同, 可能导致意外行为尽管这两种克隆类型都至少提供 写入时复制”快照修改可以同时包含快照和 同一 VMO 内写入时写入最少的页面数。此外,这项变更 需要进行性能测试当 VMO 有分页器支持时, 在创建每个克隆时,快照会分配更少的内存, 没有创建隐藏的共同祖先实体。因此,迁移 在某些使用中, snapshot-at-least-on-write 可能会导致性能下降 案例
有必要研究替换 SNAPSHOT_AT_LEAST_ON_WRITE
,
不过,因为它会简化 zx_vmo_create_child()
的 API,就像大多数情况下一样
fdio 帮助程序会承诺与 SNAPSHOT_MODIFIED
兼容的语义。