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_page.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_page.c')
-rw-r--r-- | vm/vm_page.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/vm/vm_page.c b/vm/vm_page.c index a7dab114..9a7fa275 100644 --- a/vm/vm_page.c +++ b/vm/vm_page.c @@ -313,7 +313,6 @@ vm_page_can_move(const struct vm_page *page) */ return !page->busy - && !page->external_laundry && !page->wanted && !page->absent && page->object->alive; @@ -1157,26 +1156,19 @@ restart: * fault could occur, during which the map would be locked. * This fault would cause a new paging request to the default * pager. Receiving that request would deadlock when trying to - * lock the map again. Instead, the page isn't double paged. - * The external_laundry bit is set to indicate this situation - * to vm_pageout_setup. + * lock the map again. Instead, the page isn't double paged + * and vm_pageout_setup wires the page down, trusting the + * default pager as for internal pages. */ - assert(!page->laundry && !page->external_laundry); + assert(!page->laundry); assert(!(double_paging && page->external)); - if (object->internal) { + if (object->internal || !alloc_paused || + memory_manager_default_port(object->pager)) { double_paging = FALSE; } else { - if (memory_manager_default_port(object->pager)) { - double_paging = FALSE; - page->external_laundry = TRUE; - } else if (!alloc_paused) { - double_paging = FALSE; - } else { - double_paging = TRUE; - page->laundry = TRUE; - } + double_paging = page->laundry = TRUE; } out: |