| <!-- |
| Copyright 2023 The Fuchsia Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| |
| DO NOT EDIT. Generated from FIDL library zx by zither, a Fuchsia platform tool. |
| |
| See //docs/reference/syscalls/README.md#documentation-generation for |
| regeneration instructions. |
| --> |
| |
| # zx_pager_op_range |
| |
| ## Summary |
| |
| Perform an operation on a range of a pager owned VMO. |
| |
| ## Declaration |
| |
| ```c |
| #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. |
| |
| ```c |
| 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*. |
| |
| ## See also |
| |
| - [`zx_pager_create_vmo()`] |
| - [`zx_pager_detach_vmo()`] |
| - [`zx_pager_query_dirty_ranges()`] |
| - [`zx_pager_supply_pages()`] |
| |
| [`zx_pager_create_vmo()`]: pager_create_vmo.md |
| [`zx_pager_detach_vmo()`]: pager_detach_vmo.md |
| [`zx_pager_query_dirty_ranges()`]: pager_query_dirty_ranges.md |
| [`zx_pager_supply_pages()`]: pager_supply_pages.md |
| [`zx_vmo_op_range()`]: vmo_op_range.md |
| [`zx_vmo_read()`]: vmo_read.md |
| [`zx_vmo_write()`]: vmo_write.md |