摘要
對 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_READ 或 ZX_PAGER_VMO_DIRTY。
data 包含遇到的錯誤 (已符號擴充為 uint64_t 值的 zx_status_t 錯誤代碼) - 允許的值為 ZX_ERR_IO、ZX_ERR_IO_DATA_INTEGRITY、ZX_ERR_BAD_STATE、ZX_ERR_NO_SPACE 和 ZX_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 pager 或 pager_vmo 不是有效的控制代碼。
ZX_ERR_WRONG_TYPE pager 不是分頁器控制代碼,或 pager_vmo 不是 VMO 控制代碼。
ZX_ERR_ACCESS_DENIED pager 沒有 ZX_RIGHT_MANAGE_VMO 或 pager_vmo 沒有 ZX_RIGHT_WRITE。
ZX_ERR_INVALID_ARGS 符合下列任一條件:
- pager_vmo 不是從 pager 建立的 VMO。
- offset 或 length 未與頁面對齊。
- op 為
ZX_PAGER_OP_FAIL,且 data 不是ZX_ERR_IO、ZX_ERR_IO_DATA_INTEGRITY或ZX_ERR_BAD_STATE。 - op 為
ZX_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 op 是 ZX_PAGER_OP_DIRTY,且由 offset 和 length 表示的範圍包含未提供的區域,或是先前已填入但隨後遭核心逐出的區域。
ZX_ERR_BAD_STATE op 為 ZX_PAGER_OP_DIRTY 或 ZX_PAGER_OP_FAIL,且 pager_vmo 已從 pager 分離。