summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_kern.c
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>2002-03-09 16:24:27 +0000
committertegge <tegge@FreeBSD.org>2002-03-09 16:24:27 +0000
commita814ebd3df242da0755ecde99c89f7b277ae092d (patch)
tree1d59aa957780d0a2624da02b166fc2771a918e9f /sys/vm/vm_kern.c
parent3adb054e5ad13b66111b6af08523e8e06ef490c3 (diff)
downloadFreeBSD-src-a814ebd3df242da0755ecde99c89f7b277ae092d.zip
FreeBSD-src-a814ebd3df242da0755ecde99c89f7b277ae092d.tar.gz
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 <logan@mail.2cactus.com>, can be found in the freebsd-hackers mail archive (12 Apr 2001). The problem was recently noticed again by Archie Cobbs <archie@dellroad.org>. Reviewed by: dillon
Diffstat (limited to 'sys/vm/vm_kern.c')
-rw-r--r--sys/vm/vm_kern.c12
1 files changed, 12 insertions, 0 deletions
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;
OpenPOWER on IntegriCloud