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
This commit is contained in:
parent
8727c174b0
commit
660344ca44
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user