Index: share/man/man9/Makefile =================================================================== --- share/man/man9/Makefile +++ share/man/man9/Makefile @@ -1287,6 +1287,7 @@ make_dev.9 make_dev_s.9 MLINKS+=malloc.9 free.9 \ malloc.9 malloc_domain.9 \ + malloc.9 malloc_domainset.9 \ malloc.9 free_domain.9 \ malloc.9 mallocarray.9 \ malloc.9 MALLOC_DECLARE.9 \ Index: share/man/man9/domainset.9 =================================================================== --- share/man/man9/domainset.9 +++ share/man/man9/domainset.9 @@ -127,6 +127,7 @@ .Xr cpuset 2 , .Xr cpuset_setdomain 2 , .Xr bitset 9 +.Xr malloc_domainset 9 , .Sh HISTORY .In sys/domainset.h first appeared in Index: share/man/man9/malloc.9 =================================================================== --- share/man/man9/malloc.9 +++ share/man/man9/malloc.9 @@ -29,7 +29,7 @@ .\" $NetBSD: malloc.9,v 1.3 1996/11/11 00:05:11 lukem Exp $ .\" $FreeBSD$ .\" -.Dd June 13, 2018 +.Dd September 28, 2018 .Dt MALLOC 9 .Os .Sh NAME @@ -71,11 +71,15 @@ .Pp The .Fn malloc_domain -variant allocates the object from the specified memory domain. Memory allocated -with this function should be returned with +variant permit allocations from a specific +.Xr numa 9 +domain. +.Fn malloc_domain +will attempt to allocate memory from the specified domain, and will fall +back to other domains if the specified domain does not contain sufficient +free memory. +Memory allocated with this function should be freed with .Fn free_domain . -See -.Xr numa 9 for more details. .Pp The .Fn mallocarray @@ -312,5 +316,7 @@ .Sh SEE ALSO .Xr vmstat 8 , .Xr contigmalloc 9 , +.Xr domainset 9 , .Xr memguard 9 , +.Xr numa 9 , .Xr vnode 9 Index: sys/kern/kern_malloc.c =================================================================== --- sys/kern/kern_malloc.c +++ sys/kern/kern_malloc.c @@ -68,6 +68,7 @@ #include #include +#include #include #include #include @@ -596,21 +597,23 @@ } void * -malloc_domain(size_t size, struct malloc_type *mtp, int domain, - int flags) +malloc_domain(size_t size, struct malloc_type *mtp, int domain, int flags) { - int indx; - caddr_t va; + struct vm_domainset_iter di; uma_zone_t zone; #if defined(DEBUG_REDZONE) unsigned long osize = size; #endif + caddr_t va; + int indx; #ifdef MALLOC_DEBUG va = NULL; if (malloc_dbg(&va, &size, mtp, flags) != 0) return (va); #endif + vm_domainset_iter_policy_init(&di, DOMAINSET_PREF(domain), + &domain, &flags); if (size <= kmem_zmax && (flags & M_EXEC) == 0) { if (size & KMEM_ZMASK) size = (size & ~KMEM_ZMASK) + KMEM_ZBASE; @@ -619,14 +622,22 @@ #ifdef MALLOC_PROFILE krequests[size >> KMEM_ZSHIFT]++; #endif - va = uma_zalloc_domain(zone, NULL, domain, flags); - if (va != NULL) - size = zone->uz_size; + do { + va = uma_zalloc_domain(zone, NULL, domain, flags); + if (va != NULL) { + size = zone->uz_size; + break; + } + } while (vm_domainset_iter_policy(&di, &domain) == 0); malloc_type_zone_allocated(mtp, va == NULL ? 0 : size, indx); } else { size = roundup(size, PAGE_SIZE); zone = NULL; - va = uma_large_malloc_domain(size, domain, flags); + do { + va = uma_large_malloc_domain(size, domain, flags); + if (va != NULL) + break; + } while (vm_domainset_iter_policy(&di, &domain) == 0); malloc_type_allocated(mtp, va == NULL ? 0 : size); } if (flags & M_WAITOK) Index: sys/sys/malloc.h =================================================================== --- sys/sys/malloc.h +++ sys/sys/malloc.h @@ -230,6 +230,8 @@ _malloc_item; \ }) +struct domainset; + void *malloc_domain(size_t size, struct malloc_type *type, int domain, int flags) __malloc_like __result_use_check __alloc_size(1); void *mallocarray(size_t nmemb, size_t size, struct malloc_type *type,