summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/vm/vm_page.c7
-rw-r--r--sys/vm/vm_phys.c17
-rw-r--r--sys/vm/vm_phys.h5
3 files changed, 19 insertions, 10 deletions
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 4e68410..622f5fd 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -1026,8 +1026,11 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
mtx_unlock(&vm_page_queue_free_mtx);
return (NULL);
}
- vm_phys_unfree_page(m);
- vm_phys_set_pool(VM_FREEPOOL_DEFAULT, m, 0);
+ if (vm_phys_unfree_page(m))
+ vm_phys_set_pool(VM_FREEPOOL_DEFAULT, m, 0);
+ else
+ panic("vm_page_alloc: cache page %p is missing"
+ " from the free queue", m);
} else if ((req & VM_ALLOC_IFCACHED) != 0) {
mtx_unlock(&vm_page_queue_free_mtx);
return (NULL);
diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c
index 0fb685e..a57304b 100644
--- a/sys/vm/vm_phys.c
+++ b/sys/vm/vm_phys.c
@@ -468,7 +468,7 @@ vm_phys_set_pool(int pool, vm_page_t m, int order)
*
* The free page queues must be locked.
*/
-void
+boolean_t
vm_phys_unfree_page(vm_page_t m)
{
struct vm_freelist *fl;
@@ -489,13 +489,15 @@ vm_phys_unfree_page(vm_page_t m)
order < VM_NFREEORDER - 1; ) {
order++;
pa = m->phys_addr & (~(vm_paddr_t)0 << (PAGE_SHIFT + order));
- KASSERT(pa >= seg->start && pa < seg->end,
- ("vm_phys_unfree_page: paddr %#jx is not within segment %p",
- (uintmax_t)pa, seg));
- m_set = &seg->first_page[atop(pa - seg->start)];
+ if (pa >= seg->start && pa < seg->end)
+ m_set = &seg->first_page[atop(pa - seg->start)];
+ else
+ return (FALSE);
}
- KASSERT(m_set->order >= order, ("vm_phys_unfree_page: page %p's order"
- " (%d) is less than expected (%d)", m_set, m_set->order, order));
+ if (m_set->order < order)
+ return (FALSE);
+ if (m_set->order == VM_NFREEORDER)
+ return (FALSE);
KASSERT(m_set->order < VM_NFREEORDER,
("vm_phys_unfree_page: page %p has unexpected order %d",
m_set, m_set->order));
@@ -525,6 +527,7 @@ vm_phys_unfree_page(vm_page_t m)
fl[order].lcnt++;
}
KASSERT(m_set == m, ("vm_phys_unfree_page: fatal inconsistency"));
+ return (TRUE);
}
/*
diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h
index 3e35f9b..0e012c3 100644
--- a/sys/vm/vm_phys.h
+++ b/sys/vm/vm_phys.h
@@ -38,6 +38,8 @@
#ifndef _VM_PHYS_H_
#define _VM_PHYS_H_
+#ifdef _KERNEL
+
void vm_phys_add_page(vm_paddr_t pa);
vm_page_t vm_phys_alloc_contig(unsigned long npages,
vm_paddr_t low, vm_paddr_t high,
@@ -47,7 +49,8 @@ vm_paddr_t vm_phys_bootstrap_alloc(vm_size_t size, unsigned long alignment);
void vm_phys_free_pages(vm_page_t m, int order);
void vm_phys_init(void);
void vm_phys_set_pool(int pool, vm_page_t m, int order);
-void vm_phys_unfree_page(vm_page_t m);
+boolean_t vm_phys_unfree_page(vm_page_t m);
boolean_t vm_phys_zero_pages_idle(void);
+#endif /* _KERNEL */
#endif /* !_VM_PHYS_H_ */
OpenPOWER on IntegriCloud