From a814ebd3df242da0755ecde99c89f7b277ae092d Mon Sep 17 00:00:00 2001 From: tegge Date: Sat, 9 Mar 2002 16:24:27 +0000 Subject: Revert change in revision 1.53 and add a small comment to protect the revived code. vm pages newly allocated are marked busy (PG_BUSY), thus calling vm_page_delete before the pages has been freed or unbusied will cause a deadlock since vm_page_object_page_remove will wait for the busy flag to be cleared. This can be triggered by calling malloc with size > PAGE_SIZE and the M_NOWAIT flag on systems low on physical free memory. A kernel module that reproduces the problem, written by Logan Gabriel , can be found in the freebsd-hackers mail archive (12 Apr 2001). The problem was recently noticed again by Archie Cobbs . Reviewed by: dillon --- sys/vm/vm_kern.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'sys/vm/vm_kern.c') diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 2e5ea30..5a0dfda 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -378,6 +378,18 @@ retry: vm_map_lock(map); goto retry; } + /* + * Free the pages before removing the map entry. + * They are already marked busy. Calling + * vm_map_delete before the pages has been freed or + * unbusied will cause a deadlock. + */ + while (i != 0) { + i -= PAGE_SIZE; + m = vm_page_lookup(kmem_object, + OFF_TO_IDX(offset + i)); + vm_page_free(m); + } vm_map_delete(map, addr, addr + size); vm_map_unlock(map); goto bad; -- cgit v1.1