svn commit: r357547 - in head: share/man/man9 sys/vm
Ryan Libby
rlibby at FreeBSD.org
Tue Feb 4 22:40:12 UTC 2020
Author: rlibby
Date: Tue Feb 4 22:40:11 2020
New Revision: 357547
URL: https://svnweb.freebsd.org/changeset/base/357547
Log:
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
Modified:
head/share/man/man9/zone.9
head/sys/vm/uma.h
head/sys/vm/uma_core.c
head/sys/vm/uma_int.h
Modified: head/share/man/man9/zone.9
==============================================================================
--- head/share/man/man9/zone.9 Tue Feb 4 22:39:58 2020 (r357546)
+++ head/share/man/man9/zone.9 Tue Feb 4 22:40:11 2020 (r357547)
@@ -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
Modified: head/sys/vm/uma.h
==============================================================================
--- head/sys/vm/uma.h Tue Feb 4 22:39:58 2020 (r357546)
+++ head/sys/vm/uma.h Tue Feb 4 22:40:11 2020 (r357547)
@@ -236,6 +236,10 @@ uma_zone_t uma_zcache_create(char *name, int size, uma
* 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
Modified: head/sys/vm/uma_core.c
==============================================================================
--- head/sys/vm/uma_core.c Tue Feb 4 22:39:58 2020 (r357546)
+++ head/sys/vm/uma_core.c Tue Feb 4 22:40:11 2020 (r357547)
@@ -271,6 +271,7 @@ static void *noobj_alloc(uma_zone_t, vm_size_t, int, u
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);
@@ -1660,6 +1661,19 @@ noobj_alloc(uma_zone_t zone, vm_size_t bytes, int doma
}
/*
+ * 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
*
* Arguments:
@@ -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
Modified: head/sys/vm/uma_int.h
==============================================================================
--- head/sys/vm/uma_int.h Tue Feb 4 22:39:58 2020 (r357546)
+++ head/sys/vm/uma_int.h Tue Feb 4 22:40:11 2020 (r357547)
@@ -200,6 +200,7 @@
"\6NOFREE" \
"\5MALLOC" \
"\4NOTOUCH" \
+ "\3CONTIG" \
"\2ZINIT"
/*
More information about the svn-src-head
mailing list