From d07c5718060de7337ab278cfd1b0f7f0616493c0 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sat, 21 Dec 2019 19:04:05 +0000 Subject: [PATCH] Fix VPO_UNMANAGED handling in vm_page_reclaim_run() after r353540. When allocating a replacement page we must clear VPO_UNMANAGED since we only ever reclaim pages from managed objects. vm_page_replace() does not handle this for us. Sprinkle some assertions to help catch this sort of issue. Reported by: pho Reviewed by: alc, kib Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D22868 --- sys/vm/vm_page.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index a13a20cf1b41..d5ed9ea5ba3c 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1724,6 +1724,9 @@ vm_page_replace(vm_page_t mnew, vm_object_t object, vm_pindex_t pindex) mnew->pindex = pindex; atomic_set_int(&mnew->ref_count, VPRC_OBJREF); mold = vm_radix_replace(&object->rtree, mnew); + KASSERT((mold->oflags & VPO_UNMANAGED) == + (mnew->oflags & VPO_UNMANAGED), + ("vm_page_replace: mismatched VPO_UNMANAGED")); /* Keep the resident page list in sorted order. */ TAILQ_INSERT_AFTER(&object->memq, mold, mnew, listq); @@ -2684,8 +2687,7 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run, KASSERT(pmap_page_get_memattr(m) == VM_MEMATTR_DEFAULT, ("page %p has an unexpected memattr", m)); - KASSERT((m->oflags & (VPO_SWAPINPROG | - VPO_SWAPSLEEP | VPO_UNMANAGED)) == 0, + KASSERT(m->oflags == 0, ("page %p has unexpected oflags", m)); /* Don't care: PGA_NOSYNC. */ if (!vm_page_none_valid(m)) { @@ -2753,6 +2755,7 @@ vm_page_reclaim_run(int req_class, int domain, u_long npages, vm_page_t m_run, ~PGA_QUEUE_STATE_MASK; KASSERT(m_new->oflags == VPO_UNMANAGED, ("page %p is managed", m_new)); + m_new->oflags = 0; pmap_copy_page(m, m_new); m_new->valid = m->valid; m_new->dirty = m->dirty; @@ -3676,6 +3679,10 @@ vm_page_free_prep(vm_page_t m) panic("vm_page_free_prep: freeing shared busy page %p", m); if (m->object != NULL) { + KASSERT(((m->oflags & VPO_UNMANAGED) != 0) == + ((m->object->flags & OBJ_UNMANAGED) != 0), + ("vm_page_free_prep: managed flag mismatch for page %p", + m)); vm_page_object_remove(m); /*