2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
8 * This file is part of the SPL, Solaris Porting Layer.
9 * For details, see <http://zfsonlinux.org/>.
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * You should have received a copy of the GNU General Public License along
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
29 #include <linux/sched.h>
30 #include <linux/vmalloc.h>
32 typedef struct vmem
{ } vmem_t
;
34 extern vmem_t
*heap_arena
;
35 extern vmem_t
*zio_alloc_arena
;
36 extern vmem_t
*zio_arena
;
38 extern size_t vmem_size(vmem_t
*vmp
, int typemask
);
41 * Memory allocation interfaces
43 #define VMEM_ALLOC 0x01
44 #define VMEM_FREE 0x02
47 #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START)
51 vmalloc_nofail(size_t size
, gfp_t flags
)
56 * Retry failed __vmalloc() allocations once every second. The
57 * rational for the delay is that the likely failure modes are:
59 * 1) The system has completely exhausted memory, in which case
60 * delaying 1 second for the memory reclaim to run is reasonable
61 * to avoid thrashing the system.
62 * 2) The system has memory but has exhausted the small virtual
63 * address space available on 32-bit systems. Retrying the
64 * allocation immediately will only result in spinning on the
65 * virtual address space lock. It is better delay a second and
66 * hope that another process will free some of the address space.
67 * But the bottom line is there is not much we can actually do
68 * since we can never safely return a failure and honor the
72 ptr
= __vmalloc(size
, flags
| __GFP_HIGHMEM
, PAGE_KERNEL
);
73 if (unlikely((ptr
== NULL
) && (flags
& __GFP_WAIT
))) {
74 set_current_state(TASK_INTERRUPTIBLE
);
85 vzalloc_nofail(size_t size
, gfp_t flags
)
89 ptr
= vmalloc_nofail(size
, flags
);
91 memset(ptr
, 0, (size
));
99 * Memory accounting functions to be used only when DEBUG_KMEM is set.
101 #ifdef HAVE_ATOMIC64_T
103 #define vmem_alloc_used_add(size) atomic64_add(size, &vmem_alloc_used)
104 #define vmem_alloc_used_sub(size) atomic64_sub(size, &vmem_alloc_used)
105 #define vmem_alloc_used_read() atomic64_read(&vmem_alloc_used)
106 #define vmem_alloc_used_set(size) atomic64_set(&vmem_alloc_used, size)
108 extern atomic64_t vmem_alloc_used
;
109 extern unsigned long long vmem_alloc_max
;
111 #else /* HAVE_ATOMIC64_T */
113 #define vmem_alloc_used_add(size) atomic_add(size, &vmem_alloc_used)
114 #define vmem_alloc_used_sub(size) atomic_sub(size, &vmem_alloc_used)
115 #define vmem_alloc_used_read() atomic_read(&vmem_alloc_used)
116 #define vmem_alloc_used_set(size) atomic_set(&vmem_alloc_used, size)
118 extern atomic_t vmem_alloc_used
;
119 extern unsigned long long vmem_alloc_max
;
121 #endif /* HAVE_ATOMIC64_T */
123 #ifdef DEBUG_KMEM_TRACKING
125 * DEBUG_KMEM && DEBUG_KMEM_TRACKING
127 * The maximum level of memory debugging. All memory will be accounted
128 * for and each allocation will be explicitly tracked. Any allocation
129 * which is leaked will be reported on module unload and the exact location
130 * where that memory was allocation will be reported. This level of memory
131 * tracking will have a significant impact on performance and should only
132 * be enabled for debugging. This feature may be enabled by passing
133 * --enable-debug-kmem-tracking to configure.
135 #define vmem_alloc(sz, fl) vmem_alloc_track((sz), (fl), \
136 __FUNCTION__, __LINE__)
137 #define vmem_zalloc(sz, fl) vmem_alloc_track((sz), (fl)|__GFP_ZERO,\
138 __FUNCTION__, __LINE__)
139 #define vmem_free(ptr, sz) vmem_free_track((ptr), (sz))
141 extern void *kmem_alloc_track(size_t, int, const char *, int, int, int);
142 extern void kmem_free_track(const void *, size_t);
143 extern void *vmem_alloc_track(size_t, int, const char *, int);
144 extern void vmem_free_track(const void *, size_t);
146 #else /* DEBUG_KMEM_TRACKING */
148 * DEBUG_KMEM && !DEBUG_KMEM_TRACKING
150 * The default build will set DEBUG_KEM. This provides basic memory
151 * accounting with little to no impact on performance. When the module
152 * is unloaded in any memory was leaked the total number of leaked bytes
153 * will be reported on the console. To disable this basic accounting
154 * pass the --disable-debug-kmem option to configure.
156 #define vmem_alloc(sz, fl) vmem_alloc_debug((sz), (fl), \
157 __FUNCTION__, __LINE__)
158 #define vmem_zalloc(sz, fl) vmem_alloc_debug((sz), (fl)|__GFP_ZERO,\
159 __FUNCTION__, __LINE__)
160 #define vmem_free(ptr, sz) vmem_free_debug((ptr), (sz))
162 extern void *vmem_alloc_debug(size_t, int, const char *, int);
163 extern void vmem_free_debug(const void *, size_t);
165 #endif /* DEBUG_KMEM_TRACKING */
166 #else /* DEBUG_KMEM */
168 * !DEBUG_KMEM && !DEBUG_KMEM_TRACKING
170 * All debugging is disabled. There will be no overhead even for
171 * minimal memory accounting. To enable basic accounting pass the
172 * --enable-debug-kmem option to configure.
174 #define vmem_alloc(sz, fl) vmalloc_nofail((sz), (fl))
175 #define vmem_zalloc(sz, fl) vzalloc_nofail((sz), (fl))
176 #define vmem_free(ptr, sz) ((void)(sz), vfree(ptr))
178 #endif /* DEBUG_KMEM */
180 int spl_vmem_init(void);
181 void spl_vmem_fini(void);
183 #endif /* _SPL_VMEM_H */