git: 92439940517b - main - vm_reserv: find reservations with iterators

From: Doug Moore <dougm_at_FreeBSD.org>
Date: Sun, 20 Apr 2025 19:54:18 UTC
The branch main has been updated by dougm:

URL: https://cgit.FreeBSD.org/src/commit/?id=92439940517ba57954f6b7f50545a43e506540f1

commit 92439940517ba57954f6b7f50545a43e506540f1
Author:     Doug Moore <dougm@FreeBSD.org>
AuthorDate: 2025-04-20 19:52:53 +0000
Commit:     Doug Moore <dougm@FreeBSD.org>
CommitDate: 2025-04-20 19:52:53 +0000

    vm_reserv: find reservations with iterators
    
    Instead of passing a preceding page to a vm _reserv alloc function,
    pass an iterator, and use the iterator to find the predecessor and
    successor.
    
    Reviewed by:    markj, kib
    Differential Revision:  https://reviews.freebsd.org/D49921
---
 sys/vm/vm_page.c   |  7 ++++---
 sys/vm/vm_reserv.c | 32 +++++++++++++++++---------------
 sys/vm/vm_reserv.h | 13 +++++++------
 3 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index db91b7bab2ab..6601ea23bf0e 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2182,7 +2182,7 @@ again:
 	 * Can we allocate the page from a reservation?
 	 */
 	if (vm_object_reserv(object) &&
-	    (m = vm_reserv_alloc_page(object, pindex, domain, req, mpred)) !=
+	    (m = vm_reserv_alloc_page(object, pages, pindex, domain, req)) !=
 	    NULL) {
 		goto found;
 	}
