diff options
Diffstat (limited to 'include/linux/slub_def.h')
-rw-r--r-- | include/linux/slub_def.h | 57 |
1 files changed, 24 insertions, 33 deletions
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index 74962077f632..3b361b2906bd 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -72,7 +72,7 @@ struct kmem_cache { | |||
72 | * We keep the general caches in an array of slab caches that are used for | 72 | * We keep the general caches in an array of slab caches that are used for |
73 | * 2^x bytes of allocations. | 73 | * 2^x bytes of allocations. |
74 | */ | 74 | */ |
75 | extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1]; | 75 | extern struct kmem_cache kmalloc_caches[PAGE_SHIFT]; |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * Sorry that the following has to be that ugly but some versions of GCC | 78 | * Sorry that the following has to be that ugly but some versions of GCC |
@@ -83,9 +83,6 @@ static __always_inline int kmalloc_index(size_t size) | |||
83 | if (!size) | 83 | if (!size) |
84 | return 0; | 84 | return 0; |
85 | 85 | ||
86 | if (size > KMALLOC_MAX_SIZE) | ||
87 | return -1; | ||
88 | |||
89 | if (size <= KMALLOC_MIN_SIZE) | 86 | if (size <= KMALLOC_MIN_SIZE) |
90 | return KMALLOC_SHIFT_LOW; | 87 | return KMALLOC_SHIFT_LOW; |
91 | 88 | ||
@@ -102,6 +99,10 @@ static __always_inline int kmalloc_index(size_t size) | |||
102 | if (size <= 512) return 9; | 99 | if (size <= 512) return 9; |
103 | if (size <= 1024) return 10; | 100 | if (size <= 1024) return 10; |
104 | if (size <= 2 * 1024) return 11; | 101 | if (size <= 2 * 1024) return 11; |
102 | /* | ||
103 | * The following is only needed to support architectures with a larger page | ||
104 | * size than 4k. | ||
105 | */ | ||
105 | if (size <= 4 * 1024) return 12; | 106 | if (size <= 4 * 1024) return 12; |
106 | if (size <= 8 * 1024) return 13; | 107 | if (size <= 8 * 1024) return 13; |
107 | if (size <= 16 * 1024) return 14; | 108 | if (size <= 16 * 1024) return 14; |
@@ -109,13 +110,9 @@ static __always_inline int kmalloc_index(size_t size) | |||
109 | if (size <= 64 * 1024) return 16; | 110 | if (size <= 64 * 1024) return 16; |
110 | if (size <= 128 * 1024) return 17; | 111 | if (size <= 128 * 1024) return 17; |
111 | if (size <= 256 * 1024) return 18; | 112 | if (size <= 256 * 1024) return 18; |
112 | if (size <= 512 * 1024) return 19; | 113 | if (size <= 512 * 1024) return 19; |
113 | if (size <= 1024 * 1024) return 20; | 114 | if (size <= 1024 * 1024) return 20; |
114 | if (size <= 2 * 1024 * 1024) return 21; | 115 | if (size <= 2 * 1024 * 1024) return 21; |
115 | if (size <= 4 * 1024 * 1024) return 22; | ||
116 | if (size <= 8 * 1024 * 1024) return 23; | ||
117 | if (size <= 16 * 1024 * 1024) return 24; | ||
118 | if (size <= 32 * 1024 * 1024) return 25; | ||
119 | return -1; | 116 | return -1; |
120 | 117 | ||
121 | /* | 118 | /* |
@@ -140,19 +137,6 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) | |||
140 | if (index == 0) | 137 | if (index == 0) |
141 | return NULL; | 138 | return NULL; |
142 | 139 | ||
143 | /* | ||
144 | * This function only gets expanded if __builtin_constant_p(size), so | ||
145 | * testing it here shouldn't be needed. But some versions of gcc need | ||
146 | * help. | ||
147 | */ | ||
148 | if (__builtin_constant_p(size) && index < 0) { | ||
149 | /* | ||
150 | * Generate a link failure. Would be great if we could | ||
151 | * do something to stop the compile here. | ||
152 | */ | ||
153 | extern void __kmalloc_size_too_large(void); | ||
154 | __kmalloc_size_too_large(); | ||
155 | } | ||
156 | return &kmalloc_caches[index]; | 140 | return &kmalloc_caches[index]; |
157 | } | 141 | } |
158 | 142 | ||
@@ -168,15 +152,21 @@ void *__kmalloc(size_t size, gfp_t flags); | |||
168 | 152 | ||
169 | static __always_inline void *kmalloc(size_t size, gfp_t flags) | 153 | static __always_inline void *kmalloc(size_t size, gfp_t flags) |
170 | { | 154 | { |
171 | if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { | 155 | if (__builtin_constant_p(size)) { |
172 | struct kmem_cache *s = kmalloc_slab(size); | 156 | if (size > PAGE_SIZE / 2) |
157 | return (void *)__get_free_pages(flags | __GFP_COMP, | ||
158 | get_order(size)); | ||
173 | 159 | ||
174 | if (!s) | 160 | if (!(flags & SLUB_DMA)) { |
175 | return ZERO_SIZE_PTR; | 161 | struct kmem_cache *s = kmalloc_slab(size); |
162 | |||
163 | if (!s) | ||
164 | return ZERO_SIZE_PTR; | ||
176 | 165 | ||
177 | return kmem_cache_alloc(s, flags); | 166 | return kmem_cache_alloc(s, flags); |
178 | } else | 167 | } |
179 | return __kmalloc(size, flags); | 168 | } |
169 | return __kmalloc(size, flags); | ||
180 | } | 170 | } |
181 | 171 | ||
182 | #ifdef CONFIG_NUMA | 172 | #ifdef CONFIG_NUMA |
@@ -185,15 +175,16 @@ void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); | |||
185 | 175 | ||
186 | static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) | 176 | static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) |
187 | { | 177 | { |
188 | if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { | 178 | if (__builtin_constant_p(size) && |
189 | struct kmem_cache *s = kmalloc_slab(size); | 179 | size <= PAGE_SIZE / 2 && !(flags & SLUB_DMA)) { |
180 | struct kmem_cache *s = kmalloc_slab(size); | ||
190 | 181 | ||
191 | if (!s) | 182 | if (!s) |
192 | return ZERO_SIZE_PTR; | 183 | return ZERO_SIZE_PTR; |
193 | 184 | ||
194 | return kmem_cache_alloc_node(s, flags, node); | 185 | return kmem_cache_alloc_node(s, flags, node); |
195 | } else | 186 | } |
196 | return __kmalloc_node(size, flags, node); | 187 | return __kmalloc_node(size, flags, node); |
197 | } | 188 | } |
198 | #endif | 189 | #endif |
199 | 190 | ||