diff options
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/vm_page.c | 7 | ||||
-rw-r--r-- | sys/vm/vm_phys.c | 17 | ||||
-rw-r--r-- | sys/vm/vm_phys.h | 5 |
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_ */ |