git: 660344ca44c6 - main - Add a VM flag to prevent reclaim on a failed contig allocation

Ryan Stone rstone at FreeBSD.org
Wed Feb 3 21:18:11 UTC 2021


The branch main has been updated by rstone:

URL: https://cgit.FreeBSD.org/src/commit/?id=660344ca44c63bfe4a16c3e57d0f6dbcbb5e083e

commit 660344ca44c63bfe4a16c3e57d0f6dbcbb5e083e
Author:     Ryan Stone <rstone at FreeBSD.org>
AuthorDate: 2021-01-29 21:13:57 +0000
Commit:     Ryan Stone <rstone at FreeBSD.org>
CommitDate: 2021-02-03 21:16:51 +0000

    Add a VM flag to prevent reclaim on a failed contig allocation
    
    If a M_WAITOK contig alloc fails, the VM subsystem will try to
    reclaim contiguous memory twice before actually failing the
    request.  On a system with 64GB of RAM I've observed this take
    400-500ms before it finally gives up, and I believe that this
    will only be worse on systems with even more memory.
    
    In certain contexts this delay is extremely harmful, so add a flag
    that will skip reclaim for allocation requests to allow those
    paths to opt-out of doing an expensive reclaim.
    
    Sponsored by: Dell Inc
    Differential Revision:  https://reviews.freebsd.org/D28422
    Reviewed by: markj, kib
---
 sys/sys/malloc.h | 1 +
 sys/vm/vm_kern.c | 9 +++++++--
 sys/vm/vm_page.h | 3 +++
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
index a11dd767efc5..54a05e94a3a2 100644
--- a/sys/sys/malloc.h
+++ b/sys/sys/malloc.h
@@ -54,6 +54,7 @@
  */
 #define	M_NOWAIT	0x0001		/* do not block */
 #define	M_WAITOK	0x0002		/* ok to block */
+#define	M_NORECLAIM	0x0080		/* do not reclaim after failure */
 #define	M_ZERO		0x0100		/* bzero the allocation */
 #define	M_NOVM		0x0200		/* don't ask VM for pages */
 #define	M_USE_RESERVE	0x0400		/* can alloc out of reserve memory */
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index f1704f834157..e8e24c3ca8a3 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -177,17 +177,22 @@ kmem_alloc_contig_pages(vm_object_t object, vm_pindex_t pindex, int domain,
 {
 	vm_page_t m;
 	int tries;
-	bool wait;
+	bool wait, reclaim;
 
 	VM_OBJECT_ASSERT_WLOCKED(object);
 
+	/* Disallow an invalid combination of flags. */
+	MPASS((pflags & (VM_ALLOC_WAITOK | VM_ALLOC_NORECLAIM)) !=
+	    (VM_ALLOC_WAITOK | VM_ALLOC_NORECLAIM));
+
 	wait = (pflags & VM_ALLOC_WAITOK) != 0;
+	reclaim = (pflags & VM_ALLOC_NORECLAIM) == 0;
 	pflags &= ~(VM_ALLOC_NOWAIT | VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL);
 	pflags |= VM_ALLOC_NOWAIT;
 	for (tries = wait ? 3 : 1;; tries--) {
 		m = vm_page_alloc_contig_domain(object, pindex, domain, pflags,
 		    npages, low, high, alignment, boundary, memattr);
-		if (m != NULL || tries == 0)
+		if (m != NULL || tries == 0 || !reclaim)
 			break;
 
 		VM_OBJECT_WUNLOCK(object);
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index b05a3d1be861..ed372cae2a3b 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -541,6 +541,7 @@ vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
 #define	VM_ALLOC_WAITFAIL	0x0010	/* (acf) Sleep and return error */
 #define	VM_ALLOC_WIRED		0x0020	/* (acfgp) Allocate a wired page */
 #define	VM_ALLOC_ZERO		0x0040	/* (acfgp) Allocate a prezeroed page */
+#define	VM_ALLOC_NORECLAIM	0x0080	/* (c) Do not reclaim after failure */
 #define	VM_ALLOC_NOOBJ		0x0100	/* (acg) No associated object */
 #define	VM_ALLOC_NOBUSY		0x0200	/* (acgp) Do not excl busy the page */
 #define	VM_ALLOC_NOCREAT	0x0400	/* (gp) Don't create a page */
@@ -570,6 +571,8 @@ malloc2vm_flags(int malloc_flags)
 		pflags |= VM_ALLOC_NOWAIT;
 	if ((malloc_flags & M_WAITOK))
 		pflags |= VM_ALLOC_WAITOK;
+	if ((malloc_flags & M_NORECLAIM))
+		pflags |= VM_ALLOC_NORECLAIM;
 	return (pflags);
 }
 #endif


More information about the dev-commits-src-main mailing list