From 5dd4f67522ad0d49a2cecdb9b109251f546d4dd1 Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Sat, 23 Jul 2016 00:52:47 +0200 Subject: VM: fix pageout-related deadlock * vm/vm_map.c (_vm_map_entry_create): Temporarily set the current thread as VM privileged. --- vm/vm_map.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'vm/vm_map.c') diff --git a/vm/vm_map.c b/vm/vm_map.c index ccbe8f1a..acac66e4 100644 --- a/vm/vm_map.c +++ b/vm/vm_map.c @@ -241,8 +241,26 @@ vm_map_entry_t _vm_map_entry_create(map_header) const struct vm_map_header *map_header; { vm_map_entry_t entry; + boolean_t vm_privilege; + /* + * XXX Map entry creation may occur while a map is locked, + * for example when clipping entries. If the system is running + * low on memory, allocating an entry may block until pages + * are available. But if a map used by the default pager is + * kept locked, a deadlock occurs. + * + * This workaround temporarily elevates the current thread + * VM privileges to avoid that particular deadlock, and does + * so regardless of the map for convenience, and because it's + * currently impossible to predict which map the default pager + * may depend on. + */ + vm_privilege = current_thread()->vm_privilege; + current_thread()->vm_privilege = TRUE; entry = (vm_map_entry_t) kmem_cache_alloc(&vm_map_entry_cache); + current_thread()->vm_privilege = vm_privilege; + if (entry == VM_MAP_ENTRY_NULL) panic("vm_map_entry_create"); -- cgit v1.2.3