git: 742e58ddc989 - main - vm_page: Fix the error path in vm_page_alloc_contig_domain()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 24 Sep 2026 15:52:07 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=742e58ddc989563f90a1d636cb29793641784ca1

commit 742e58ddc989563f90a1d636cb29793641784ca1
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-09-24 15:49:37 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-24 15:51:06 +0000

    vm_page: Fix the error path in vm_page_alloc_contig_domain()
    
    If we are inserting a run of pages into a VM object and fail at some
    point due to a memory allocation failure, we have to free all of the
    pages in the run.  We do that by resetting some fields and calling
    vm_page_free_toq() on each page; this removes the page from the object
    and frees it back to the buddy allocator.
    
    If the page is supposed to be wired, we reset the reference count, but
    this was done incorrectly: the VPRC_OBJREF flag must be retained as the
    page still belongs to an object.  Resetting it to zero will cause a
    panic in vm_page_free_prep(): vm_page_free_object_prep() will subtract
    VPRC_OBJREF from the refcount, causing underflow, and
    vm_page_free_prep() subsequently calls panic() if the refcount is
    non-zero.
    
    Reviewed by:    alc, kib
    Fixes:          fee2a2fa3983 ("Change synchonization rules for vm_page reference counting.")
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D59908
---
 sys/vm/vm_page.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 98d0472c8487..251d01221af7 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2432,7 +2432,7 @@ vm_page_alloc_contig_domain(vm_object_t object, vm_pindex_t pindex, int domain,
 			for (m = m_ret; m < &m_ret[npages]; m++) {
 				if (m <= mpred &&
 				    (req & VM_ALLOC_WIRED) != 0)
-					m->ref_count = 0;
+					m->ref_count = VPRC_OBJREF;
 				m->oflags = VPO_UNMANAGED;
 				m->busy_lock = VPB_UNBUSIED;
 				/* Don't change PG_ZERO. */