1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  14  * Copyright 2017 RackTop Systems.
  15  */
  16 
  17 #include <sys/kmem.h>
  18 
  19 #include <sys/debug.h>
  20 #include <sys/ksynch.h>
  21 #include <sys/systm.h>
  22 #include <sys/cmn_err.h>
  23 
  24 #include <umem.h>
  25 
  26 void    abort(void) __NORETURN;
  27 
  28 static int
  29 kmem_failed_cb(void)
  30 {
  31         abort();
  32         return (UMEM_CALLBACK_RETRY);
  33 }
  34 
  35 #pragma init(_kmem_init)
  36 static int
  37 _kmem_init(void)
  38 {
  39         umem_nofail_callback(kmem_failed_cb);
  40         return (0);
  41 }
  42 
  43 static int
  44 kmem2umem_flags(int kmflags)
  45 {
  46         int umflags = UMEM_NOFAIL;
  47         if (kmflags & KM_NOSLEEP)
  48                 umflags = UMEM_DEFAULT;
  49         return (umflags);
  50 }
  51 
  52 int
  53 kmem_debugging(void)
  54 {
  55         return (0);
  56 }
  57 
  58 void *
  59 kmem_alloc(size_t size, int kmflags)
  60 {
  61         return (umem_alloc(size, kmem2umem_flags(kmflags)));
  62 }
  63 
  64 void *
  65 kmem_zalloc(size_t size, int kmflags)
  66 {
  67         return (umem_zalloc(size, kmem2umem_flags(kmflags)));
  68 }
  69 
  70 /*
  71  * Do not change the length of the returned string; it must be freed
  72  * with strfree().
  73  */
  74 char *
  75 kmem_asprintf(const char *fmt, ...)
  76 {
  77         int size;
  78         va_list adx;
  79         char *buf;
  80 
  81         va_start(adx, fmt);
  82         size = vsnprintf(NULL, 0, fmt, adx) + 1;
  83         va_end(adx);
  84 
  85         buf = kmem_alloc(size, KM_SLEEP);
  86 
  87         va_start(adx, fmt);
  88         size = vsnprintf(buf, size, fmt, adx);
  89         va_end(adx);
  90 
  91         return (buf);
  92 }
  93 
  94 void
  95 kmem_free(void *buf, size_t size)
  96 {
  97         umem_free(buf, size);
  98 }
  99 
 100 /* void *kmem_alloc_tryhard(size_t size, size_t *alloc_size, int kmflags); */
 101 
 102 kmem_cache_t *
 103 kmem_cache_create(
 104         char *name,             /* descriptive name for this cache */
 105         size_t bufsize,         /* size of the objects it manages */
 106         size_t align,           /* required object alignment */
 107         int (*constructor)(void *, void *, int), /* object constructor */
 108         void (*destructor)(void *, void *),     /* object destructor */
 109         void (*reclaim)(void *), /* memory reclaim callback */
 110         void *private,          /* pass-thru arg for constr/destr/reclaim */
 111         vmem_t *vmp,            /* vmem source for slab allocation */
 112         int kcflags)            /* cache creation flags */
 113 {
 114         umem_cache_t *uc;
 115         int ucflags = 0;
 116 
 117         /* Ignore KMC_NOTOUCH - not needed for userland caches */
 118         if (kcflags & KMC_NODEBUG)
 119                 ucflags |= UMC_NODEBUG;
 120         if (kcflags & KMC_NOMAGAZINE)
 121                 ucflags |= UMC_NOMAGAZINE;
 122         if (kcflags & KMC_NOHASH)
 123                 ucflags |= UMC_NOHASH;
 124 
 125         uc = umem_cache_create(name, bufsize, align,
 126             constructor, destructor, reclaim,
 127             private, vmp, ucflags);
 128         return ((kmem_cache_t *)uc);
 129 }
 130 
 131 void
 132 kmem_cache_destroy(kmem_cache_t *kc)
 133 {
 134         umem_cache_destroy((umem_cache_t *)kc);
 135 }
 136 
 137 void *
 138 kmem_cache_alloc(kmem_cache_t *kc, int kmflags)
 139 {
 140         return (umem_cache_alloc((umem_cache_t *)kc,
 141             kmem2umem_flags(kmflags)));
 142 }
 143 
 144 void
 145 kmem_cache_free(kmem_cache_t *kc, void *p)
 146 {
 147         umem_cache_free((umem_cache_t *)kc, p);
 148 }
 149 
 150 /* ARGSUSED */
 151 void
 152 kmem_cache_set_move(kmem_cache_t *kc,
 153         kmem_cbrc_t (*fun)(void *, void *, size_t, void *))
 154 {
 155 }
 156 
 157 /* ARGSUSED */
 158 void
 159 kmem_cache_reap_now(kmem_cache_t *kc)
 160 {
 161 }
 162 
 163 /* uint64_t kmem_cache_stat(kmem_cache_t *, char *); */
 164 
 165 /* ARGSUSED */
 166 void
 167 vmem_qcache_reap(struct  vmem *vmp)
 168 {
 169 }
 170 
 171 void
 172 strfree(char *str)
 173 {
 174         ASSERT(str != NULL);
 175         kmem_free(str, strlen(str) + 1);
 176 }