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:
parent
f2c819bf2b
commit
ff91d7800f
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user