摘要
在 VMO 範圍內執行作業。
宣告
#include <zircon/syscalls.h>
zx_status_t zx_vmo_op_range(zx_handle_t handle,
uint32_t op,
uint64_t offset,
uint64_t size,
void* buffer,
size_t buffer_size);
說明
zx_vmo_op_range()
會針對虛擬記憶體物件 (VMO) 所持有的頁面執行快取和記憶體作業。
offset 位元組偏移,在 VMO 保存記憶體中,指定 op 的起始位置。
size 長度 (以位元組為單位),用於執行這項作業。
操作來執行作業:
buffer 和 buffer_size,也可能不使用或不使用,視運算而定,如下所述。
ZX_VMO_OP_COMMIT
:為 VMO 修訂版本指定頁數的大小位元組數 (從 VMO 的偏移開始)。詳情請參閱 vm 物件說明文件。需要有 ZX_RIGHT_WRITE
權限。
ZX_VMO_OP_DECOMMIT
:發布先前提交至 VMO 的特定頁面範圍從「偏移」到「偏移」+「大小」,藉此將範圍的位元組重設為 0。需要有 ZX_RIGHT_WRITE
權限。這個方法僅適用於透過 zx_vmo_create()
建立 (沒有非配量子項) 的 VM OS,以及這類 vmos 的配量子項。提供的範圍必須與頁面對齊。
ZX_VMO_OP_ZERO
:將 VMO 中的位元組範圍從 offset 重設為 offset + size 至 0。這在語意上相當於使用 zx_vmo_write()
寫入 0,但排除重複至零個頁面,可提高執行效率並節省記憶體。需要有 ZX_RIGHT_WRITE
權限。
ZX_VMO_OP_LOCK
:在使用 ZX_VMO_DISCARDABLE
建立的 VMO 中鎖定多個頁面,避免核心捨棄這些頁面。保證可以成功鎖定 VMO,並在引數有效時傳回 ZX_OK
。buffer 指向 zx_vmo_lock_state_t
結構,而 buffer_size 應能容納結構。傳回「buffer」中已鎖定和先前捨棄範圍的相關資訊,以便用戶端可以視需要重新初始化捨棄的內容。
應一次鎖定整個 VMO,因此 offset 應為 0,且 size 應為 VMO 的目前大小 (與 zx_vmo_get_size()
傳回的頁面對齊大小)。需要 ZX_RIGHT_READ
或 ZX_RIGHT_WRITE
。請注意,鎖定本身並不會提交 VMO 中的任何頁面;只會將 VMO 的狀態標示為核心「取消卡頓」。
buffer 為 zx_info_lock_state_t
類型的指標。
typedef struct zx_vmo_lock_state {
// |offset| and |size| track the locked range, and will be set to the |offset|
// and |size| arguments passed in if the ZX_VMO_OP_LOCK is successful.
uint64_t offset;
uint64_t size;
// |discarded_offset| and |discarded_size| track the discarded range prior to
// the lock operation. This is the maximal range within the locked range that
// contains discarded pages; not all pages within this range might have been
// discarded. Both |discarded_offset| and |discarded_size| will be set to 0 if
// the range was not discarded.
uint64_t discarded_offset;
uint64_t discarded_size;
} zx_vmo_lock_state_t;
ZX_VMO_OP_TRY_LOCK
:在使用 ZX_VMO_DISCARDABLE
建立的 VMO 中鎖定特定範圍的頁面,避免核心捨棄這些頁面。只有在核心尚未捨棄範圍時才會成功,否則 ZX_ERR_UNAVAILABLE
會失敗。對 ZX_VMO_OP_LOCK
嘗試鎖定 VMO 無需設定緩衝區引數,這項工作可以做為輕量的替代方案。還能讓用戶端在無法鎖定 VMO 後選擇不採取任何行動;用戶端如要再次鎖定 VMO,則必須使用 ZX_VMO_OP_LOCK
。
應一次鎖定整個 VMO,因此 offset 應為 0,且 size 應為 VMO 的目前大小 (與 zx_vmo_get_size()
傳回的頁面對齊大小)。需要 ZX_RIGHT_READ
或 ZX_RIGHT_WRITE
。請注意,鎖定本身並不會提交 VMO 中的任何頁面;只會將 VMO 的狀態標示為核心「取消卡頓」。
ZX_VMO_OP_UNLOCK
- 解鎖使用 ZX_VMO_DISCARDABLE
建立的 VMO 中一系列頁面,表示核心可在記憶體壓力下捨棄頁面。已解鎖但尚未捨棄的頁面將被視為已修訂的頁面。
應一次解鎖整個 VMO,因此 offset 應為 0,且 size 應為 VMO 的目前大小 (與 zx_vmo_get_size()
傳回的頁面對齊大小)。需要 ZX_RIGHT_READ
或 ZX_RIGHT_WRITE
。
ZX_VMO_OP_CACHE_SYNC
- 將指令快取與資料快取同步,因此指令擷取作業可查看先前的寫入內容。需要有 ZX_RIGHT_READ
權限。
ZX_VMO_OP_CACHE_INVALIDATE
- 執行快取撤銷作業,以便日後讀取讀取主記憶體的外部變更。請注意,此作業僅適用於 kernel.enable-debugging-syscalls
為 true 時。在未啟用 syscall 的情況下,此作業會失敗,並顯示 ZX_ERR_NOT_SUPPORTED
需要 ZX_RIGHT_WRITE
權限。
ZX_VMO_OP_CACHE_CLEAN
- 清除 (寫回) 資料快取,因此先前的寫入作業會顯示在主記憶體中。需要有 ZX_RIGHT_READ
權限。
ZX_VMO_OP_CACHE_CLEAN_INVALIDATE
- 一併執行快取清理和無效作業。需要有 ZX_RIGHT_READ
權限。
ZX_VMO_OP_DONT_NEED
- 指定範圍中不再需要頁面的提示,應將其視為記憶體回收。適合與利用 zx_pager_create_vmo()
建立的 VMO 搭配使用;在其他 VMO 中短暫成功。
這項做法僅適用於指定範圍內已經修訂的頁面,也就是說,這項結果不會產生任何新頁面。如有需要,系統會將 offset 無條件捨去至上一頁邊界,offset + size 則會無條件進位至下一頁邊界。
ZX_VMO_OP_ALWAYS_NEED
:表示指定範圍內的頁面很重要,應避免記憶體回收。如果系統的記憶體壓力較大,核心可以決定覆寫這項提示。此外,這項提示亦不會阻止網頁以記憶體回收以外的方式釋放頁面 (例如解除修訂、VMO 大小調整或 VMO 刪除)。適合與利用 zx_pager_create_vmo()
建立的 VMO 搭配使用;對其他 VMO 來說會是最小可行的。
這麼做可能會在適用情況下修訂指定範圍內的頁面。舉例來說,如果 VMO 直接由 Pager 提供支援,系統會修訂其頁面;若為本機副本,則會提交可在本機副本中可見的頁面。如有需要,系統會將 offset 無條件捨去至前一個頁面邊界,而 offset+size 則會無條件進位至下一頁邊界。
請注意,ZX_VMO_OP_DONT_NEED
不會復原先前的 ZX_VMO_OP_ALWAYS_NEED
。ZX_VMO_OP_ALWAYS_NEED
提示是固定的,直到核心因記憶體壓力而決定覆寫提示為止。
權限
如果 op 為 ZX_VMO_OP_COMMIT
,handle 必須為 ZX_OBJ_TYPE_VMO
類型,且具有 ZX_RIGHT_WRITE
。
如果 op 為 ZX_VMO_OP_DECOMMIT
,handle 必須為 ZX_OBJ_TYPE_VMO
類型,且具有 ZX_RIGHT_WRITE
。
如果 op 為 ZX_VMO_OP_CACHE_SYNC
,handle 必須為 ZX_OBJ_TYPE_VMO
類型,且具有 ZX_RIGHT_READ
。
如果 op 為 ZX_VMO_OP_CACHE_INVALIDATE
,handle 必須為 ZX_OBJ_TYPE_VMO
類型,且具有 ZX_RIGHT_WRITE
。
如果 op 為 ZX_VMO_OP_CACHE_CLEAN
,handle 必須為 ZX_OBJ_TYPE_VMO
類型,且具有 ZX_RIGHT_READ
。
如果 op 為 ZX_VMO_OP_CACHE_CLEAN_INVALIDATE
,handle 必須為 ZX_OBJ_TYPE_VMO
類型,且具有 ZX_RIGHT_READ
。
傳回值
zx_vmo_op_range()
會在成功時傳回 ZX_OK
。如果失敗,系統會傳回負值的錯誤值。
錯誤
ZX_ERR_BAD_HANDLE
帳號代碼不是有效的帳號代碼。
ZX_ERR_OUT_OF_RANGE
由 offset 和 size 指定的記憶體範圍無效。
ZX_ERR_NO_MEMORY
分配至 ZX_VMO_OP_COMMIT
或 ZX_VMO_OP_ZERO
的修訂版本頁面失敗。
ZX_ERR_WRONG_TYPE
帳號代碼並非 VMO 控制代碼。
ZX_ERR_ACCESS_DENIED
帳號代碼沒有執行這項作業的權限。
ZX_ERR_INVALID_ARGS
緩衝區 是無效指標 (如果作業需要的話),op 並非有效作業,size 為零,op 為快取作業,或 op 是 ZX_VMO_OP_DECOMMIT
,且範圍未對齊頁面。
符合以下任一條件的 ZX_ERR_NOT_SUPPORTED
:op 為 ZX_VMO_OP_LOCK
、ZX_VMO_OP_TRY_LOCK
或 ZX_VMO_OP_UNLOCK
,且 VMO 並非使用 ZX_VMO_DISCARDABLE
建立。
- op 為 ZX_VMO_OP_DECOMMIT
,且基礎 VMO 不允許停用。
- op 為 ZX_VMO_OP_CACHE_INVALIDATE
,kernel.enable-debugging-syscalls
為 false。
ZX_ERR_UNAVAILABLE
運算為 ZX_VMO_OP_TRY_LOCK
,表示可捨棄 VMO,且核心已捨棄 VMO。
ZX_ERR_BAD_STATE
運算為 ZX_VMO_OP_COMMIT
,代表 VMO 受到呼叫器支援,且呼叫器或 VMO 處於不良狀態,導致系統無法填入要求的網頁。op 為 ZX_VMO_OP_UNLOCK
,VMO 可捨棄,且 VMO 之前並未鎖定。
ZX_ERR_IO
運算為 ZX_VMO_OP_COMMIT
,VMO 由呼叫器支援,且呼叫器在提交要求的網頁時遇到 I/O 錯誤。
ZX_ERR_IO_DATA_INTEGRITY
運算為 ZX_VMO_OP_COMMIT
,VMO 會由呼叫器支援,而在修訂的頁面透過 Pager 讀取的內容會損毀。
另請參閱
zx_vmo_create()
zx_vmo_create_child()
zx_vmo_get_size()
zx_vmo_read()
zx_vmo_set_size()
zx_vmo_write()