summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_page.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2013-08-15 11:01:25 +0000
committerattilio <attilio@FreeBSD.org>2013-08-15 11:01:25 +0000
commitae49aeaba62c1f7009421f40d601061db0b3eefe (patch)
tree1e1dd3e40523f3eb8a564c2fad3920fe3917b97c /sys/vm/vm_page.c
parentb6945a92d66d759606a00571506ccf47e63d6961 (diff)
downloadFreeBSD-src-ae49aeaba62c1f7009421f40d601061db0b3eefe.zip
FreeBSD-src-ae49aeaba62c1f7009421f40d601061db0b3eefe.tar.gz
On the recovery path for vm_page_alloc(), if a page had been requested
wired, unwind back the wiring bits otherwise we can end up freeing a page that is considered wired. Sponsored by: EMC / Isilon storage division Reported by: alc
Diffstat (limited to 'sys/vm/vm_page.c')
-rw-r--r--sys/vm/vm_page.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 0336e04..44a57fe 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1611,6 +1611,10 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
if (vp != NULL)
vdrop(vp);
pagedaemon_wakeup();
+ if (req & VM_ALLOC_WIRED) {
+ atomic_subtract_int(&cnt.v_wire_count, 1);
+ m->wire_count = 0;
+ }
m->object = NULL;
vm_page_free(m);
return (NULL);
@@ -1806,8 +1810,13 @@ retry:
&deferred_vdrop_list);
if (vm_paging_needed())
pagedaemon_wakeup();
+ if ((req & VM_ALLOC_WIRED) != 0)
+ atomic_subtract_int(&cnt.v_wire_count,
+ npages);
for (m_tmp = m, m = m_ret;
m < &m_ret[npages]; m++) {
+ if ((req & VM_ALLOC_WIRED) != 0)
+ m->wire_count = 0;
if (m >= m_tmp)
m->object = NULL;
vm_page_free(m);
OpenPOWER on IntegriCloud