Summary
Perform an operation on a range of a pager owned VMO.
Declaration
#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);
Description
Performs a pager operation, specified by op on pager_vmo in the range [offset, offset +
length). The pager_vmo must have previously been created from the pager by
zx_pager_create_vmo()
. offset and length must be page aligned. data is an optional
parameter, if the specified op supports one.
Operations that can be performed, i.e. values op can take:
ZX_PAGER_OP_DIRTY
- The userspace pager wants to transition pages in the range [offset,
offset + length) from clean to dirty. This will unblock any writes that were waiting on
ZX_PAGER_VMO_DIRTY
page requests for the specified range.
ZX_PAGER_OP_FAIL
- The userspace pager failed to fulfill page requests for pager_vmo in the
range [offset, offset + length) with command ZX_PAGER_VMO_READ
or ZX_PAGER_VMO_DIRTY
.
data contains the error encountered (a zx_status_t
error code sign-extended to a uint64_t
value) - permitted values are ZX_ERR_IO
, ZX_ERR_IO_DATA_INTEGRITY
, ZX_ERR_BAD_STATE
,
ZX_ERR_NO_SPACE
, and ZX_ERR_BUFFER_TOO_SMALL
.
This will signal threads that might be waiting on page requests in that range, unblocking them. If
the blocked thread was requesting pages through a zx_vmo_read()
/ zx_vmo_write()
or a
zx_vmo_op_range()
with ZX_VMO_OP_COMMIT
, the call will fail and the error status (data)
will be returned. If the blocked thread was requesting pages through a VMAR mapping, the thread will
take a fatal page fault exception.
ZX_PAGER_OP_WRITEBACK_BEGIN
- The userspace pager wants to begin writing back pages in the range
[offset, offset + length). This indicates an intent to clean any dirty pages in the specified
range once the writeback is completed (signaled with ZX_PAGER_OP_WRITEBACK_END
). Refer to the
sample code below for suggested usage.
data can optionally be set to ZX_VMO_DIRTY_RANGE_IS_ZERO
to indicate that the caller wants to
write back the specified range as zeroes. This is intended to be used when the caller is processing
a range that was returned by zx_pager_query_dirty_ranges()
with its options
set to
ZX_VMO_DIRTY_RANGE_IS_ZERO
. It ensures that any non-zero content that was created in the range
after the query but before the writeback was started is not lost, by incorrectly assuming it is
still zero and marking it clean (hence evictable).
ZX_PAGER_OP_WRITEBACK_END
- The userspace pager is done writing back pages in the range
[offset, offset + length). This indicates that any dirty pages in the specified range that
were previously signaled with ZX_PAGER_OP_WRITEBACK_BEGIN
can be marked clean. Refer to the
sample code below for suggested usage.
The kernel is free to evict any pages or zero ranges that have been marked clean, after which the userspace pager will be expected to supply them again if needed. This also means that the pager should be careful to not have any stale supplies in flight, and should only supply with the new content it has just written back.
Sample code (modulo error handling) to discover and clean any dirty pages might look something like this.
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);
}
Rights
pager must be of type ZX_OBJ_TYPE_PAGER
and have ZX_RIGHT_MANAGE_VMO
.
pager_vmo must be of type ZX_OBJ_TYPE_VMO
and have ZX_RIGHT_WRITE
.
Return value
zx_pager_op_range()
returns ZX_OK on success, or one of the following error codes on failure.
Errors
ZX_ERR_BAD_HANDLE
pager or pager_vmo is not a valid handle.
ZX_ERR_WRONG_TYPE
pager is not a pager handle, or pager_vmo is not a VMO handle.
ZX_ERR_ACCESS_DENIED
pager does not have ZX_RIGHT_MANAGE_VMO
or pager_vmo does not have
ZX_RIGHT_WRITE
.
ZX_ERR_INVALID_ARGS
under any of these conditions:
- pager_vmo is not a VMO created from pager.
- offset or length is not page aligned.
- op is ZX_PAGER_OP_FAIL
and data is not one of ZX_ERR_IO
, ZX_ERR_IO_DATA_INTEGRITY
or ZX_ERR_BAD_STATE
.
- op is ZX_PAGER_OP_WRITEBACK_BEGIN
and data is not 0 or ZX_VMO_DIRTY_RANGE_IS_ZERO
.
ZX_ERR_OUT_OF_RANGE
The specified range in pager_vmo is invalid.
ZX_ERR_NOT_SUPPORTED
op is not supported on the specified range in pager_vmo.
ZX_ERR_NOT_FOUND
op is ZX_PAGER_OP_DIRTY
and the range denoted by offset and
length contains unsupplied regions, or regions that were previously populated but have since been
evicted by the kernel.
ZX_ERR_BAD_STATE
op is ZX_PAGER_OP_DIRTY
or ZX_PAGER_OP_FAIL
and pager_vmo has been
detached from the pager.