Index: sys/vm/uma.h =================================================================== --- sys/vm/uma.h (revision 266197) +++ sys/vm/uma.h (working copy) @@ -45,6 +45,7 @@ /* Types and type defs */ struct uma_zone; +struct vm_domain_select; /* Opaque type used as a handle to the zone */ typedef struct uma_zone * uma_zone_t; @@ -280,11 +281,6 @@ uma_zone_t uma_zcache_create(char *name, int size, * Allocates mp_ncpus slabs sized to * sizeof(struct pcpu). */ -#define UMA_ZONE_NUMA 0x10000 /* - * Zone is NUMA aware. Implements - * a best effort first-touch - * allocation policy. - */ /* * These flags are shared between the keg and zone. In zones wishing to add @@ -585,6 +581,19 @@ void uma_zone_set_allocf(uma_zone_t zone, uma_allo void uma_zone_set_freef(uma_zone_t zone, uma_free freef); /* + * XXX + * + * Arguments: + * zone The zone NUMA policy is being installed. + * sel Selector of the NUMA policy requested. + * + * Returns: + * Nothing + */ +void uma_zone_set_domain_selector(uma_zone_t zone, + struct vm_domain_select *sel); + +/* * These flags are setable in the allocf and visible in the freef. */ #define UMA_SLAB_BOOT 0x01 /* Slab alloced from boot pages */ Index: sys/vm/uma_core.c =================================================================== --- sys/vm/uma_core.c (revision 266197) +++ sys/vm/uma_core.c (working copy) @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -312,7 +313,8 @@ bucket_init(void) size += sizeof(void *) * ubz->ubz_entries; ubz->ubz_zone = uma_zcreate(ubz->ubz_name, size, NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, - UMA_ZONE_MTXCLASS | UMA_ZFLAG_BUCKET | UMA_ZONE_NUMA); + UMA_ZONE_MTXCLASS | UMA_ZFLAG_BUCKET); + uma_zone_set_domain_selector(ubz->ubz_zone, &vm_sel_ft); } } @@ -715,10 +717,10 @@ cache_drain_safe_cpu(uma_zone_t zone) ZONE_LOCK(zone); critical_enter(); - if (zone->uz_flags & UMA_ZONE_NUMA) - domain = PCPU_GET(domain); + if (zone->uz_sel == NULL) + domain = 0; else - domain = 0; + domain = vm_domain_select_first(zone->uz_sel); cache = &zone->uz_cpu[curcpu]; if (cache->uc_allocbucket) { if (cache->uc_allocbucket->ub_cnt != 0) @@ -1605,6 +1607,7 @@ zone_ctor(void *mem, int size, void *udata, int fl zone->uz_sleeps = 0; zone->uz_count = 0; zone->uz_count_min = 0; + zone->uz_sel = NULL; zone->uz_flags = 0; zone->uz_warning = NULL; timevalclear(&zone->uz_ratecheck); @@ -2268,13 +2271,12 @@ zalloc_start: goto zalloc_start; } - /* Get the domain according to zone flags. */ - if (zone->uz_flags & UMA_ZONE_NUMA) { - domain = PCPU_GET(domain); - zdom = &zone->uz_domain[domain]; - } else { + if (zone->uz_sel == NULL) { domain = UMA_ANYDOMAIN; zdom = &zone->uz_domain[0]; + } else { + domain = vm_domain_select_first(zone->uz_sel); + zdom = &zone->uz_domain[domain]; } /* @@ -2835,13 +2837,12 @@ zfree_start: } cache->uc_freebucket = NULL; - /* Get the domain according to zone flags. */ - if (zone->uz_flags & UMA_ZONE_NUMA) { - domain = PCPU_GET(domain); - zdom = &zone->uz_domain[domain]; - } else { + if (zone->uz_sel == NULL) { zdom = &zone->uz_domain[0]; domain = UMA_ANYDOMAIN; + } else { + domain = vm_domain_select_first(zone->uz_sel); + zdom = &zone->uz_domain[domain]; } /* Can we throw this on the zone full list? */ @@ -3166,6 +3167,16 @@ uma_zone_set_allocf(uma_zone_t zone, uma_alloc all /* See uma.h */ void +uma_zone_set_domain_selector(uma_zone_t zone, struct vm_domain_select *sel) +{ + + ZONE_LOCK(zone); + zone->uz_sel = sel; + ZONE_UNLOCK(zone); +} + +/* See uma.h */ +void uma_zone_reserve(uma_zone_t zone, int items) { uma_keg_t keg; Index: sys/vm/uma_int.h =================================================================== --- sys/vm/uma_int.h (revision 266197) +++ sys/vm/uma_int.h (working copy) @@ -312,6 +312,8 @@ struct uma_zone_domain { typedef struct uma_zone_domain * uma_zone_domain_t; +struct vm_domain_select; + /* * Zone management structure * @@ -347,6 +349,7 @@ struct uma_zone { uint64_t uz_sleeps; /* Total number of alloc sleeps */ uint16_t uz_count; /* Amount of items in full bucket */ uint16_t uz_count_min; /* Minimal amount of items there */ + struct vm_domain_select *uz_sel; /* Domain memory selector. */ /* The next three fields are used to print a rate-limited warnings. */ const char *uz_warning; /* Warning to print on failure */