From c78fe96446794f71a2db7d7e3d43cb15658590a3 Mon Sep 17 00:00:00 2001
From: Richard Braun <rbraun@sceen.net>
Date: Fri, 16 Sep 2016 04:39:02 +0200
Subject: VM: improve pageout deadlock workaround

Commit 5dd4f67522ad0d49a2cecdb9b109251f546d4dd1 makes VM map entry
allocation done with VM privilege, so that a VM map isn't held locked
while physical allocations are paused, which may block the default
pager during page eviction, causing a system-wide deadlock.

First, it turns out that map entries aren't the only buffers allocated,
and second, their number can't be easily determined, which makes a
preallocation strategy very hard to implement.

This change generalizes the strategy of VM privilege increase when a
VM map is locked.

* device/ds_routines.c (io_done_thread): Use integer values instead
of booleans when setting VM privilege.
* kern/thread.c (thread_init, thread_wire): Likewise.
* vm/vm_pageout.c (vm_pageout): Likewise.
* kern/thread.h (struct thread): Turn member `vm_privilege' into an
unsigned integer.
* vm/vm_map.c (vm_map_lock): New function, where VM privilege is
temporarily increased.
(vm_map_unlock): New function, where VM privilege is decreased.
(_vm_map_entry_create): Remove VM privilege workaround from this
function.
* vm/vm_map.h (vm_map_lock, vm_map_unlock): Turn into functions.
---
 vm/vm_map.h | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

(limited to 'vm/vm_map.h')

diff --git a/vm/vm_map.h b/vm/vm_map.h
index dad07139..537c36ef 100644
--- a/vm/vm_map.h
+++ b/vm/vm_map.h
@@ -352,13 +352,9 @@ MACRO_BEGIN					\
 	(map)->timestamp = 0;			\
 MACRO_END
 
-#define vm_map_lock(map)			\
-MACRO_BEGIN					\
-	lock_write(&(map)->lock);		\
-	(map)->timestamp++;			\
-MACRO_END
+void vm_map_lock(struct vm_map *map);
+void vm_map_unlock(struct vm_map *map);
 
-#define vm_map_unlock(map)	lock_write_done(&(map)->lock)
 #define vm_map_lock_read(map)	lock_read(&(map)->lock)
 #define vm_map_unlock_read(map)	lock_read_done(&(map)->lock)
 #define vm_map_lock_write_to_read(map) \
-- 
cgit v1.2.3