mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-30 16:51:41 +00:00
Add a helper function to the swapout daemon's deactivation code.
vm_swapout_object_deactivate_pages() is renamed to vm_swapout_object_deactivate(), and the loop body is moved into the new vm_swapout_object_deactivate_page(). This makes the code a bit easier to follow and is in preparation for some functional changes. Reviewed by: jeff, kib Sponsored by: Netflix, Intel Differential Revision: https://reviews.freebsd.org/D22651
This commit is contained in:
parent
5cff1f4dc3
commit
9be9ea420e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=355587
@ -165,13 +165,64 @@ static int last_swapin;
|
|||||||
static void swapclear(struct proc *);
|
static void swapclear(struct proc *);
|
||||||
static int swapout(struct proc *);
|
static int swapout(struct proc *);
|
||||||
static void vm_swapout_map_deactivate_pages(vm_map_t, long);
|
static void vm_swapout_map_deactivate_pages(vm_map_t, long);
|
||||||
static void vm_swapout_object_deactivate_pages(pmap_t, vm_object_t, long);
|
static void vm_swapout_object_deactivate(pmap_t, vm_object_t, long);
|
||||||
static void swapout_procs(int action);
|
static void swapout_procs(int action);
|
||||||
static void vm_req_vmdaemon(int req);
|
static void vm_req_vmdaemon(int req);
|
||||||
static void vm_thread_swapout(struct thread *td);
|
static void vm_thread_swapout(struct thread *td);
|
||||||
|
|
||||||
|
static void
|
||||||
|
vm_swapout_object_deactivate_page(pmap_t pmap, vm_page_t m, bool unmap)
|
||||||
|
{
|
||||||
|
int act_delta;
|
||||||
|
|
||||||
|
if (vm_page_tryxbusy(m) == 0)
|
||||||
|
return;
|
||||||
|
VM_CNT_INC(v_pdpages);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The page may acquire a wiring after this check.
|
||||||
|
* The page daemon handles wired pages, so there is
|
||||||
|
* no harm done if a wiring appears while we are
|
||||||
|
* attempting to deactivate the page.
|
||||||
|
*/
|
||||||
|
if (vm_page_wired(m) || !pmap_page_exists_quick(pmap, m)) {
|
||||||
|
vm_page_xunbusy(m);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
act_delta = pmap_ts_referenced(m);
|
||||||
|
vm_page_lock(m);
|
||||||
|
if ((m->a.flags & PGA_REFERENCED) != 0) {
|
||||||
|
if (act_delta == 0)
|
||||||
|
act_delta = 1;
|
||||||
|
vm_page_aflag_clear(m, PGA_REFERENCED);
|
||||||
|
}
|
||||||
|
if (!vm_page_active(m) && act_delta != 0) {
|
||||||
|
vm_page_activate(m);
|
||||||
|
m->a.act_count += act_delta;
|
||||||
|
} else if (vm_page_active(m)) {
|
||||||
|
/*
|
||||||
|
* The page daemon does not requeue pages
|
||||||
|
* after modifying their activation count.
|
||||||
|
*/
|
||||||
|
if (act_delta == 0) {
|
||||||
|
m->a.act_count -= min(m->a.act_count, ACT_DECLINE);
|
||||||
|
if (unmap && m->a.act_count == 0) {
|
||||||
|
(void)vm_page_try_remove_all(m);
|
||||||
|
vm_page_deactivate(m);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
vm_page_activate(m);
|
||||||
|
if (m->a.act_count < ACT_MAX - ACT_ADVANCE)
|
||||||
|
m->a.act_count += ACT_ADVANCE;
|
||||||
|
}
|
||||||
|
} else if (vm_page_inactive(m))
|
||||||
|
(void)vm_page_try_remove_all(m);
|
||||||
|
vm_page_unlock(m);
|
||||||
|
vm_page_xunbusy(m);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vm_swapout_object_deactivate_pages
|
* vm_swapout_object_deactivate
|
||||||
*
|
*
|
||||||
* Deactivate enough pages to satisfy the inactive target
|
* Deactivate enough pages to satisfy the inactive target
|
||||||
* requirements.
|
* requirements.
|
||||||
@ -179,12 +230,12 @@ static void vm_thread_swapout(struct thread *td);
|
|||||||
* The object and map must be locked.
|
* The object and map must be locked.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vm_swapout_object_deactivate_pages(pmap_t pmap, vm_object_t first_object,
|
vm_swapout_object_deactivate(pmap_t pmap, vm_object_t first_object,
|
||||||
long desired)
|
long desired)
|
||||||
{
|
{
|
||||||
vm_object_t backing_object, object;
|
vm_object_t backing_object, object;
|
||||||
vm_page_t p;
|
vm_page_t m;
|
||||||
int act_delta, remove_mode;
|
bool unmap;
|
||||||
|
|
||||||
VM_OBJECT_ASSERT_LOCKED(first_object);
|
VM_OBJECT_ASSERT_LOCKED(first_object);
|
||||||
if ((first_object->flags & OBJ_FICTITIOUS) != 0)
|
if ((first_object->flags & OBJ_FICTITIOUS) != 0)
|
||||||
@ -197,63 +248,19 @@ vm_swapout_object_deactivate_pages(pmap_t pmap, vm_object_t first_object,
|
|||||||
REFCOUNT_COUNT(object->paging_in_progress) > 0)
|
REFCOUNT_COUNT(object->paging_in_progress) > 0)
|
||||||
goto unlock_return;
|
goto unlock_return;
|
||||||
|
|
||||||
remove_mode = 0;
|
unmap = true;
|
||||||
if (object->shadow_count > 1)
|
if (object->shadow_count > 1)
|
||||||
remove_mode = 1;
|
unmap = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan the object's entire memory queue.
|
* Scan the object's entire memory queue.
|
||||||
*/
|
*/
|
||||||
TAILQ_FOREACH(p, &object->memq, listq) {
|
TAILQ_FOREACH(m, &object->memq, listq) {
|
||||||
if (pmap_resident_count(pmap) <= desired)
|
if (pmap_resident_count(pmap) <= desired)
|
||||||
goto unlock_return;
|
goto unlock_return;
|
||||||
if (should_yield())
|
if (should_yield())
|
||||||
goto unlock_return;
|
goto unlock_return;
|
||||||
if (vm_page_tryxbusy(p) == 0)
|
vm_swapout_object_deactivate_page(pmap, m, unmap);
|
||||||
continue;
|
|
||||||
VM_CNT_INC(v_pdpages);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The page may acquire a wiring after this check.
|
|
||||||
* The page daemon handles wired pages, so there is
|
|
||||||
* no harm done if a wiring appears while we are
|
|
||||||
* attempting to deactivate the page.
|
|
||||||
*/
|
|
||||||
if (vm_page_wired(p) || !pmap_page_exists_quick(pmap, p)) {
|
|
||||||
vm_page_xunbusy(p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
act_delta = pmap_ts_referenced(p);
|
|
||||||
vm_page_lock(p);
|
|
||||||
if ((p->a.flags & PGA_REFERENCED) != 0) {
|
|
||||||
if (act_delta == 0)
|
|
||||||
act_delta = 1;
|
|
||||||
vm_page_aflag_clear(p, PGA_REFERENCED);
|
|
||||||
}
|
|
||||||
if (!vm_page_active(p) && act_delta != 0) {
|
|
||||||
vm_page_activate(p);
|
|
||||||
p->a.act_count += act_delta;
|
|
||||||
} else if (vm_page_active(p)) {
|
|
||||||
/*
|
|
||||||
* The page daemon does not requeue pages
|
|
||||||
* after modifying their activation count.
|
|
||||||
*/
|
|
||||||
if (act_delta == 0) {
|
|
||||||
p->a.act_count -= min(p->a.act_count,
|
|
||||||
ACT_DECLINE);
|
|
||||||
if (!remove_mode && p->a.act_count == 0) {
|
|
||||||
(void)vm_page_try_remove_all(p);
|
|
||||||
vm_page_deactivate(p);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
vm_page_activate(p);
|
|
||||||
if (p->a.act_count < ACT_MAX -
|
|
||||||
ACT_ADVANCE)
|
|
||||||
p->a.act_count += ACT_ADVANCE;
|
|
||||||
}
|
|
||||||
} else if (vm_page_inactive(p))
|
|
||||||
(void)vm_page_try_remove_all(p);
|
|
||||||
vm_page_unlock(p);
|
|
||||||
vm_page_xunbusy(p);
|
|
||||||
}
|
}
|
||||||
if ((backing_object = object->backing_object) == NULL)
|
if ((backing_object = object->backing_object) == NULL)
|
||||||
goto unlock_return;
|
goto unlock_return;
|
||||||
@ -307,7 +314,7 @@ vm_swapout_map_deactivate_pages(vm_map_t map, long desired)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bigobj != NULL) {
|
if (bigobj != NULL) {
|
||||||
vm_swapout_object_deactivate_pages(map->pmap, bigobj, desired);
|
vm_swapout_object_deactivate(map->pmap, bigobj, desired);
|
||||||
VM_OBJECT_RUNLOCK(bigobj);
|
VM_OBJECT_RUNLOCK(bigobj);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -321,8 +328,8 @@ vm_swapout_map_deactivate_pages(vm_map_t map, long desired)
|
|||||||
obj = tmpe->object.vm_object;
|
obj = tmpe->object.vm_object;
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
VM_OBJECT_RLOCK(obj);
|
VM_OBJECT_RLOCK(obj);
|
||||||
vm_swapout_object_deactivate_pages(map->pmap,
|
vm_swapout_object_deactivate(map->pmap, obj,
|
||||||
obj, desired);
|
desired);
|
||||||
VM_OBJECT_RUNLOCK(obj);
|
VM_OBJECT_RUNLOCK(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user