aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2007-07-16 02:38:22 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-16 12:05:36 -0400
commit6193a2ff180920f84ee06977165ebf32431fc2d2 (patch)
treed3c6423c50463ea741080a58a2e654cf103431f3 /include
parentf7977793240d836e60ff413e94e6914f08e10941 (diff)
slob: initial NUMA support
This adds preliminary NUMA support to SLOB, primarily aimed at systems with small nodes (tested all the way down to a 128kB SRAM block), whether asymmetric or otherwise. We follow the same conventions as SLAB/SLUB, preferring current node placement for new pages, or with explicit placement, if a node has been specified. Presently on UP NUMA this has the side-effect of preferring node#0 allocations (since numa_node_id() == 0, though this could be reworked if we could hand off a pfn to determine node placement), so single-CPU NUMA systems will want to place smaller nodes further out in terms of node id. Once a page has been bound to a node (via explicit node id typing), we only do block allocations from partial free pages that have a matching node id in the page flags. The current implementation does have some scalability problems, in that all partial free pages are tracked in the global freelist (with contention due to the single spinlock). However, these are things that are being reworked for SMP scalability first, while things like per-node freelists can easily be built on top of this sort of functionality once it's been added. More background can be found in: http://marc.info/?l=linux-mm&m=118117916022379&w=2 http://marc.info/?l=linux-mm&m=118170446306199&w=2 http://marc.info/?l=linux-mm&m=118187859420048&w=2 and subsequent threads. Acked-by: Christoph Lameter <clameter@sgi.com> Acked-by: Matt Mackall <mpm@selenic.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org> Acked-by: Nick Piggin <nickpiggin@yahoo.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/slab.h126
-rw-r--r--include/linux/slab_def.h4
-rw-r--r--include/linux/slob_def.h46
-rw-r--r--include/linux/slub_def.h6
4 files changed, 117 insertions, 65 deletions
diff --git a/include/linux/slab.h b/include/linux/slab.h
index cd6ab658553f..27402fea9b79 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -42,7 +42,6 @@ struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
42 void (*)(void *, struct kmem_cache *, unsigned long)); 42 void (*)(void *, struct kmem_cache *, unsigned long));
43void kmem_cache_destroy(struct kmem_cache *); 43void kmem_cache_destroy(struct kmem_cache *);
44int kmem_cache_shrink(struct kmem_cache *); 44int kmem_cache_shrink(struct kmem_cache *);
45void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
46void *kmem_cache_zalloc(struct kmem_cache *, gfp_t); 45void *kmem_cache_zalloc(struct kmem_cache *, gfp_t);
47void kmem_cache_free(struct kmem_cache *, void *); 46void kmem_cache_free(struct kmem_cache *, void *);
48unsigned int kmem_cache_size(struct kmem_cache *); 47unsigned int kmem_cache_size(struct kmem_cache *);
@@ -61,16 +60,6 @@ int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr);
61 sizeof(struct __struct), __alignof__(struct __struct),\ 60 sizeof(struct __struct), __alignof__(struct __struct),\
62 (__flags), NULL, NULL) 61 (__flags), NULL, NULL)
63 62
64#ifdef CONFIG_NUMA
65extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
66#else
67static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
68 gfp_t flags, int node)
69{
70 return kmem_cache_alloc(cachep, flags);
71}
72#endif
73
74/* 63/*
75 * The largest kmalloc size supported by the slab allocators is 64 * The largest kmalloc size supported by the slab allocators is
76 * 32 megabyte (2^25) or the maximum allocatable page order if that is 65 * 32 megabyte (2^25) or the maximum allocatable page order if that is
@@ -89,7 +78,6 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
89/* 78/*
90 * Common kmalloc functions provided by all allocators 79 * Common kmalloc functions provided by all allocators
91 */ 80 */
92void *__kmalloc(size_t, gfp_t);
93void *__kzalloc(size_t, gfp_t); 81void *__kzalloc(size_t, gfp_t);
94void * __must_check krealloc(const void *, size_t, gfp_t); 82void * __must_check krealloc(const void *, size_t, gfp_t);
95void kfree(const void *); 83void kfree(const void *);
@@ -100,40 +88,6 @@ size_t ksize(const void *);
100 * @n: number of elements. 88 * @n: number of elements.
101 * @size: element size. 89 * @size: element size.
102 * @flags: the type of memory to allocate. 90 * @flags: the type of memory to allocate.
103 */
104static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
105{
106 if (n != 0 && size > ULONG_MAX / n)
107 return NULL;
108 return __kzalloc(n * size, flags);
109}
110
111/*
112 * Allocator specific definitions. These are mainly used to establish optimized
113 * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by selecting
114 * the appropriate general cache at compile time.
115 */
116
117#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB)
118#ifdef CONFIG_SLUB
119#include <linux/slub_def.h>
120#else
121#include <linux/slab_def.h>
122#endif /* !CONFIG_SLUB */
123#else
124
125/*
126 * Fallback definitions for an allocator not wanting to provide
127 * its own optimized kmalloc definitions (like SLOB).
128 */
129
130/**
131 * kmalloc - allocate memory
132 * @size: how many bytes of memory are required.
133 * @flags: the type of memory to allocate.
134 *
135 * kmalloc is the normal method of allocating memory
136 * in the kernel.
137 * 91 *
138 * The @flags argument may be one of: 92 * The @flags argument may be one of:
139 * 93 *
@@ -141,7 +95,7 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
141 * 95 *
142 * %GFP_KERNEL - Allocate normal kernel ram. May sleep. 96 * %GFP_KERNEL - Allocate normal kernel ram. May sleep.
143 * 97 *
144 * %GFP_ATOMIC - Allocation will not sleep. 98 * %GFP_ATOMIC - Allocation will not sleep. May use emergency pools.
145 * For example, use this inside interrupt handlers. 99 * For example, use this inside interrupt handlers.
146 * 100 *
147 * %GFP_HIGHUSER - Allocate pages from high memory. 101 * %GFP_HIGHUSER - Allocate pages from high memory.
@@ -150,18 +104,22 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
150 * 104 *
151 * %GFP_NOFS - Do not make any fs calls while trying to get memory. 105 * %GFP_NOFS - Do not make any fs calls while trying to get memory.
152 * 106 *
107 * %GFP_NOWAIT - Allocation will not sleep.
108 *
109 * %GFP_THISNODE - Allocate node-local memory only.
110 *
111 * %GFP_DMA - Allocation suitable for DMA.
112 * Should only be used for kmalloc() caches. Otherwise, use a
113 * slab created with SLAB_DMA.
114 *
153 * Also it is possible to set different flags by OR'ing 115 * Also it is possible to set different flags by OR'ing
154 * in one or more of the following additional @flags: 116 * in one or more of the following additional @flags:
155 * 117 *
156 * %__GFP_COLD - Request cache-cold pages instead of 118 * %__GFP_COLD - Request cache-cold pages instead of
157 * trying to return cache-warm pages. 119 * trying to return cache-warm pages.
158 * 120 *
159 * %__GFP_DMA - Request memory from the DMA-capable zone.
160 *
161 * %__GFP_HIGH - This allocation has high priority and may use emergency pools. 121 * %__GFP_HIGH - This allocation has high priority and may use emergency pools.
162 * 122 *
163 * %__GFP_HIGHMEM - Allocated memory may be from highmem.
164 *
165 * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail 123 * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail
166 * (think twice before using). 124 * (think twice before using).
167 * 125 *
@@ -171,24 +129,57 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
171 * %__GFP_NOWARN - If allocation fails, don't issue any warnings. 129 * %__GFP_NOWARN - If allocation fails, don't issue any warnings.
172 * 130 *
173 * %__GFP_REPEAT - If allocation fails initially, try once more before failing. 131 * %__GFP_REPEAT - If allocation fails initially, try once more before failing.
132 *
133 * There are other flags available as well, but these are not intended
134 * for general use, and so are not documented here. For a full list of
135 * potential flags, always refer to linux/gfp.h.
174 */ 136 */
175static inline void *kmalloc(size_t size, gfp_t flags) 137static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
176{ 138{
177 return __kmalloc(size, flags); 139 if (n != 0 && size > ULONG_MAX / n)
140 return NULL;
141 return __kzalloc(n * size, flags);
178} 142}
179 143
180/** 144/*
181 * kzalloc - allocate memory. The memory is set to zero. 145 * Allocator specific definitions. These are mainly used to establish optimized
182 * @size: how many bytes of memory are required. 146 * ways to convert kmalloc() calls to kmem_cache_alloc() invocations by
183 * @flags: the type of memory to allocate (see kmalloc). 147 * selecting the appropriate general cache at compile time.
148 *
149 * Allocators must define at least:
150 *
151 * kmem_cache_alloc()
152 * __kmalloc()
153 * kmalloc()
154 * kzalloc()
155 *
156 * Those wishing to support NUMA must also define:
157 *
158 * kmem_cache_alloc_node()
159 * kmalloc_node()
160 *
161 * See each allocator definition file for additional comments and
162 * implementation notes.
184 */ 163 */
185static inline void *kzalloc(size_t size, gfp_t flags) 164#ifdef CONFIG_SLUB
186{ 165#include <linux/slub_def.h>
187 return __kzalloc(size, flags); 166#elif defined(CONFIG_SLOB)
188} 167#include <linux/slob_def.h>
168#else
169#include <linux/slab_def.h>
189#endif 170#endif
190 171
191#ifndef CONFIG_NUMA 172#if !defined(CONFIG_NUMA) && !defined(CONFIG_SLOB)
173/**
174 * kmalloc_node - allocate memory from a specific node
175 * @size: how many bytes of memory are required.
176 * @flags: the type of memory to allocate (see kcalloc).
177 * @node: node to allocate from.
178 *
179 * kmalloc() for non-local nodes, used to allocate from a specific node
180 * if available. Equivalent to kmalloc() in the non-NUMA single-node
181 * case.
182 */
192static inline void *kmalloc_node(size_t size, gfp_t flags, int node) 183static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
193{ 184{
194 return kmalloc(size, flags); 185 return kmalloc(size, flags);
@@ -198,7 +189,15 @@ static inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
198{ 189{
199 return __kmalloc(size, flags); 190 return __kmalloc(size, flags);
200} 191}
201#endif /* !CONFIG_NUMA */ 192
193void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
194
195static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
196 gfp_t flags, int node)
197{
198 return kmem_cache_alloc(cachep, flags);
199}
200#endif /* !CONFIG_NUMA && !CONFIG_SLOB */
202 201
203/* 202/*
204 * kmalloc_track_caller is a special version of kmalloc that records the 203 * kmalloc_track_caller is a special version of kmalloc that records the
@@ -245,4 +244,3 @@ extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *);
245 244
246#endif /* __KERNEL__ */ 245#endif /* __KERNEL__ */
247#endif /* _LINUX_SLAB_H */ 246#endif /* _LINUX_SLAB_H */
248
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 8d81a60518e4..365d036c454a 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -25,6 +25,9 @@ struct cache_sizes {
25}; 25};
26extern struct cache_sizes malloc_sizes[]; 26extern struct cache_sizes malloc_sizes[];
27 27
28void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
29void *__kmalloc(size_t size, gfp_t flags);
30
28static inline void *kmalloc(size_t size, gfp_t flags) 31static inline void *kmalloc(size_t size, gfp_t flags)
29{ 32{
30 if (__builtin_constant_p(size)) { 33 if (__builtin_constant_p(size)) {
@@ -79,6 +82,7 @@ found:
79 82
80#ifdef CONFIG_NUMA 83#ifdef CONFIG_NUMA
81extern void *__kmalloc_node(size_t size, gfp_t flags, int node); 84extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
85extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
82 86
83static inline void *kmalloc_node(size_t size, gfp_t flags, int node) 87static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
84{ 88{
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
new file mode 100644
index 000000000000..a2daf2d418a9
--- /dev/null
+++ b/include/linux/slob_def.h
@@ -0,0 +1,46 @@
1#ifndef __LINUX_SLOB_DEF_H
2#define __LINUX_SLOB_DEF_H
3
4void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
5
6static inline void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
7{
8 return kmem_cache_alloc_node(cachep, flags, -1);
9}
10
11void *__kmalloc_node(size_t size, gfp_t flags, int node);
12
13static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
14{
15 return __kmalloc_node(size, flags, node);
16}
17
18/**
19 * kmalloc - allocate memory
20 * @size: how many bytes of memory are required.
21 * @flags: the type of memory to allocate (see kcalloc).
22 *
23 * kmalloc is the normal method of allocating memory
24 * in the kernel.
25 */
26static inline void *kmalloc(size_t size, gfp_t flags)
27{
28 return __kmalloc_node(size, flags, -1);
29}
30
31static inline void *__kmalloc(size_t size, gfp_t flags)
32{
33 return kmalloc(size, flags);
34}
35
36/**
37 * kzalloc - allocate memory. The memory is set to zero.
38 * @size: how many bytes of memory are required.
39 * @flags: the type of memory to allocate (see kcalloc).
40 */
41static inline void *kzalloc(size_t size, gfp_t flags)
42{
43 return __kzalloc(size, flags);
44}
45
46#endif /* __LINUX_SLOB_DEF_H */
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 6207a3d8da71..a582f6771525 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -171,6 +171,9 @@ static inline struct kmem_cache *kmalloc_slab(size_t size)
171#define ZERO_SIZE_PTR ((void *)16) 171#define ZERO_SIZE_PTR ((void *)16)
172 172
173 173
174void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
175void *__kmalloc(size_t size, gfp_t flags);
176
174static inline void *kmalloc(size_t size, gfp_t flags) 177static inline void *kmalloc(size_t size, gfp_t flags)
175{ 178{
176 if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { 179 if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) {
@@ -198,7 +201,8 @@ static inline void *kzalloc(size_t size, gfp_t flags)
198} 201}
199 202
200#ifdef CONFIG_NUMA 203#ifdef CONFIG_NUMA
201extern void *__kmalloc_node(size_t size, gfp_t flags, int node); 204void *__kmalloc_node(size_t size, gfp_t flags, int node);
205void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
202 206
203static inline void *kmalloc_node(size_t size, gfp_t flags, int node) 207static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
204{ 208{