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
This commit is contained in:
Tor Egge 2002-03-09 16:24:27 +00:00
parent f2c819bf2b
commit ff91d7800f

View File

@ -378,6 +378,18 @@ kmem_malloc(map, size, flags)
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;