uma: add UMA_ZONE_CONTIG, and a default contig_alloc

For now, copy the mbuf allocator.

Reviewed by:	jeff, markj (previous version)
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D23237
This commit is contained in:
Ryan Libby 2020-02-04 22:40:11 +00:00
parent 5ba16cf3d7
commit ec0d828071
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357547
4 changed files with 42 additions and 15 deletions

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd January 8, 2020
.Dd February 4, 2020
.Dt UMA 9
.Os
.Sh NAME
@ -340,6 +340,10 @@ was allocated will cause mixing in per-CPU caches.
See
.Xr numa 4
for more details.
.It Dv UMA_ZONE_CONTIG
Items in this zone must be contiguous in physical address space.
Items will follow normal alignment constraints and may span page boundaries
between pages with contiguous physical addresses.
.El
.Pp
Zones can be destroyed using
@ -465,12 +469,8 @@ and
.Fn uma_zone_set_freef
functions allow a zone's default slab allocation and free functions to be
overridden.
This is useful if the zone's items have special memory allocation constraints.
For example, if multi-page objects are required to be physically contiguous,
an
.Fa allocf
function which requests contiguous memory from the kernel's page allocator
may be used.
This is useful if memory with special constraints such as attributes,
alignment, or address ranges must be used.
.Pp
The
.Fn uma_zone_set_max

View File

@ -236,6 +236,10 @@ uma_zone_t uma_zcache_create(char *name, int size, uma_ctor ctor, uma_dtor dtor,
* overlap when adding new features.
*/
#define UMA_ZONE_ZINIT 0x0002 /* Initialize with zeros */
#define UMA_ZONE_CONTIG 0x0004 /*
* Physical memory underlying an object
* must be contiguous.
*/
#define UMA_ZONE_NOTOUCH 0x0008 /* UMA may not access the memory */
#define UMA_ZONE_MALLOC 0x0010 /* For use by malloc(9) only! */
#define UMA_ZONE_NOFREE 0x0020 /* Do not free slabs of this type! */
@ -639,8 +643,7 @@ smr_t uma_zone_get_smr(uma_zone_t zone);
#define UMA_SLAB_BOOT 0x01 /* Slab alloced from boot pages */
#define UMA_SLAB_KERNEL 0x04 /* Slab alloced from kmem */
#define UMA_SLAB_PRIV 0x08 /* Slab alloced from priv allocator */
#define UMA_SLAB_OFFP 0x10 /* Slab is managed separately */
/* 0x02, 0x40, and 0x80 are available */
/* 0x02, 0x10, 0x40, and 0x80 are available */
/*
* Used to pre-fill a zone with some number of items

View File

@ -271,6 +271,7 @@ static void *noobj_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
static void *page_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
static void *pcpu_page_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
static void *startup_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
static void *contig_alloc(uma_zone_t, vm_size_t, int, uint8_t *, int);
static void page_free(void *, vm_size_t, uint8_t);
static void pcpu_page_free(void *, vm_size_t, uint8_t);
static uma_slab_t keg_alloc_slab(uma_keg_t, uma_zone_t, int, int, int);
@ -1659,6 +1660,19 @@ noobj_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *flags,
return ((void *)retkva);
}
/*
* Allocate physically contiguous pages.
*/
static void *
contig_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag,
int wait)
{
*pflag = UMA_SLAB_KERNEL;
return ((void *)kmem_alloc_contig_domainset(DOMAINSET_FIXED(domain),
bytes, wait, 0, ~(vm_paddr_t)0, 1, 0, VM_MEMATTR_DEFAULT));
}
/*
* Frees a number of pages to the system
*
@ -1679,8 +1693,8 @@ page_free(void *mem, vm_size_t size, uint8_t flags)
return;
}
if ((flags & UMA_SLAB_KERNEL) == 0)
panic("UMA: page_free used with invalid flags %x", flags);
KASSERT((flags & UMA_SLAB_KERNEL) != 0,
("UMA: page_free used with invalid flags %x", flags));
kmem_free((vm_offset_t)mem, size);
}
@ -2044,6 +2058,8 @@ keg_ctor(void *mem, int size, void *udata, int flags)
keg->uk_allocf = startup_alloc;
else if (keg->uk_flags & UMA_ZONE_PCPU)
keg->uk_allocf = pcpu_page_alloc;
else if ((keg->uk_flags & UMA_ZONE_CONTIG) != 0 && keg->uk_ppera > 1)
keg->uk_allocf = contig_alloc;
else
keg->uk_allocf = page_alloc;
#ifdef UMA_MD_SMALL_ALLOC
@ -2105,10 +2121,17 @@ zone_kva_available(uma_zone_t zone, void *unused)
if ((zone->uz_flags & UMA_ZFLAG_CACHE) != 0)
return;
KEG_GET(zone, keg);
if (keg->uk_flags & UMA_ZONE_PCPU)
keg->uk_allocf = pcpu_page_alloc;
else if (keg->uk_allocf == startup_alloc)
keg->uk_allocf = page_alloc;
if (keg->uk_allocf == startup_alloc) {
/* Switch to the real allocator. */
if (keg->uk_flags & UMA_ZONE_PCPU)
keg->uk_allocf = pcpu_page_alloc;
else if ((keg->uk_flags & UMA_ZONE_CONTIG) != 0 &&
keg->uk_ppera > 1)
keg->uk_allocf = contig_alloc;
else
keg->uk_allocf = page_alloc;
}
}
static void

View File

@ -200,6 +200,7 @@
"\6NOFREE" \
"\5MALLOC" \
"\4NOTOUCH" \
"\3CONTIG" \
"\2ZINIT"
/*