diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h --- 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 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -177,17 +177,22 @@ { 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 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -541,6 +541,7 @@ #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 @@ 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