vm_fault_hold: handle vm_page_rename failure

On vm_page_rename failure, fix a missing object unlock and a double free of
a page.

First remove the old page, then rename into other page into first_object,
then free the old page.  This avoids the problem on rename failure.  This is
a little ugly but seems to be the most straightforward solution.

Tested with:
  $ sysctl debug.fail_point.uma_zalloc_arg="1%return"
  $ kyua test -k /usr/tests/sys/Kyuafile

Submitted by:	Ryan Libby <rlibby@gmail.com>
Reviewed by:	kib
Seen by:	alc
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D4326
This commit is contained in:
Conrad Meyer 2015-12-06 17:46:12 +00:00
parent 10386b56ad
commit 6fee422ed5

View File

@ -839,7 +839,7 @@ RetryFault:;
* get rid of the unnecessary page
*/
vm_page_lock(fs.first_m);
vm_page_free(fs.first_m);
vm_page_remove(fs.first_m);
vm_page_unlock(fs.first_m);
/*
* grab the page and put it into the
@ -848,9 +848,13 @@ RetryFault:;
*/
if (vm_page_rename(fs.m, fs.first_object,
fs.first_pindex)) {
VM_OBJECT_WUNLOCK(fs.first_object);
unlock_and_deallocate(&fs);
goto RetryFault;
}
vm_page_lock(fs.first_m);
vm_page_free(fs.first_m);
vm_page_unlock(fs.first_m);
#if VM_NRESERVLEVEL > 0
/*
* Rename the reservation.