diff options
author | Richard Braun <rbraun@sceen.net> | 2016-12-27 19:51:30 +0100 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2016-12-27 19:51:30 +0100 |
commit | 941d462425fb2692fd9ffea1ab03e927697fcfb0 (patch) | |
tree | 7f18f1b5c1f3f7ec5fc410b3e08310d893ad0e32 /vm/vm_pageout.c | |
parent | a926bb3a5bbd9cd5db6f1435d32312a5499ed62d (diff) | |
download | gnumach-941d462425fb2692fd9ffea1ab03e927697fcfb0.tar.gz gnumach-941d462425fb2692fd9ffea1ab03e927697fcfb0.tar.bz2 gnumach-941d462425fb2692fd9ffea1ab03e927697fcfb0.zip |
VM: really fix pageout of external objects backed by the default pager
Commit eb07428ffb0009085fcd01dd1b79d9953af8e0ad does fix pageout of
external objects backed by the default pager, but the way it's done
has a vicious side effect: because they're considered external, the
pageout daemon can keep evicting them even though the external pagers
haven't released them, unlike internal pages which must all be
released before the pageout daemon can make progress. This can lead
to a situation where too many pages become wired, the default pager
cannot allocate memory to process new requests, and the pageout
daemon cannot recycle any more page, causing a panic.
This change makes the pageout daemon use the same strategy for both
internal pages and external pages sent to the default pager: use
the laundry bit and wait for all laundry pages to be released,
thereby completely synchronizing the pageout daemon and the default
pager.
* vm/vm_page.c (vm_page_can_move): Allow external laundry pages to
be moved.
(vm_page_seg_evict): Don't alter the `external_laundry' bit, merely
disable double paging for external pages sent to the default pager.
* vm/vm_pageout.c: Include vm/memory_object.h.
(vm_pageout_setup): Don't check whether the `external_laundry' bit
is set, but handle external pages sent to the default pager the same
as internal pages.
Diffstat (limited to 'vm/vm_pageout.c')
-rw-r--r-- | vm/vm_pageout.c | 13 |
1 files changed, 3 insertions, 10 deletions
diff --git a/vm/vm_pageout.c b/vm/vm_pageout.c index 62a27f1a..575a9f5d 100644 --- a/vm/vm_pageout.c +++ b/vm/vm_pageout.c @@ -47,6 +47,7 @@ #include <kern/task.h> #include <kern/thread.h> #include <kern/printf.h> +#include <vm/memory_object.h> #include <vm/pmap.h> #include <vm/vm_map.h> #include <vm/vm_object.h> @@ -253,21 +254,13 @@ vm_pageout_setup( assert(!old_object->internal); m->laundry = FALSE; - } else if (old_object->internal) { + } else if (old_object->internal || + memory_manager_default_port(old_object->pager)) { m->laundry = TRUE; vm_page_laundry_count++; vm_page_wire(m); } else { - /* - * The caller is telling us that this page belongs - * to an external object managed by the default pager. - * Wire it to avoid a deadlock on the default pager map. - */ - if (m->external_laundry) { - vm_page_wire(m); - } - m->external_laundry = TRUE; /* |