From b4d07d3c60449dde5c567aaeb2db0cd9f39547bd Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Mon, 16 May 2016 17:10:06 +0200 Subject: Fix pageout deadlock The pageout daemon uses small, internal, temporary objects to transport the data out to memory managers, which are expected to release the data once written out to backing store. Releasing this data is done with a vm_deallocate call. The problem with this is that vm_map is allowed to merge these objects, in which case vm_deallocate will only remove a reference instead of releasing the underlying pages, causing the pageout daemon to deadlock. This change makes the pageout daemon mark these objects so that they don't get merged. * vm/vm_object.c (vm_object_bootstrap): Update template. (vm_object_coalesce): Don't coalesce if an object is used for pageout. * vm/vm_object.h (struct vm_object): New `used_for_pageout` member. * vm/vm_pageout.c (vm_pageout_page): Mark new objects for pageout. --- vm/vm_object.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'vm/vm_object.c') diff --git a/vm/vm_object.c b/vm/vm_object.c index bc301288..046b6c49 100644 --- a/vm/vm_object.c +++ b/vm/vm_object.c @@ -302,6 +302,7 @@ void vm_object_bootstrap(void) vm_object_template.all_wanted = 0; /* all bits FALSE */ vm_object_template.paging_in_progress = 0; + vm_object_template.used_for_pageout = FALSE; vm_object_template.can_persist = FALSE; vm_object_template.cached = FALSE; vm_object_template.internal = TRUE; @@ -2742,6 +2743,7 @@ boolean_t vm_object_coalesce( if ((prev_object->ref_count > 1) || prev_object->pager_created || + prev_object->used_for_pageout || (prev_object->shadow != VM_OBJECT_NULL) || (prev_object->copy != VM_OBJECT_NULL) || (prev_object->paging_in_progress != 0)) { -- cgit v1.2.3