class VmCowPages
Defined at line 147 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
Implements a copy-on-write hierarchy of pages in a VmPageList.
VmCowPages have a life cycle where they start in an Init state to allow them to have
initialization finished outside the constructor. A VmCowPages in the Init state may be
destructed, although it is not allowed to have any pages put in it.
Once transitioned to the Alive state the VmCowPages may generally be used, and must be
explicitly transitioned to the Dead state prior to being destructed. The explicit transition
ensures that a VmCowPages does not own any pages whilst in its destructor, and hence while the
object is unreachable due to having a ref count of 0.
Public Methods
Lock<CriticalMutex> * lock ()
Define the lock retrieval functions differently depending on whether we should be returning a
local lock instance, or the common one in the hierarchy_state_ptr. Due to the TA_RET_CAP
statements we cannot perform |if constexpr| or equivalent indirection in the function body, and
must have two completely different function definitions.
In the absence of a local lock it is assumed, and enforced in vm_object_lock.h, that there is a
shared lock in the hierarchy state. If there is both a local and a shared lock then the local
lock is to be used for the improved lock tracking.
Defined at line 165 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
Lock<CriticalMutex> & lock_ref ()
Defined at line 166 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
uint64_t lock_order ()
Defined at line 168 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
uint64_t size_locked ()
Returns the size in bytes of this cow pages range. This will always be a multiple of the page
size.
Defined at line 232 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_root_source_user_pager_backed ()
Returns whether this cow pages node is ultimately backed by a user pager to fulfill initial
content, and not zero pages. Contiguous VMOs have page_source_ set, but are not pager backed
in this sense.
This should only be used to report to user mode whether a VMO is user-pager backed, not for any
other purpose.
Defined at line 240 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool root_has_page_source ()
Returns whether the root of the cow pages hierarchy has non-null page_source_.
Defined at line 245 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
VmCowPagesOptions inheritable_options ()
Helper function for CowPage cloning methods. Returns any options that should be passed down to
the child.
Defined at line 249 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_root_source_preserving_page_content ()
Defined at line 254 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_parent_hidden_locked ()
Defined at line 258 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool has_no_children_locked ()
Defined at line 260 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_discardable ()
Defined at line 262 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool can_evict ()
Defined at line 264 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool can_root_source_evict ()
Defined at line 266 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool can_borrow ()
can_borrow() returns true if the VmCowPages is capable of borrowing pages, but whether
the VmCowPages should actually borrow pages also depends on a borrowing-site-specific flag that
the caller is responsible for checking (in addition to checking can_borrow()). Only if
both are true should the caller actually borrow at the caller's specific potential borrowing
site.
Aside from the general borrowing in the PhysicalPageBorrowingConfig being turned on and
off, the ability to borrow is constant over the lifetime of the VmCowPages.
Defined at line 279 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool should_borrow_locked ()
In addition to whether a VmCowPages is allowed, for correctness reasons, to borrow pages there
are other, potentially variable, factors that influence whether it's considered a good idea for
this VmCowPages to borrow pages. In particular it's possible for this to change over the
lifetime of the VmCowPages.
Defined at line 309 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_dirty_tracked ()
Returns whether this cow pages node is dirty tracked.
Defined at line 326 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool tree_has_parent_content_markers ()
If true this node, and all nodes in this hierarchy, are using parent content markers to
indicate when a leaf node may need to walk up the tree to find content.
When parent content markers are in use an empty page list slot in a leaf node means that there
is *no* visible parent content above, and the parent hierarchy does not have to be searched.
For memory efficiency, and because it would be redundant, parent content markers are never
placed in the hidden nodes, only leaf nodes.
The presence of a parent content marker in a leaf node indicates that there *might* be content
in a parent node and that a tree walk *must* be performed to search for it. The reason for
spurious parent content markers is that zero page deduplication could happen on hidden nodes,
which could remove the content, but leave the parent content markers in the leaf nodes. These
parent content markers are redundant and could be cleaned up.
Use of parent content markers is just the inverse of having a page source, since if there is a
page source we always have to go to it for content as the zero page cannot be assumed. Although
some page sources do supply zero content (physical page provider for contiguous VMOs),
optimizing this check for that is redundant since such page sources do not support
copy-on-write, and so never have children to begin with.
Defined at line 352 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool node_has_parent_content_markers ()
Indicates whether this node can have parent content markers placed in it. This is just checking
if it is both a leaf node, and the tree overall can have parent content markers.
Note that even if this is false, if |tree_has_parent_content_markers| is true then reasoning
may need to be done about parent content markers.
Defined at line 359 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
void mark_modified_locked ()
The modified state is only supported for root pager-backed VMOs, and will get queried (and
possibly reset) on the next QueryPagerVmoStatsLocked() call. Although the modified state is
only tracked for the root VMO.
Defined at line 366 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_high_memory_priority_locked ()
Defined at line 374 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
uint64_t pinned_page_count_locked ()
See description on |pinned_page_count_| for meaning.
Defined at line 380 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
void set_paged_backlink_locked (VmObjectPaged * ref)
Sets the VmObjectPaged backlink for this copy-on-write node.
Currently it is assumed that all nodes always have backlinks with the 1:1 hierarchy mapping,
unless this is a hidden node.
Defined at line 385 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
VmObjectPaged * get_paged_backlink_locked ()
Defined at line 387 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
uint64_t HeapAllocationBytesLocked ()
Defined at line 389 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
uint64_t ReclamationEventCountLocked ()
Defined at line 393 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
ktl::optional<zx_koid_t> GetPageSourceKoid ()
Defined at line 397 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_page_dirty_tracked (const vm_page_t * page)
Defined at line 478 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_page_dirty (const vm_page_t * page)
Defined at line 481 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_page_clean (const vm_page_t * page)
Defined at line 484 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
bool is_page_awaiting_clean (const vm_page_t * page)
Defined at line 487 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
zx_status_t QueryPagerVmoStatsLocked (bool reset, zx_pager_vmo_stats_t * stats)
Query pager VMO |stats|, and reset them too if |reset| is set to true.
Defined at line 505 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
void ResetPagerVmoStatsLocked ()
Defined at line 522 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
DiscardableVmoTracker * DebugGetDiscardableTracker ()
Exposed for testing.
Defined at line 790 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
void FreePages (list_node * pages)
Helper to free |pages| to the PMM. This function will also try to invoke FreePages() on the
backing page source if it supports it. Given the allowance of freeing pages from any object in
the hierarchy, but the page source only being on the root, it is a requirement (and checked on
clone creation), that if a page source is handling free then it may not have CoW children.
There is also an equivalent assumption that if the page source is handling free, then the page
source will be supplying all the pages and this object must never allocate directly from the
PMM.
Callers should avoid calling pmm_free() directly from inside VmCowPages, and instead should use
this helper.
Defined at line 840 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
void FreePage (vm_page_t * page)
Helper to free |pages| to the PMM. This function will also try to invoke FreePages() on the
backing page source if it supports it. Given the allowance of freeing pages from any object in
the hierarchy, but the page source only being on the root, it is a requirement (and checked on
clone creation), that if a page source is handling free then it may not have CoW children.
There is also an equivalent assumption that if the page source is handling free, then the page
source will be supplying all the pages and this object must never allocate directly from the
PMM.
Callers should avoid calling pmm_free_page() directly from inside VmCowPages, and instead
should use this helper.
Defined at line 860 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
PmmOptDelayReuse should_delay_reuse_on_free ()
Returns an appropriate PmmOptDelayReuse value for use when freeing pages from this object.
Defined at line 875 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
zx_status_t Create (VmCowPagesOptions options, uint32_t pmm_alloc_flags, uint64_t size, ktl::unique_ptr<DiscardableVmoTracker> discardable_tracker, fbl::RefPtr<VmCowPages> * cow_pages)
Defined at line 1421 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t CreateExternal (fbl::RefPtr<PageSource> src, VmCowPagesOptions options, uint64_t size, fbl::RefPtr<VmCowPages> * cow_pages)
Defined at line 1440 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx::result<LockedRefPtr> CreateCloneLocked (SnapshotType type, bool require_unidirection, VmCowRange range, DeferredOps & ops)
Creates a copy-on-write clone with the desired parameters. This can fail due to various
internal states not being correct.
Defined at line 1791 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void TransitionToAliveLocked ()
VmCowPages are initially created in the Init state and need to be transitioned to Alive prior
to being used. This is exposed for VmObjectPaged to call after ensuring that creation is
successful, i.e. after it can guarantee that it will transition this cow pages to Dead prior to
it being destroyed.
Defined at line 1003 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void DetachSource ()
Defined at line 6617 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t Resize (uint64_t size)
Resizes the range of this cow pages. |size| must be a multiple of the page size.
Defined at line 5209 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t LookupLocked (VmCowRange range, VmObject::LookupFunction lookup_fn)
See VmObject::Lookup
Defined at line 5372 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t LookupReadableLocked (VmCowRange range, LookupReadableFunction lookup_fn)
Defined at line 5398 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t TakePages (VmCowRange range, uint64_t splice_offset, VmPageSpliceList * pages, uint64_t * taken_len, MultiPageRequest * page_request)
See VmObject::TakePages
May return ZX_ERR_SHOULD_WAIT if the |page_request| is filled out and needs waiting on. In this
case |taken_len| might be populated with a value less than |len|.
|taken_len| is always filled with the amount of |len| that has been processed to allow for
gradual progress of calls. Will always be equal to |len| if ZX_OK is returned. Similarly the
|splice_offset| indicates the base offset in |pages| where the content should be inserted.
Defined at line 5480 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t ProcessPagesForSupply (VmPageSpliceList * pages)
Pre-process a VmPageSpliceList for supply.
If there is a page source, references are converted to pages. When allocating pages from
references, ZX_ERR_SHOULD_WAIT can be returned which is managed by this function.
TODO(sagebarred): handle InitializeVmPage from PhysicalPageProvider here.
Defined at line 5710 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t SupplyPagesLocked (VmCowRange range, VmPageSpliceList * pages, SupplyOptions options, DeferredOps & deferred, MultiPageRequest * page_request)
See VmObject::SupplyPages
Should never return ZX_ERR_SHOULD_WAIT, waiting on page requests is managed by
ProcessPagesForSupply.
Defined at line 5748 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t FailPageRequestsLocked (VmCowRange range, zx_status_t error_status)
See VmObject::FailPageRequests
Defined at line 5988 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t DirtyPages (VmCowRange range, list_node_t * alloc_list, AnonymousPageRequest * page_request)
See VmObject::DirtyPages. |page_request| is required to support delayed PMM allocations; if
ZX_ERR_SHOULD_WAIT is returned the caller should wait on |page_request|. |alloc_list| will hold
any pages that were allocated but not used in case of delayed PMM allocations, so that it can
be reused across multiple successive calls whilst ensuring forward progress.
Defined at line 6011 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t EnumerateDirtyRangesLocked (VmCowRange range, DirtyRangeEnumerateFunction && dirty_range_fn)
See VmObject::EnumerateDirtyRanges
Defined at line 6306 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t WritebackBeginLocked (VmCowRange range, bool is_zero_range)
See VmObject::WritebackBegin
Defined at line 6365 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t WritebackEndLocked (VmCowRange range)
See VmObject::WritebackEnd
Defined at line 6493 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t PrepareForWriteLocked (VmCowRange range, LazyPageRequest * page_request, uint64_t * dirty_len_out)
Tries to prepare the range [offset, offset + len) for writing by marking pages dirty or
verifying that they are already dirty. It is possible for only some or none of the pages in the
range to be dirtied at the end of this call. |dirty_len_out| will return the (page-aligned)
length starting at |offset| that contains dirty pages, either already dirty before making the
call or dirtied during the call. In other words, the range [offset, offset + dirty_len_out)
will be dirty when this call returns, i.e. prepared for the write to proceed, where
|dirty_len_out|
<
= |len|.
If the specified range starts with pages that are not already dirty and need to request the
page source before transitioning to dirty, a DIRTY page request will be forwarded to the page
source. In this case |dirty_len_out| will be set to 0, ZX_ERR_SHOULD_WAIT will be returned and
the caller should wait on |page_request|. If no page requests need to be generated, i.e. we
could find some pages that are already dirty at the start of the range, or if the VMO does not
require dirty transitions to be trapped, ZX_OK is returned.
|offset| and |len| should be page-aligned.
Defined at line 2931 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx::result<LookupCursor> GetLookupCursorLocked (VmCowRange range)
See VmObjectPaged::GetLookupCursorLocked
Defined at line 3695 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t AddNewPageLocked (uint64_t offset, vm_page_t * page, CanOverwriteSlot overwrite, VmPageOrMarker * released_page, bool zero, DeferredOps * deferred)
Adds an allocated page to this cow pages at the specified offset, can be optionally zeroed and
any mappings invalidated. If an error is returned the caller retains ownership of |page|.
Offset must be page aligned. Mappings being invalidated is controlled by |deferred| where if
a nullptr is passed then no mappings, in this object or any child, will be invalidated. If
|deferred| is non-null then mappings will be invalidated if necessary, both immediately in this
object, and via |deferred| for the children.
|overwrite| controls how the function handles pre-existing content at |offset|. If |overwrite|
does not permit replacing the content, ZX_ERR_ALREADY_EXISTS will be returned. If a page is
released from the page list as a result of overwriting, it is returned through |released_page|
and the caller takes ownership of this page. If the |overwrite| action is such that a page
cannot be released, it is valid for the caller to pass in nullptr for |released_page|.
Defined at line 2479 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t AddNewPagesLocked (uint64_t start_offset, list_node_t * pages, CanOverwriteSlot overwrite, bool zero, DeferredOps * deferred)
Adds a set of pages consecutively starting from the given offset. Regardless of the return
result ownership of the pages is taken. Pages are assumed to be in the ALLOC state and can be
optionally zeroed before inserting. start_offset must be page aligned.
|overwrite| controls how the function handles pre-existing content in the range, however it is
not valid to specify the |CanOverwriteSlot::PageOrRef| option, as any pages or compressed
references that would get released as a consequence cannot be returned.
Defined at line 2518 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t DecommitRange (VmCowRange range)
Attempts to release pages in the pages list causing the range to become copy-on-write again.
For consistency if there is a parent or a backing page source, such that the range would not
explicitly copy-on-write the zero page then this will fail. Use ZeroPagesLocked for an
operation that is guaranteed to succeed, but may not release memory.
Defined at line 3865 of file ../../zircon/kernel/vm/vm_cow_pages.cc
ktl::pair<zx_status_t, uint64_t> ZeroPagesLocked (VmCowRange range, bool dirty_track, DeferredOps & deferred, MultiPageRequest * page_request)
After successful completion the range of pages will all read as zeros. The mechanism used to
achieve this is not guaranteed to decommit, but it will try to.
|range| must be page aligned offsets within the range of the object. |dirty_track| specifies
whether the range being zeroed subscribes to dirty tracking, if |true| the range will start out
as dirty. |dirty_track| only has meaning if the VMO supports dirty tracking, otherwise it is
ignored.
Returns a status code, and the number of bytes that were actually zeroed.
This may be nonzero even if the returned status != ZX_OK.
The returned status is one of the following:
* ZX_OK => The whole range was successfully zeroed.
* ZX_ERR_SHOULD_WAIT => The caller needs to wait on the |page_request| and then retry the
operation. The caller may advance the start offset by the number of zeroed bytes before
retrying.
* Any other error code indicates a failure to zero a part of the range or the whole
range.
Defined at line 4458 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t CommitRangeLocked (VmCowRange range, DeferredOps & deferred, uint64_t * committed_len, MultiPageRequest * page_request)
Attempts to commit a range of pages. This has three kinds of return status
ZX_OK => The whole range was successfully committed and |len| will be written to
|committed_len|
ZX_ERR_SHOULD_WAIT => A partial (potentially 0) range was committed (output in |committed_len|
and the passed in |page_request| should be waited on before retrying
the commit operation. The portion that was successfully committed does
not need to retried.
* => Any other error, the number of pages committed is undefined.
The |offset| and |len| are assumed to be page aligned and within the range of |size_|.
Defined at line 3719 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t PinRangeLocked (VmCowRange range)
Increases the pin count of the range of pages given by |offset| and |len|. The full range must
already be committed and this either pins all pages in the range, or pins no pages and returns
an error. The caller can assume that on success len / kPageSize pages were pinned.
The |offset| and |len| are assumed to be page aligned and within the range of |size_|.
All pages in the specified range are assumed to be non-loaned pages, so the caller is expected
to replace any loaned pages beforehand if required.
Defined at line 3801 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void UnpinLocked (VmCowRange range, DeferredOps * deferred)
See VmObject::Unpin
An optional |DeferredOps| can be provided for the purposes of performing extra debugging
checks, but otherwise has no functional requirement. The debug checks are optional as call
sites may not be able to satisfy the locking requirements to construct a DeferredOps, and may
know (due to be undoing a pin they themselves had started), that no checks need to be done.
Defined at line 5001 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugIsRangePinnedLocked (VmCowRange range)
See VmObject::DebugIsRangePinned
Defined at line 5074 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool PageWouldReadZeroLocked (uint64_t page_offset)
Returns true if a page is not currently committed, and if the offset were to be read from, it
would be read as zero. Requested offset must be page aligned and within range.
Defined at line 3931 of file ../../zircon/kernel/vm/vm_cow_pages.cc
AttributionCounts GetAttributedMemoryInRangeLocked (VmCowRange range)
Defined at line 2243 of file ../../zircon/kernel/vm/vm_cow_pages.cc
VmCowReclaimResult ReclaimPage (vm_page_t * page, uint64_t offset, EvictionAction eviction_action, VmCompressor * compressor)
Asks the VMO to attempt to reclaim the specified page. There are a few possible outcomes:
1. Exactly this page is reclaimed.
2. This page and other pages are reclaimed.
3. Just other pages are reclaimed.
4. No pages are reclaimed.
Pages other than the one requested may get reclaimed due to any internal relationships between
pages that make it meaningless or difficult to reclaim just the single page in question.
In the cases of (3) and (4) there are some guarantees provided:
1. If the |page| was not from this VMO (or not at the specified offset) then nothing about the
|page| or this VMO will be modified.
2. If the |page| is from this VMO and offset (and was not reclaimed) then the page will have
been removed from any candidate reclamation lists (such as the DontNeed pager backed list).
The effect of (2) is that the caller can assume in the case of reclamation failure it will not
keep finding this page as a reclamation candidate and infinitely retry it.
If the |compressor| is non-null then it must have just had |Arm| called on it.
|eviction_action| hints indicates whether the |always_need| eviction hint should be respected
or ignored. Require will force eviction.
The actual number of pages reclaimed is returned if successful, or a failure reason if not.
VmCowReclaimResult is an alias for fit::result
<VmCowReclaimFailure
, VmCowReclaimSuccess>.
Defined at line 7138 of file ../../zircon/kernel/vm/vm_cow_pages.cc
template <typename T>
ktl::optional<VmCowReclaimFailure> CannotReclaimPageLocked (vm_page_t * page, T actual)
Helper for reclamation functions to perform common checks for whether or not reclamation should
proceed. It takes two parameters, one being the original requested page and the other being
the result of a page list Lookup or LookupMutable, allowing it to check if the page is still
up to date and owned by this VMO.
Defined at line 6845 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t ReplacePagesWithNonLoanedLocked (VmCowRange range, DeferredOps & deferred, AnonymousPageRequest * page_request, uint64_t * non_loaned_len)
If any pages in the specified range are loaned pages, replaces them with non-loaned pages
(which requires providing a |page_request|). The specified range should be fully committed
before calling this function. If a gap or a marker is encountered, or a loaned page cannot be
replaced, returns early with ZX_ERR_BAD_STATE. If the replacement needs to wait on the PMM for
allocation, returns ZX_ERR_SHOULD_WAIT, and the caller should wait on the |page_request|.
|non_loaned_len| is set to the length (starting at |offset|) that contains only non-loaned
pages. |offset| and |len| must be page-aligned.
Defined at line 7180 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t ReplacePageWithLoaned (vm_page_t * before_page, uint64_t offset)
If page is still at offset, replace it with a loaned page.
Defined at line 7239 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DedupZeroPage (vm_page_t * page, uint64_t offset)
Attempts to dedup the given page at the specified offset with the zero page. The only
correctness requirement for this is that `page` must be *some* valid vm_page_t, meaning that
all race conditions are handled internally. This function returns false if
* page is either not from this VMO, or not found at the specified offset
* page is pinned
* vmo is uncached
* page is not all zeroes
Otherwise 'true' is returned and the page will have been returned to the pmm with a zero page
marker put in its place.
Defined at line 1348 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void DumpLocked (uint depth, bool verbose)
Defined at line 2164 of file ../../zircon/kernel/vm/vm_cow_pages.cc
uint32_t DebugLookupDepthLocked ()
see VmObject::DebugLookupDepth
Defined at line 2229 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugValidatePageSharingLocked ()
VMO_VALIDATION
Defined at line 7373 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugValidateBacklinksLocked ()
Defined at line 7515 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugValidateHierarchyLocked ()
Calls DebugValidatePageSharesLocked on this and every parent in the chain, returning true if
all return true. Also calls DebugValidateBacklinksLocked on every node in the hierarchy.
Defined at line 7344 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugValidateZeroIntervalsLocked ()
Defined at line 7602 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t DebugForEachDescendant (fit::inline_function<zx_status_t (VmCowPages *, uint)> )
Walks all the descendants in a preorder traversal. Stops if func returns anything other than
ZX_OK.
Defined at line 1330 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugValidateVmoPageBorrowingLocked ()
VMO_FRUGAL_VALIDATION
Defined at line 7553 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void RangeChangeUpdateLocked (VmCowRange range, RangeChangeOp op, DeferredOps * deferred)
Applies the specific operation to all mappings in the given range. The mappings for the current
object are operated on immediately, with any children being operated on using |deferred|. If
the caller knows that no |DeferredOps| is needed (e.g. the VMO has no children and is not pager
backed) then a nullptr can be provided.
Defined at line 6684 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void FinishCachePolicyTransitionLocked ()
The VmObjectPaged is changing its cache mapping policy. Clean / invalidate all existing pages
and update page queues if required.
Defined at line 6824 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t PromoteRangeForReclamation (VmCowRange range)
Promote pages in the specified range for reclamation under memory pressure. |offset| will be
rounded down to the page boundary, and |len| will be rounded up to the page boundary.
Currently used only for pager-backed VMOs to move their pages to the end of the
pager-backed queue, so that they can be evicted first.
Defined at line 4600 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t ProtectRangeFromReclamation (VmCowRange range, bool set_always_need, bool ignore_errors)
Protect pages in the specified range from reclamation under memory pressure. |offset| will be
rounded down to the page boundary, and |len| will be rounded up to the page boundary. Any
absent pages in the range will first be committed and then, if |set_always_need| is true, the
|always_need| flag in the pages will be set.
If the |ignore_errors| flag is set then any per page errors will be ignored and future pages in
the range will still be operated on. If this flag is not set then any kind of error causes an
immediate abort.
Defined at line 4652 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t DecompressInRange (VmCowRange range)
Ensures any pages in the specified range are not compressed, but does not otherwise commit any
pages.
Defined at line 4800 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t LockRangeLocked (VmCowRange range, zx_vmo_lock_state_t * lock_state_out)
Defined at line 7672 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t TryLockRangeLocked (VmCowRange range)
Defined at line 7715 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t UnlockRangeLocked (VmCowRange range)
Defined at line 7749 of file ../../zircon/kernel/vm/vm_cow_pages.cc
uint64_t DebugGetPageCountLocked ()
Defined at line 7783 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugIsPage (uint64_t offset)
Defined at line 7798 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugIsMarker (uint64_t offset)
Defined at line 7806 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugIsEmpty (uint64_t offset)
Defined at line 7814 of file ../../zircon/kernel/vm/vm_cow_pages.cc
vm_page_t * DebugGetPage (uint64_t offset)
Defined at line 7822 of file ../../zircon/kernel/vm/vm_cow_pages.cc
vm_page_t * DebugGetPageLocked (uint64_t offset)
Defined at line 7828 of file ../../zircon/kernel/vm/vm_cow_pages.cc
bool DebugIsHighMemoryPriority ()
Defined at line 7838 of file ../../zircon/kernel/vm/vm_cow_pages.cc
DiscardablePageCounts DebugGetDiscardablePageCounts ()
Defined at line 7844 of file ../../zircon/kernel/vm/vm_cow_pages.cc
fbl::RefPtr<VmCowPages> DebugGetParent ()
Returns the parent of this cow pages, may be null. Generally the parent should never be
directly accessed externally, but this exposed specifically for tests.
Defined at line 6610 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void InitializePageCache (uint32_t level)
Initializes the PageCache instance for COW page allocations.
Defined at line 8040 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t ReplacePage (vm_page_t * before_page, uint64_t offset, bool with_loaned, vm_page_t ** after_page, AnonymousPageRequest * page_request)
Unlocked wrapper around ReplacePageLocked, exposed for the physical page provider to cancel
loans with.
Defined at line 7247 of file ../../zircon/kernel/vm/vm_cow_pages.cc
VmCowReclaimResult ReclaimPageForEviction (vm_page_t * page, uint64_t offset, EvictionAction eviction_action)
Eviction wrapper, unlike ReclaimPage this wrapper can assume it just needs to evict, and has no
requirements on updating any reclamation lists. Exposed for the physical page provider to
reclaim loaned pages.
Is also used as an internal helper by ReclaimPage.
Defined at line 6863 of file ../../zircon/kernel/vm/vm_cow_pages.cc
fbl::RefPtr<VmCowPages> MaybeDeadTransition ()
Potentially transitions from Alive->Dead if the cow pages is unreachable (i.e. has no
paged_ref_ and no children). Used by the VmObjectPaged when it unlinks the paged_ref_, but
prior to dropping the RefPtr, giving the VmCowPages a chance to transition.
If a VmCowPages is returned then this is a parent that needs to have MaybeDeadTransition called
on it.
Defined at line 1008 of file ../../zircon/kernel/vm/vm_cow_pages.cc
zx_status_t AllocPage (vm_page_t ** page, AnonymousPageRequest * page_request)
Helper to allocate a new page for the VMO, filling out the page request if necessary.
Defined at line 873 of file ../../zircon/kernel/vm/vm_cow_pages.cc
void DebugDumpReclaimCounters ()
static
Defined at line 192 of file ../../zircon/kernel/vm/vm_cow_pages.cc
Enumerations
enum DirtyState
| Name | Value |
|---|---|
| Untracked | 0 |
| Clean | 1 |
| Dirty | 2 |
| AwaitingClean | 3 |
| NumStates | 4 |
Used to track dirty_state in the vm_page_t.
The transitions between the three states can roughly be summarized as follows:
1. A page starts off as Clean when supplied.
2. A write transitions the page from Clean to Dirty.
3. A writeback_begin moves the Dirty page to AwaitingClean.
4. A writeback_end moves the AwaitingClean page to Clean.
5. A write that comes in while the writeback is in progress (i.e. the page is AwaitingClean)
moves the AwaitingClean page back to Dirty.
Defined at line 460 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
enum CanOverwriteSlot
| Name | Value |
|---|---|
| Empty | 0 |
| EmptyOrParent | 1 |
| ZeroMarkerOrInterval | 2 |
| PageOrRef | 3 |
Controls the type of VmPageOrMarker slot in |this| VmCowPages' page_list_ that can be
overwritten by the Add[New]Page[s]Locked functions. It is the caller's responsibility to ensure
that the previous content is dealt with correctly (e.g. any pages and compressed
references are freed).
Defined at line 557 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
enum EvictionAction
| Name | Value |
|---|---|
| FollowHint | 0 |
| IgnoreHint | 1 |
| Require | 2 |
TODO(sagebarreda
@
): consider refactoring eviction out of reclamation so it can be called
instead of using reclamation with `Require`.
Defined at line 663 of file ../../zircon/kernel/vm/include/vm/vm_cow_pages.h
Records
Friends
class PriorityChanger
class LockedParentWalker
class RefPtr