Restructure vm_page_select_cache() so that adding assertions is easy.
Some of the conditions that caused vm_page_select_cache() to deactivate a page were wrong. For example, deactivating an unmanaged or wired page is a nop. Thus, if vm_page_select_cache() had ever encountered an unmanaged or wired page, it would have looped forever. Now, we assert that the page is neither unmanaged nor wired.
This commit is contained in:
parent
14bc83bc9c
commit
625c8dfb26
@ -708,17 +708,23 @@ vm_page_select_cache(int color)
|
||||
vm_page_t m;
|
||||
|
||||
mtx_assert(&vm_page_queue_mtx, MA_OWNED);
|
||||
while (TRUE) {
|
||||
m = vm_pageq_find(PQ_CACHE, color, FALSE);
|
||||
if (m && ((m->flags & (PG_BUSY|PG_UNMANAGED)) || m->busy ||
|
||||
m->hold_count || m->wire_count ||
|
||||
(!VM_OBJECT_TRYLOCK(m->object) &&
|
||||
!VM_OBJECT_LOCKED(m->object)))) {
|
||||
vm_page_deactivate(m);
|
||||
continue;
|
||||
while ((m = vm_pageq_find(PQ_CACHE, color, FALSE)) != NULL) {
|
||||
if ((m->flags & PG_BUSY) == 0 && m->busy == 0 &&
|
||||
m->hold_count == 0 && (VM_OBJECT_TRYLOCK(m->object) ||
|
||||
VM_OBJECT_LOCKED(m->object))) {
|
||||
KASSERT(m->dirty == 0,
|
||||
("Found dirty cache page %p", m));
|
||||
KASSERT(!pmap_page_is_mapped(m),
|
||||
("Found mapped cache page %p", m));
|
||||
KASSERT((m->flags & PG_UNMANAGED) == 0,
|
||||
("Found unmanaged cache page %p", m));
|
||||
KASSERT(m->wire_count == 0,
|
||||
("Found wired cache page %p", m));
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
vm_page_deactivate(m);
|
||||
}
|
||||
return (m);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -795,7 +801,6 @@ vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
|
||||
pagedaemon_wakeup();
|
||||
return (NULL);
|
||||
}
|
||||
KASSERT(m->dirty == 0, ("Found dirty cache page %p", m));
|
||||
m_object = m->object;
|
||||
VM_OBJECT_LOCK_ASSERT(m_object, MA_OWNED);
|
||||
vm_page_busy(m);
|
||||
|
Loading…
Reference in New Issue
Block a user