diff options
author | tegge <tegge@FreeBSD.org> | 2002-03-09 16:24:27 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 2002-03-09 16:24:27 +0000 |
commit | a814ebd3df242da0755ecde99c89f7b277ae092d (patch) | |
tree | 1d59aa957780d0a2624da02b166fc2771a918e9f /sys/vm/vm_kern.c | |
parent | 3adb054e5ad13b66111b6af08523e8e06ef490c3 (diff) | |
download | FreeBSD-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.c | 12 |
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; |