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 }