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"
 
 /*
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to