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);

說明

在 [offset, offset + length) 範圍內,對 pager_vmo 執行由 op 指定的分頁器作業。pager_vmo 必須先前已從 pager 透過 zx_pager_create_vmo() 建立。位移長度必須與頁面對齊。如果指定的 op 支援 資料,則此為選用參數。

可執行的作業,也就是 op 可採用的值:

ZX_PAGER_OP_DIRTY - 使用者空間分頁程式想將範圍 [offset,offset + length) 中的頁面從乾淨轉換為髒污。這會解除指定範圍內等待 ZX_PAGER_VMO_DIRTY 網頁要求的任何寫入作業。

ZX_PAGER_OP_FAIL - 使用者空間分頁器無法滿足範圍 [offset, offset + length) 中 pager_vmo 的頁面要求,指令為 ZX_PAGER_VMO_READZX_PAGER_VMO_DIRTYdata 包含遇到的錯誤 (已符號擴充為 uint64_t 值的 zx_status_t 錯誤代碼) - 允許的值為 ZX_ERR_IOZX_ERR_IO_DATA_INTEGRITYZX_ERR_BAD_STATEZX_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 - 使用者空間分頁器想要開始在範圍 [offset, offset + length) 中寫回頁面。這表示寫回完成後 (以 ZX_PAGER_OP_WRITEBACK_END 表示),系統會清除指定範圍內的任何髒頁面。如需建議用法,請參閱下方的程式碼範例。

data 可以選擇設為 ZX_VMO_DIRTY_RANGE_IS_ZERO,表示呼叫端想將指定範圍寫回為零。當呼叫端處理 zx_pager_query_dirty_ranges() 傳回的範圍,且 options 設為 ZX_VMO_DIRTY_RANGE_IS_ZERO 時,應使用此方法。確保在查詢後但開始回寫前,範圍內建立的任何非零內容不會因錯誤假設仍為零而遺失,並標示為乾淨 (因此可逐出)。

ZX_PAGER_OP_WRITEBACK_END - 使用者空間分頁器已完成寫回範圍內的頁面 [offset, offset + length)。這表示指定範圍內先前以 ZX_PAGER_OP_WRITEBACK_BEGIN 標示的任何髒頁面,都可以標示為乾淨。如需建議用法,請參閱下方的程式碼範例。

核心可任意逐出已標示為乾淨的任何頁面或零範圍,之後如果需要,使用者空間分頁器會再次提供這些頁面或範圍。這也表示分頁器應謹慎行事,避免有任何過時的供應項目在傳輸中,且只應提供剛寫回的新內容。

以下是探索及清除任何髒頁面的程式碼範例 (模數錯誤處理)。

  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 pager 沒有 ZX_RIGHT_MANAGE_VMOpager_vmo 沒有 ZX_RIGHT_WRITE

ZX_ERR_INVALID_ARGS 符合下列任一條件:

  • pager_vmo 不是從 pager 建立的 VMO。
  • offsetlength 未與頁面對齊。
  • opZX_PAGER_OP_FAIL,且 data 不是 ZX_ERR_IOZX_ERR_IO_DATA_INTEGRITYZX_ERR_BAD_STATE
  • opZX_PAGER_OP_WRITEBACK_BEGIN,且 data 不是 0 或 ZX_VMO_DIRTY_RANGE_IS_ZERO

ZX_ERR_OUT_OF_RANGE pager_vmo 中指定的範圍無效。

ZX_ERR_NOT_SUPPORTED op 不支援 pager_vmo 中的指定範圍。

ZX_ERR_NOT_FOUND opZX_PAGER_OP_DIRTY,且由 offsetlength 表示的範圍包含未提供的區域,或是先前已填入但隨後遭核心逐出的區域。

ZX_ERR_BAD_STATE opZX_PAGER_OP_DIRTYZX_PAGER_OP_FAIL,且 pager_vmo 已從 pager 分離。

另請參閱