zx_pager_op_range

摘要

对分页器拥有的一系列 VMO 执行操作。

声明

#include <zircon/syscalls.h>

zx_status_t zx_pager_op_range(zx_handle_t pager,
                              uint32_t op,
                              zx_handle_t pager_vmo,
                              uint64_t offset,
                              uint64_t length,
                              uint64_t data);

说明

pager_vmo 上 [offsetoffset + length)。pager_vmo 必须是之前由 pager 创建的 zx_pager_create_vmo()offsetlength 必须页面对齐。data 是可选的 参数(如果指定的 op 支持此参数)。

可以执行的操作,即 op 可以采用的值:

ZX_PAGER_OP_DIRTY - 用户空间分页器想要转换 [offset, offset + length)从干净到脏。这将解除所有正在等待的写入操作 针对指定范围的 ZX_PAGER_VMO_DIRTY 个页面请求。

ZX_PAGER_OP_FAIL - 用户空间分页器未能满足对 pager_vmo 中 使用 ZX_PAGER_VMO_READZX_PAGER_VMO_DIRTY 命令时,将范围 [offset]、offset + 长度 [offset] 设为长度)。 data 包含遇到的错误(zx_status_t 错误代码符号扩展为 uint64_t 值)- 允许的值包括 ZX_ERR_IOZX_ERR_IO_DATA_INTEGRITYZX_ERR_BAD_STATE ZX_ERR_NO_SPACEZX_ERR_BUFFER_TOO_SMALL

这将指示可能正在等待该范围内的页面请求的线程,从而解除对它们的阻塞。如果 被屏蔽的线程正在通过 zx_vmo_read() / zx_vmo_write()zx_vmo_op_range() 使用 ZX_VMO_OP_COMMIT,调用将失败并显示错误状态(数据) 返回的值。如果被屏蔽的线程正在通过 VMAR 映射请求页面,该线程将会 发生严重的页面错误异常。

ZX_PAGER_OP_WRITEBACK_BEGIN - 用户空间分页器想要开始回写该范围内的页面 [offsetoffset + length)。这表示想要清理指定 范围(通过 ZX_PAGER_OP_WRITEBACK_END 发出信号)。请参阅 请参阅下面的示例代码,了解建议的用法。

data 可以选择性地设置为 ZX_VMO_DIRTY_RANGE_IS_ZERO,以表明调用方想要 将指定范围写回为 0。此字段适用于调用方处理 由 zx_pager_query_dirty_ranges() 返回的范围,其 options 设置为 ZX_VMO_DIRTY_RANGE_IS_ZERO。它可确保在该范围内创建的任何非零内容 在查询之后、开始回写之前,如果错误地假定 并将其标记为干净(因此可逐出)。

ZX_PAGER_OP_WRITEBACK_END - 用户空间分页器完成了对该范围内的页面写回 [offsetoffset + length)。这表示指定范围内的所有脏页 之前带有 ZX_PAGER_OP_WRITEBACK_BEGIN 信号的 API 可以标记为“安全”。请参阅 请参阅下面的示例代码,了解建议的用法。

内核可以随意逐出已标记为干净的任何页面或零个范围,之后 如果需要,用户空间分页器需要再次提供这些值。这也意味着 应注意避免任何正在投放中的过时用品, 刚刚撰写的内容。

用于发现和清理脏页的示例代码(模数错误处理)可能如下所示: 这个。

  zx_vmo_dirty_range_t ranges[kMaxRanges];
  uint64_t num_ranges;

  zx_status_t st =
      zx_pager_query_dirty_ranges(pager, vmo, 0, vmo_size, &ranges[0],
                                  kMaxRanges * sizeof(zx_vmo_dirty_range_t), &num_ranges, nullptr);

  for (uint64_t i = 0; i < num_ranges; i++) {
    uint64_t start = ranges[i].offset;
    uint64_t len = ranges[i].length;
    st = zx_pager_op_range(pager, ZX_PAGER_OP_WRITEBACK_BEGIN, vmo, start, len, 0);
    WritebackToDisk(vmo, start, len);
    st = zx_pager_op_range(pager, ZX_PAGER_OP_WRITEBACK_END, vmo, start, len, 0);
  }

权限

pager 的类型必须为 ZX_OBJ_TYPE_PAGER 且包含 ZX_RIGHT_MANAGE_VMO

pager_vmo 的类型必须为 ZX_OBJ_TYPE_VMO 且包含 ZX_RIGHT_WRITE

返回值

zx_pager_op_range() 在成功时返回 ZX_OK,或者在失败时返回以下某个错误代码。

错误

ZX_ERR_BAD_HANDLE pagerpager_vmo 不是有效的句柄。

ZX_ERR_WRONG_TYPE pager 不是分页器句柄,或 pager_vmo 不是 VMO 句柄。

ZX_ERR_ACCESS_DENIED 分页器不含 ZX_RIGHT_MANAGE_VMOpager_vmo 不含 ZX_RIGHT_WRITE

ZX_ERR_INVALID_ARGS: - pager_vmo 不是通过 pager 创建的 VMO。 - offsetlength 未页面对齐。 - opZX_PAGER_OP_FAILdata 不是 ZX_ERR_IOZX_ERR_IO_DATA_INTEGRITY 其中之一 或 ZX_ERR_BAD_STATE。 - opZX_PAGER_OP_WRITEBACK_BEGINdata 不是 0 或 ZX_VMO_DIRTY_RANGE_IS_ZERO

ZX_ERR_OUT_OF_RANGEpager_vmo 中指定的范围无效。

pager_vmo 中的指定范围不支持 ZX_ERR_NOT_SUPPORTED op

ZX_ERR_NOT_FOUND opZX_PAGER_OP_DIRTY,范围由 offsetlength 包含未提供的区域,或之前填充过但后来填充的区域 被内核逐出。

ZX_ERR_BAD_STATE opZX_PAGER_OP_DIRTYZX_PAGER_OP_FAIL,并且 pager_vmo 已 与分页器分离。

另请参阅