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:
parent
5ba16cf3d7
commit
ec0d828071
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=357547
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -200,6 +200,7 @@
|
||||
"\6NOFREE" \
|
||||
"\5MALLOC" \
|
||||
"\4NOTOUCH" \
|
||||
"\3CONTIG" \
|
||||
"\2ZINIT"
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user