Changeset View
Changeset View
Standalone View
Standalone View
head/sys/vm/vm_page.c
Show First 20 Lines • Show All 2,669 Lines • ▼ Show 20 Lines | #endif | ||||
* Skip the page for one of the following reasons: (1) | * Skip the page for one of the following reasons: (1) | ||||
* It is enqueued in the physical memory allocator's | * It is enqueued in the physical memory allocator's | ||||
* free page queues. However, it is not the first | * free page queues. However, it is not the first | ||||
* page in a run of contiguous free pages. (This case | * page in a run of contiguous free pages. (This case | ||||
* rarely occurs because the scan is performed in | * rarely occurs because the scan is performed in | ||||
* ascending order.) (2) It is not reserved, and it is | * ascending order.) (2) It is not reserved, and it is | ||||
* transitioning from free to allocated. (Conversely, | * transitioning from free to allocated. (Conversely, | ||||
* the transition from allocated to free for managed | * the transition from allocated to free for managed | ||||
* pages is blocked by the page lock.) (3) It is | * pages is blocked by the page busy lock.) (3) It is | ||||
* allocated but not contained by an object and not | * allocated but not contained by an object and not | ||||
* wired, e.g., allocated by Xen's balloon driver. | * wired, e.g., allocated by Xen's balloon driver. | ||||
*/ | */ | ||||
run_ext = 0; | run_ext = 0; | ||||
} | } | ||||
/* | /* | ||||
* Extend or reset the current run of pages. | * Extend or reset the current run of pages. | ||||
▲ Show 20 Lines • Show All 930 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* vm_page_dequeue_deferred: [ internal use only ] | * vm_page_dequeue_deferred: [ internal use only ] | ||||
* | * | ||||
* Request removal of the given page from its current page | * Request removal of the given page from its current page | ||||
* queue. Physical removal from the queue may be deferred | * queue. Physical removal from the queue may be deferred | ||||
* indefinitely. | * indefinitely. | ||||
* | |||||
* The page must be locked. | |||||
*/ | */ | ||||
void | void | ||||
vm_page_dequeue_deferred(vm_page_t m) | vm_page_dequeue_deferred(vm_page_t m) | ||||
{ | { | ||||
vm_page_astate_t new, old; | vm_page_astate_t new, old; | ||||
old = vm_page_astate_load(m); | old = vm_page_astate_load(m); | ||||
do { | do { | ||||
▲ Show 20 Lines • Show All 164 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* vm_page_free_toq: | * vm_page_free_toq: | ||||
* | * | ||||
* Returns the given page to the free list, disassociating it | * Returns the given page to the free list, disassociating it | ||||
* from any VM object. | * from any VM object. | ||||
* | * | ||||
* The object must be locked. The page must be locked if it is | * The object must be locked. The page must be exclusively busied if it | ||||
* managed. | * belongs to an object. | ||||
*/ | */ | ||||
static void | static void | ||||
vm_page_free_toq(vm_page_t m) | vm_page_free_toq(vm_page_t m) | ||||
{ | { | ||||
struct vm_domain *vmd; | struct vm_domain *vmd; | ||||
uma_zone_t zone; | uma_zone_t zone; | ||||
if (!vm_page_free_prep(m)) | if (!vm_page_free_prep(m)) | ||||
Show All 12 Lines | |||||
} | } | ||||
/* | /* | ||||
* vm_page_free_pages_toq: | * vm_page_free_pages_toq: | ||||
* | * | ||||
* Returns a list of pages to the free list, disassociating it | * Returns a list of pages to the free list, disassociating it | ||||
* from any VM object. In other words, this is equivalent to | * from any VM object. In other words, this is equivalent to | ||||
* calling vm_page_free_toq() for each page of a list of VM objects. | * calling vm_page_free_toq() for each page of a list of VM objects. | ||||
* | |||||
* The objects must be locked. The pages must be locked if it is | |||||
* managed. | |||||
*/ | */ | ||||
void | void | ||||
vm_page_free_pages_toq(struct spglist *free, bool update_wire_count) | vm_page_free_pages_toq(struct spglist *free, bool update_wire_count) | ||||
{ | { | ||||
vm_page_t m; | vm_page_t m; | ||||
int count; | int count; | ||||
if (SLIST_EMPTY(free)) | if (SLIST_EMPTY(free)) | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* Release one wiring of the specified page, potentially allowing it to be | * Release one wiring of the specified page, potentially allowing it to be | ||||
* paged out. | * paged out. | ||||
* | * | ||||
* Only managed pages belonging to an object can be paged out. If the number | * Only managed pages belonging to an object can be paged out. If the number | ||||
* of wirings transitions to zero and the page is eligible for page out, then | * of wirings transitions to zero and the page is eligible for page out, then | ||||
* the page is added to the specified paging queue. If the released wiring | * the page is added to the specified paging queue. If the released wiring | ||||
* represented the last reference to the page, the page is freed. | * represented the last reference to the page, the page is freed. | ||||
* | |||||
* A managed page must be locked. | |||||
*/ | */ | ||||
void | void | ||||
vm_page_unwire(vm_page_t m, uint8_t nqueue) | vm_page_unwire(vm_page_t m, uint8_t nqueue) | ||||
{ | { | ||||
KASSERT(nqueue < PQ_COUNT, | KASSERT(nqueue < PQ_COUNT, | ||||
("vm_page_unwire: invalid queue %u request for page %p", | ("vm_page_unwire: invalid queue %u request for page %p", | ||||
nqueue, m)); | nqueue, m)); | ||||
Show All 30 Lines | vm_page_unwire_noq(vm_page_t m) | ||||
vm_wire_sub(1); | vm_wire_sub(1); | ||||
return (true); | return (true); | ||||
} | } | ||||
/* | /* | ||||
* Ensure that the page ends up in the specified page queue. If the page is | * Ensure that the page ends up in the specified page queue. If the page is | ||||
* active or being moved to the active queue, ensure that its act_count is | * active or being moved to the active queue, ensure that its act_count is | ||||
* at least ACT_INIT but do not otherwise mess with it. | * at least ACT_INIT but do not otherwise mess with it. | ||||
* | |||||
* A managed page must be locked. | |||||
*/ | */ | ||||
static __always_inline void | static __always_inline void | ||||
vm_page_mvqueue(vm_page_t m, const uint8_t nqueue, const uint16_t nflag) | vm_page_mvqueue(vm_page_t m, const uint8_t nqueue, const uint16_t nflag) | ||||
{ | { | ||||
vm_page_astate_t old, new; | vm_page_astate_t old, new; | ||||
KASSERT(m->ref_count > 0, | KASSERT(m->ref_count > 0, | ||||
("%s: page %p does not carry any references", __func__, m)); | ("%s: page %p does not carry any references", __func__, m)); | ||||
▲ Show 20 Lines • Show All 229 Lines • ▼ Show 20 Lines | vm_page_try_remove_write(vm_page_t m) | ||||
return (vm_page_try_blocked_op(m, pmap_remove_write)); | return (vm_page_try_blocked_op(m, pmap_remove_write)); | ||||
} | } | ||||
/* | /* | ||||
* vm_page_advise | * vm_page_advise | ||||
* | * | ||||
* Apply the specified advice to the given page. | * Apply the specified advice to the given page. | ||||
* | |||||
* The object and page must be locked. | |||||
*/ | */ | ||||
void | void | ||||
vm_page_advise(vm_page_t m, int advice) | vm_page_advise(vm_page_t m, int advice) | ||||
{ | { | ||||
VM_OBJECT_ASSERT_WLOCKED(m->object); | VM_OBJECT_ASSERT_WLOCKED(m->object); | ||||
vm_page_assert_xbusied(m); | |||||
if (advice == MADV_FREE) | if (advice == MADV_FREE) | ||||
/* | /* | ||||
* Mark the page clean. This will allow the page to be freed | * Mark the page clean. This will allow the page to be freed | ||||
* without first paging it out. MADV_FREE pages are often | * without first paging it out. MADV_FREE pages are often | ||||
* quickly reused by malloc(3), so we do not do anything that | * quickly reused by malloc(3), so we do not do anything that | ||||
* would result in a page fault on a later access. | * would result in a page fault on a later access. | ||||
*/ | */ | ||||
vm_page_undirty(m); | vm_page_undirty(m); | ||||
▲ Show 20 Lines • Show All 1,211 Lines • Show Last 20 Lines |