@@ -2418,8 +2418,9 @@ vm_page_alloc_contig_domain(vm_object_t object, vm_pindex_t pindex, int domain,
 		 * Can we allocate the pages from a reservation?
 		 */
 		if (vm_object_reserv(object) &&
-		    (m_ret = vm_reserv_alloc_contig(object, pindex, domain, req,
-		    mpred, npages, low, high, alignment, boundary)) != NULL) {
+		    (m_ret = vm_reserv_alloc_contig(object, &pages, pindex,
+		    domain, req, npages, low, high, alignment, boundary)) !=
+		    NULL) {
 			break;
 		}
 #endif
diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c
index e553d115a6d4..a562fd80b4a1 100644
--- a/sys/vm/vm_reserv.c
+++ b/sys/vm/vm_reserv.c
@@ -510,12 +510,13 @@ vm_reserv_from_page(vm_page_t m)
  * successor pointer.
  */
 static vm_reserv_t
-vm_reserv_from_object(vm_object_t object, vm_pindex_t pindex,
-    vm_page_t mpred, vm_page_t *msuccp)
+vm_reserv_from_object(vm_object_t object, struct pctrie_iter *pages,
+    vm_pindex_t pindex, vm_page_t *mpredp, vm_page_t *msuccp)
 {
 	vm_reserv_t rv;
-	vm_page_t msucc;
+	vm_page_t mpred, msucc;
 
+	mpred = vm_radix_iter_lookup_lt(pages, pindex);
 	if (mpred != NULL) {
 		KASSERT(mpred->object == object,
 		    ("vm_reserv_from_object: object doesn't contain mpred"));
@@ -524,9 +525,9 @@ vm_reserv_from_object(vm_object_t object, vm_pindex_t pindex,
 		rv = vm_reserv_from_page(mpred);
 		if (rv->object == object && vm_reserv_has_pindex(rv, pindex))
 			return (rv);
-		msucc = TAILQ_NEXT(mpred, listq);
-	} else
-		msucc = TAILQ_FIRST(&object->memq);
+	}
+
+	msucc = vm_radix_iter_lookup_ge(pages, pindex);
 	if (msucc != NULL) {
 		KASSERT(msucc->pindex > pindex,
 		    ("vm_reserv_from_object: msucc doesn't succeed pindex"));
@@ -534,6 +535,7 @@ vm_reserv_from_object(vm_object_t object, vm_pindex_t pindex,
 		if (rv->object == object && vm_reserv_has_pindex(rv, pindex))
 			return (rv);
 	}
+	*mpredp = mpred;
 	*msuccp = msucc;
 	return (NULL);
 }
@@ -683,13 +685,13 @@ vm_reserv_populate(vm_reserv_t rv, int index)
  * The object must be locked.
  */
 vm_page_t
-vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex, int domain,
-    int req, vm_page_t mpred, u_long npages, vm_paddr_t low, vm_paddr_t high,
-    u_long alignment, vm_paddr_t boundary)
+vm_reserv_alloc_contig(vm_object_t object, struct pctrie_iter *pages,
+    vm_pindex_t pindex, int domain, int req, u_long npages, vm_paddr_t low,
+    vm_paddr_t high, u_long alignment, vm_paddr_t boundary)
 {
 	struct vm_domain *vmd;
 	vm_paddr_t pa, size;
-	vm_page_t m, m_ret, msucc;
+	vm_page_t m, m_ret, mpred, msucc;
 	vm_pindex_t first;
 	vm_reserv_t rv;
 	u_long allocpages;
@@ -723,7 +725,7 @@ vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex, int domain,
 	/*
 	 * Look for an existing reservation.
 	 */
-	rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
+	rv = vm_reserv_from_object(object, pages, pindex, &mpred, &msucc);
 	if (rv != NULL) {
 		KASSERT(object != kernel_object || rv->domain == domain,
 		    ("vm_reserv_alloc_contig: domain mismatch"));
@@ -830,11 +832,11 @@ out:
  * The object must be locked.
  */
 vm_page_t
-vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex, int domain,
-    int req, vm_page_t mpred)
+vm_reserv_alloc_page(vm_object_t object, struct pctrie_iter *pages,
+    vm_pindex_t pindex, int domain, int req)
 {
 	struct vm_domain *vmd;
-	vm_page_t m, msucc;
+	vm_page_t m, mpred, msucc;
 	vm_pindex_t first;
 	vm_reserv_t rv;
 	int index;
@@ -851,7 +853,7 @@ vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex, int domain,
 	/*
 	 * Look for an existing reservation.
 	 */
-	rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
+	rv = vm_reserv_from_object(object, pages, pindex, &mpred, &msucc);
 	if (rv != NULL) {
 		KASSERT(object != kernel_object || rv->domain == domain,
 		    ("vm_reserv_alloc_page: domain mismatch"));
diff --git a/sys/vm/vm_reserv.h b/sys/vm/vm_reserv.h
index 98780efc9d37..1dcf09e6c736 100644
--- a/sys/vm/vm_reserv.h
+++ b/sys/vm/vm_reserv.h
@@ -45,12 +45,13 @@
 /*
  * The following functions are only to be used by the virtual memory system.
  */
-vm_page_t	vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex,
-		    int domain, int req, vm_page_t mpred, u_long npages,
-		    vm_paddr_t low, vm_paddr_t high, u_long alignment,
-		    vm_paddr_t boundary);
-vm_page_t	vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex,
-		    int domain, int req, vm_page_t mpred);
+vm_page_t	vm_reserv_alloc_contig(vm_object_t object,
+		    struct pctrie_iter *pages, vm_pindex_t pindex, int domain,
+		    int req, u_long npages, vm_paddr_t low, vm_paddr_t high,
+		    u_long alignment, vm_paddr_t boundary);
+vm_page_t	vm_reserv_alloc_page(vm_object_t object,
+		    struct pctrie_iter *pages, vm_pindex_t pindex, int domain,
+		    int req);
 void		vm_reserv_break_all(vm_object_t object);
 boolean_t	vm_reserv_free_page(vm_page_t m);
 void		vm_reserv_init(void);