]> git.proxmox.com Git - mirror_zfs.git/blame - include/sys/kmem.h
New an improved taskq implementation for the SPL. It allows a
[mirror_zfs.git] / include / sys / kmem.h
CommitLineData
09b414e8
BB
1#ifndef _SPL_KMEM_H
2#define _SPL_KMEM_H
f1ca4da6
BB
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
79b31f36 8#define DEBUG_KMEM
f1ca4da6
BB
9#undef DEBUG_KMEM_UNIMPLEMENTED
10
f1b59d26 11#include <linux/module.h>
f1ca4da6 12#include <linux/slab.h>
79b31f36 13#include <linux/vmalloc.h>
f1ca4da6
BB
14#include <linux/mm.h>
15#include <linux/spinlock.h>
937879f1 16#include <sys/debug.h>
f1ca4da6
BB
17/*
18 * Memory allocation interfaces
19 */
20#define KM_SLEEP GFP_KERNEL
21#define KM_NOSLEEP GFP_ATOMIC
22#undef KM_PANIC /* No linux analog */
23#define KM_PUSHPAGE (GFP_KERNEL | GFP_HIGH)
24#define KM_VMFLAGS GFP_LEVEL_MASK
25#define KM_FLAGS __GFP_BITS_MASK
26
27#ifdef DEBUG_KMEM
c19c06f3
BB
28extern atomic64_t kmem_alloc_used;
29extern unsigned long kmem_alloc_max;
30extern atomic64_t vmem_alloc_used;
31extern unsigned long vmem_alloc_max;
32extern int kmem_warning_flag;
f1ca4da6 33
f1ca4da6
BB
34#define __kmem_alloc(size, flags, allocator) \
35({ void *_ptr_; \
36 \
37 /* Marked unlikely because we should never be doing this */ \
6a585c61 38 if (unlikely((size) > (PAGE_SIZE * 4)) && kmem_warning_flag) \
839d8b43
BB
39 __CDEBUG_LIMIT(S_KMEM, D_WARNING, "Warning large " \
40 "kmem_alloc(%d, 0x%x) (%ld/%ld)\n", \
41 (int)(size), (int)(flags), \
3561541c
BB
42 atomic64_read(&kmem_alloc_used), \
43 kmem_alloc_max); \
f1ca4da6
BB
44 \
45 _ptr_ = (void *)allocator((size), (flags)); \
46 if (_ptr_ == NULL) { \
3561541c 47 __CDEBUG_LIMIT(S_KMEM, D_WARNING, "Warning " \
839d8b43
BB
48 "kmem_alloc(%d, 0x%x) failed (%ld/%ld)\n", \
49 (int)(size), (int)(flags), \
3561541c
BB
50 atomic64_read(&kmem_alloc_used), \
51 kmem_alloc_max); \
c19c06f3
BB
52 } else { \
53 atomic64_add((size), &kmem_alloc_used); \
54 if (unlikely(atomic64_read(&kmem_alloc_used)>kmem_alloc_max)) \
55 kmem_alloc_max = atomic64_read(&kmem_alloc_used); \
839d8b43
BB
56 \
57 __CDEBUG_LIMIT(S_KMEM, D_INFO, "kmem_alloc(%d, 0x%x)'d " \
58 "(%ld/%ld)\n", (int)(size), (int)(flags), \
59 atomic64_read(&kmem_alloc_used), \
60 kmem_alloc_max); \
f1ca4da6
BB
61 } \
62 \
63 _ptr_; \
64})
65
4fd2f7ee
BB
66#define kmem_alloc(size, flags) __kmem_alloc((size), (flags), kmalloc)
67#define kmem_zalloc(size, flags) __kmem_alloc((size), (flags), kzalloc)
f1ca4da6
BB
68
69#define kmem_free(ptr, size) \
70({ \
937879f1 71 ASSERT((ptr) || (size > 0)); \
c19c06f3 72 atomic64_sub((size), &kmem_alloc_used); \
839d8b43
BB
73 __CDEBUG_LIMIT(S_KMEM, D_INFO, "kmem_free(%d)'d (%ld/%ld)\n", \
74 (int)(size), atomic64_read(&kmem_alloc_used), \
75 kmem_alloc_max); \
f1ca4da6
BB
76 memset(ptr, 0x5a, (size)); /* Poison */ \
77 kfree(ptr); \
f1ca4da6
BB
78})
79
79b31f36
BB
80#define __vmem_alloc(size, flags) \
81({ void *_ptr_; \
82 \
937879f1 83 ASSERT(flags & KM_SLEEP); \
79b31f36 84 \
3561541c
BB
85 _ptr_ = (void *)__vmalloc((size), \
86 (((flags) | __GFP_HIGHMEM) & ~__GFP_ZERO), \
87 PAGE_KERNEL); \
79b31f36 88 if (_ptr_ == NULL) { \
3561541c 89 __CDEBUG_LIMIT(S_KMEM, D_WARNING, "Warning " \
839d8b43
BB
90 "vmem_alloc(%d, 0x%x) failed (%ld/%ld)\n", \
91 (int)(size), (int)(flags), \
3561541c
BB
92 atomic64_read(&vmem_alloc_used), \
93 vmem_alloc_max); \
c19c06f3 94 } else { \
8100fe56
HW
95 if (flags & __GFP_ZERO) \
96 memset(_ptr_, 0, (size)); \
3561541c 97 \
c19c06f3
BB
98 atomic64_add((size), &vmem_alloc_used); \
99 if (unlikely(atomic64_read(&vmem_alloc_used)>vmem_alloc_max)) \
100 vmem_alloc_max = atomic64_read(&vmem_alloc_used); \
839d8b43
BB
101 \
102 __CDEBUG_LIMIT(S_KMEM, D_INFO, "vmem_alloc(%d, 0x%x)'d " \
103 "(%ld/%ld)\n", (int)(size), (int)(flags), \
104 atomic64_read(&vmem_alloc_used), \
105 vmem_alloc_max); \
79b31f36
BB
106 } \
107 \
108 _ptr_; \
109})
110
4fd2f7ee
BB
111#define vmem_alloc(size, flags) __vmem_alloc((size), (flags))
112#define vmem_zalloc(size, flags) __vmem_alloc((size), ((flags) | \
113 __GFP_ZERO))
79b31f36
BB
114
115#define vmem_free(ptr, size) \
116({ \
937879f1 117 ASSERT((ptr) || (size > 0)); \
c19c06f3 118 atomic64_sub((size), &vmem_alloc_used); \
839d8b43
BB
119 __CDEBUG_LIMIT(S_KMEM, D_INFO, "vmem_free(%d)'d (%ld/%ld)\n", \
120 (int)(size), atomic64_read(&vmem_alloc_used), \
121 vmem_alloc_max); \
79b31f36
BB
122 memset(ptr, 0x5a, (size)); /* Poison */ \
123 vfree(ptr); \
124})
f1ca4da6
BB
125
126#else
127
4fd2f7ee
BB
128#define kmem_alloc(size, flags) kmalloc((size), (flags))
129#define kmem_zalloc(size, flags) kzalloc((size), (flags))
3b3ba48f
BB
130#define kmem_free(ptr, size) \
131({ \
937879f1 132 ASSERT((ptr) || (size > 0)); \
3b3ba48f
BB
133 kfree(ptr); \
134})
f1ca4da6 135
4fd2f7ee
BB
136#define vmem_alloc(size, flags) __vmalloc((size), ((flags) | \
137 __GFP_HIGHMEM), PAGE_KERNEL)
138#define vmem_zalloc(size, flags) __vmalloc((size), ((flags) | \
139 __GFP_HIGHMEM | __GFP_ZERO) \
140 PAGE_KERNEL)
79b31f36
BB
141#define vmem_free(ptr, size) \
142({ \
937879f1 143 ASSERT((ptr) || (size > 0)); \
79b31f36
BB
144 vfree(ptr); \
145})
146
f1ca4da6
BB
147#endif /* DEBUG_KMEM */
148
149
150#ifdef DEBUG_KMEM_UNIMPLEMENTED
151static __inline__ void *
152kmem_alloc_tryhard(size_t size, size_t *alloc_size, int kmflags)
153{
154#error "kmem_alloc_tryhard() not implemented"
155}
156#endif /* DEBUG_KMEM_UNIMPLEMENTED */
157
158/*
159 * Slab allocation interfaces
160 */
161#undef KMC_NOTOUCH /* No linux analog */
48f940b9 162#define KMC_NODEBUG 0x00000000 /* Default behavior */
f1ca4da6
BB
163#define KMC_NOMAGAZINE /* No linux analog */
164#define KMC_NOHASH /* No linux analog */
165#define KMC_QCACHE /* No linux analog */
166
167#define KMC_REAP_CHUNK 256
168#define KMC_DEFAULT_SEEKS DEFAULT_SEEKS
169
170/* Defined by linux slab.h
171 * typedef struct kmem_cache_s kmem_cache_t;
172 */
173
174/* No linux analog
175 * extern int kmem_ready;
176 * extern pgcnt_t kmem_reapahead;
177 */
178
179#ifdef DEBUG_KMEM_UNIMPLEMENTED
180static __inline__ void kmem_init(void) {
181#error "kmem_init() not implemented"
182}
183
184static __inline__ void kmem_thread_init(void) {
185#error "kmem_thread_init() not implemented"
186}
187
188static __inline__ void kmem_mp_init(void) {
189#error "kmem_mp_init() not implemented"
190}
191
192static __inline__ void kmem_reap_idspace(void) {
193#error "kmem_reap_idspace() not implemented"
194}
195
196static __inline__ size_t kmem_avail(void) {
197#error "kmem_avail() not implemented"
198}
199
200static __inline__ size_t kmem_maxavail(void) {
201#error "kmem_maxavail() not implemented"
202}
203
204static __inline__ uint64_t kmem_cache_stat(kmem_cache_t *cache) {
205#error "kmem_cache_stat() not implemented"
206}
207#endif /* DEBUG_KMEM_UNIMPLEMENTED */
208
209/* XXX - Used by arc.c to adjust its memory footprint. We may want
210 * to use this hook in the future to adjust behavior based on
211 * debug levels. For now it's safe to always return 0.
212 */
213static __inline__ int
214kmem_debugging(void)
215{
216 return 0;
217}
218
219typedef int (*kmem_constructor_t)(void *, void *, int);
220typedef void (*kmem_destructor_t)(void *, void *);
221typedef void (*kmem_reclaim_t)(void *);
222
c19c06f3
BB
223extern int kmem_set_warning(int flag);
224
f1b59d26 225extern kmem_cache_t *
f1ca4da6 226__kmem_cache_create(char *name, size_t size, size_t align,
f1b59d26
BB
227 kmem_constructor_t constructor,
228 kmem_destructor_t destructor,
229 kmem_reclaim_t reclaim,
f1ca4da6
BB
230 void *priv, void *vmp, int flags);
231
e4f1d29f 232int
f1b59d26
BB
233extern __kmem_cache_destroy(kmem_cache_t *cache);
234
235void
236extern __kmem_reap(void);
f1ca4da6 237
5d86345d
BB
238int kmem_init(void);
239void kmem_fini(void);
240
f1ca4da6
BB
241#define kmem_cache_create(name,size,align,ctor,dtor,rclm,priv,vmp,flags) \
242 __kmem_cache_create(name,size,align,ctor,dtor,rclm,priv,vmp,flags)
243#define kmem_cache_destroy(cache) __kmem_cache_destroy(cache)
244#define kmem_cache_alloc(cache, flags) kmem_cache_alloc(cache, flags)
245#define kmem_cache_free(cache, ptr) kmem_cache_free(cache, ptr)
246#define kmem_cache_reap_now(cache) kmem_cache_shrink(cache)
f1b59d26 247#define kmem_reap() __kmem_reap()
f1ca4da6
BB
248
249#ifdef __cplusplus
250}
251#endif
252
09b414e8 253#endif /* _SPL_KMEM_H */