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 }