git: 92b9138991dd - main - vm: Introduce VM_ALLOC_NOFREE and PG_NOFREE

From: Bojan Novković <bnovkov_at_FreeBSD.org>
Date: Tue, 30 Jul 2024 15:38:45 UTC
The branch main has been updated by bnovkov:

URL: https://cgit.FreeBSD.org/src/commit/?id=92b9138991dd2829ac744592cb9f9f3415be146c

commit 92b9138991dd2829ac744592cb9f9f3415be146c
Author:     Bojan Novković <bnovkov@FreeBSD.org>
AuthorDate: 2024-07-14 13:13:56 +0000
Commit:     Bojan Novković <bnovkov@FreeBSD.org>
CommitDate: 2024-07-30 15:38:24 +0000

    vm: Introduce VM_ALLOC_NOFREE and PG_NOFREE
    
    This patch adds two additional vm_page flags to distinguish pages that
    never get released while the system is running (e.g. UMA_ZONE_NOFREE slabs).
    
    Differential Revision:  https://reviews.freebsd.org/D45970
    Reviewed by:    alc, kib, markj
    Tested by:      alc
---
 sys/vm/vm_page.c | 13 ++++++++++---
 sys/vm/vm_page.h |  5 ++++-
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 64413ba10bfa..3b6b88e4eb32 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2082,7 +2082,8 @@ vm_page_alloc_domain_after(vm_object_t object, vm_pindex_t pindex, int domain,
 #define	VPA_FLAGS	(VM_ALLOC_CLASS_MASK | VM_ALLOC_WAITFAIL |	\
 			 VM_ALLOC_NOWAIT | VM_ALLOC_NOBUSY |		\
 			 VM_ALLOC_SBUSY | VM_ALLOC_WIRED |		\
-			 VM_ALLOC_NODUMP | VM_ALLOC_ZERO | VM_ALLOC_COUNT_MASK)
+			 VM_ALLOC_NODUMP | VM_ALLOC_ZERO |		\
+			 VM_ALLOC_NOFREE | VM_ALLOC_COUNT_MASK)
 	KASSERT((req & ~VPA_FLAGS) == 0,
 	    ("invalid request %#x", req));
 	KASSERT(((req & (VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY)) !=
@@ -2154,6 +2155,8 @@ found:
 	flags |= m->flags & PG_ZERO;
 	if ((req & VM_ALLOC_NODUMP) != 0)
 		flags |= PG_NODUMP;
+	if ((req & VM_ALLOC_NOFREE) != 0)
+		flags |= PG_NOFREE;
 	m->flags = flags;
 	m->a.flags = 0;
 	m->oflags = (object->flags & OBJ_UNMANAGED) != 0 ? VPO_UNMANAGED : 0;
@@ -2418,11 +2421,13 @@ vm_page_alloc_noobj_domain(int domain, int req)
 #define	VPAN_FLAGS	(VM_ALLOC_CLASS_MASK | VM_ALLOC_WAITFAIL |      \
 			 VM_ALLOC_NOWAIT | VM_ALLOC_WAITOK |		\
 			 VM_ALLOC_NOBUSY | VM_ALLOC_WIRED |		\
-			 VM_ALLOC_NODUMP | VM_ALLOC_ZERO | VM_ALLOC_COUNT_MASK)
+			 VM_ALLOC_NODUMP | VM_ALLOC_ZERO |		\
+			 VM_ALLOC_NOFREE | VM_ALLOC_COUNT_MASK)
 	KASSERT((req & ~VPAN_FLAGS) == 0,
 	    ("invalid request %#x", req));
 
-	flags = (req & VM_ALLOC_NODUMP) != 0 ? PG_NODUMP : 0;
+	flags = ((req & VM_ALLOC_NODUMP) != 0 ? PG_NODUMP : 0) |
+	    ((req & VM_ALLOC_NOFREE) != 0 ? PG_NOFREE : 0);
 	vmd = VM_DOMAIN(domain);
 again:
 	if (vmd->vmd_pgcache[VM_FREEPOOL_DIRECT].zone != NULL) {
@@ -3937,6 +3942,8 @@ vm_page_free_prep(vm_page_t m)
 			    m, i, (uintmax_t)*p));
 	}
 #endif
+	KASSERT((m->flags & PG_NOFREE) == 0,
+	    ("%s: attempting to free a PG_NOFREE page", __func__));
 	if ((m->oflags & VPO_UNMANAGED) == 0) {
 		KASSERT(!pmap_page_is_mapped(m),
 		    ("vm_page_free_prep: freeing mapped page %p", m));
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 61a0228273c2..07a6c98c8ee8 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -457,6 +457,7 @@ extern struct mtx_padalign pa_lock[];
 #define	PG_ZERO		0x04		/* page is zeroed */
 #define	PG_MARKER	0x08		/* special queue marker page */
 #define	PG_NODUMP	0x10		/* don't include this page in a dump */
+#define	PG_NOFREE	0x20		/* page should never be freed. */
 
 /*
  * Misc constants.
@@ -537,7 +538,7 @@ vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
 #define	VM_ALLOC_WIRED		0x0020	/* (acgnp) Allocate a wired page */
 #define	VM_ALLOC_ZERO		0x0040	/* (acgnp) Allocate a zeroed page */
 #define	VM_ALLOC_NORECLAIM	0x0080	/* (c) Do not reclaim after failure */
-#define	VM_ALLOC_AVAIL0		0x0100
+#define	VM_ALLOC_NOFREE		0x0100	/* (an) Page will never be released */
 #define	VM_ALLOC_NOBUSY		0x0200	/* (acgp) Do not excl busy the page */
 #define	VM_ALLOC_NOCREAT	0x0400	/* (gp) Don't create a page */
 #define	VM_ALLOC_AVAIL1		0x0800
@@ -575,6 +576,8 @@ malloc2vm_flags(int malloc_flags)
 		pflags |= VM_ALLOC_WAITOK;
 	if ((malloc_flags & M_NORECLAIM))
 		pflags |= VM_ALLOC_NORECLAIM;
+	if ((malloc_flags & M_NEVERFREED))
+		pflags |= VM_ALLOC_NOFREE;
 	return (pflags);
 }
 #endif