RFC-0252:无物理 VMO CacheOps

RFC-0252:无物理 VMO CacheOps
状态已接受
领域
  • 内核
说明

移除对物理 VMO 的缓存操作。

Gerrit 更改
作者
审核人
提交日期(年-月-日)2024-06-12
审核日期(年-月-日)2024-07-18

摘要

移除了直接在物理 VMO 上执行缓存操作的功能。

设计初衷

目前,物理 VMO 上的缓存操作无法可靠地运行,因为它们依赖于 物理贴图。鉴于物理 VMO 只能通过映射进行操作,它们 可以始终改用现有的 zx_cache_flush 操作。

物理 VMO 通常代表物理地址空间的非 RAM 区域, 例如 MMIO 寄存器。执行缓存操作是无意义的,或者 而最严重的是会导致严重错误,具体取决于架构和硬件。虽然 已经需要受限资源来创建物理 VMO,从而最大限度地减少 让用户使内核崩溃的方法仍然是一件好事

利益相关方

教员

cpu@google.com

审核者

mcgrathr@google.com、hansens@google.com、jbauman@google.com

已咨询

社交化

在 Zircon 内核/虚拟机团队中讨论。

设计

由于 zx_cache_flush 已存在并已实现,因此没有什么新内容 创建提案时因此,该方案只是 支持在物理 VMO 上执行以下操作,即 zx_vmo_create_physical:

  • ZX_VMO_OP_CACHE_SYNC
  • ZX_VMO_OP_CACHE_INVALIDATE
  • ZX_VMO_OP_CACHE_CLEAN
  • ZX_VMO_OP_CACHE_CLEAN_INVALIDATE

对非物理 VMO 执行这些操作,即通过 zx_vmo_create 创建的操作。 “zx_vmo_create_contiguous”、“zx_vmo_create_child”或“zx_pager_create_vmo”将会 保持不变,其行为与之前相同。

这会导致物理 VMO 和分页 VMO 之间的 API 不同, 因为代码可能需要容忍给出两种类型的调用。不过, 物理 VMO 并不常用, VMO 目前不可行,需要支持任意一种 VMO 的代码将 必须确保有可用的映射

实现

在树中,物理 VMO 缓存操作的用法不多,因为大多数 需要缓存操作的位置已在使用首选 zx_cache_flush.在目前使用的 VMO 缓存操作中,始终存在 可以改为用于 zx_cache_flush 的现有映射,从而 迁移可谓无所不包。

实施计划如下所示:

  1. 迁移与物理 VMO 相关的所有现有 VMO 缓存操作使用情况。
  2. 对物理 VMO 停用缓存操作并返回它们 ZX_ERR_NOT_SUPPORTED.

性能

使用 zx_cache_flush 执行缓存操作应比使用 执行系统调用,所以这项更改通常应该是一种净性能, 改进。对此有一个例外情况,那就是需要映射的 但物理 VMO 并不常用,也没有这样的情况 存在。日后如果需求发生变化,可以重新做出此决定。

工效学设计

目前的大多数缓存操作均已通过 zx_cache_flush 执行 更轻松、更方便的使用,并且从人体工学设计 始终优于 VMO 操作。不过 如果尚不存在映射

向后兼容性

这是一项 API 破坏性更改,不过缓存操作由 一类用户,通常是驾驶员和类似用户,甚至更少的用户 因此,对现有代码而言,迁移 VMO 应该不会太困难。

安全注意事项

此方案不仅从内核中移除了代码和逻辑,还会导致用户 避免在潜在的设备内存发生时 在特权模式下运行因此,它是中性的到略有正面的, 安全性的角度。

缺点、替代方案和未知问题

此方案假定用户在物理系统上执行缓存操作 VMO 符合以下任一情况:

  • 已经有映射并切换到执行缓存操作 从而保证性能,不会有任何负面影响
  • 没有映射,但可以在非性能关键型中创建映射 初始化部分。
  • 没有映射,对性能不要求, 临时映射以执行缓存操作。

用户可能会执行以下操作:

  • 没有映射。
  • 没有非性能关键型初始化点,即映射 错误。
  • 在执行缓存操作时对性能至关重要。

在针对现有用户和不受支持的潜在用户做出这些假设后, 我们可以看看完全删除缓存操作的一些替代方案。

针对所有 VMO 移除

移除所有 VMO 的缓存操作将提供统一的 API, 防止了在之前提供物理 VMO 的情况下,代码可能会失败的情况 它只有预期的分页 VMO。

不幸的是,在常见的模式中,可能会为某个服务或驱动程序提供 VMO,无需在固定并传递到 底层硬件。在这种情况下,客户端写入的数据可能需要 通过缓存操作清理到内存中的资源不过,在将 VMO 固定到 其底层页面可能会被内核更改, 清理不足。由于只有驱动程序(而不是客户端)可以固定内存, 表示驱动程序在固定后必须执行缓存操作。要求 在这种情况下,进行映射将给驱动程序带来不必要的开销。

物理 VMO 的单独内核映射

内核无需依赖于物理映射,而是可以创建单独的映射, 并对此映射执行缓存操作。

这确实解决了 physmap 使用方面的直接问题,并解除了所有相关内核的阻止 更改,并确保在没有 映射不受影响。

其缺点是:

  • 需要分配额外的页面表才能在其中映射,这会造成浪费 内存。物理 VMO 可能是 范围非常大
  • 增加内核复杂性,并继续允许用户执行缓存 可能使内核故障的无效范围上的操作。

临时内核映射

对页面表执行临时存储 映射仅在缓存操作代码路径中。不过,这种做法几乎没什么好处 执行临时映射的用户之上,因此实际上并不会 改进原始提案。