Modify vm_phys_unfree_page() so that it no longer requires the given

page to be in the free lists.  Instead, it now returns TRUE if it
removed the page from the free lists and FALSE if the page was not
in the free lists.

This change is required to support superpage reservations.  Specifically,
once reservations are introduced, a cached page can either be in the
free lists or a reservation.
This commit is contained in:
Alan Cox 2007-12-20 22:45:54 +00:00
parent 7439d1d9f0
commit e35395ce21
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=174821
3 changed files with 19 additions and 10 deletions

View File

@ -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);

View File

@ -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);
}
/*

View File

@ -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_ */