Commit | Line | Data |
---|---|---|
2e892f43 CL |
1 | #ifndef _LINUX_SLAB_DEF_H |
2 | #define _LINUX_SLAB_DEF_H | |
3 | ||
4 | /* | |
5 | * Definitions unique to the original Linux SLAB allocator. | |
6 | * | |
7 | * What we provide here is a way to optimize the frequent kmalloc | |
8 | * calls in the kernel by selecting the appropriate general cache | |
9 | * if kmalloc was called with a size that can be established at | |
10 | * compile time. | |
11 | */ | |
12 | ||
13 | #include <linux/init.h> | |
14 | #include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */ | |
15 | #include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */ | |
16 | #include <linux/compiler.h> | |
17 | ||
18 | /* Size description struct for general caches. */ | |
19 | struct cache_sizes { | |
20 | size_t cs_size; | |
21 | struct kmem_cache *cs_cachep; | |
4b51d669 | 22 | #ifdef CONFIG_ZONE_DMA |
2e892f43 | 23 | struct kmem_cache *cs_dmacachep; |
4b51d669 | 24 | #endif |
2e892f43 CL |
25 | }; |
26 | extern struct cache_sizes malloc_sizes[]; | |
27 | ||
6193a2ff PM |
28 | void *kmem_cache_alloc(struct kmem_cache *, gfp_t); |
29 | void *__kmalloc(size_t size, gfp_t flags); | |
30 | ||
2e892f43 CL |
31 | static inline void *kmalloc(size_t size, gfp_t flags) |
32 | { | |
33 | if (__builtin_constant_p(size)) { | |
34 | int i = 0; | |
6cb8f913 CL |
35 | |
36 | if (!size) | |
37 | return ZERO_SIZE_PTR; | |
38 | ||
2e892f43 CL |
39 | #define CACHE(x) \ |
40 | if (size <= x) \ | |
41 | goto found; \ | |
42 | else \ | |
43 | i++; | |
1c61fc40 | 44 | #include <linux/kmalloc_sizes.h> |
2e892f43 | 45 | #undef CACHE |
1cf3eb2f | 46 | return NULL; |
2e892f43 | 47 | found: |
4b51d669 CL |
48 | #ifdef CONFIG_ZONE_DMA |
49 | if (flags & GFP_DMA) | |
50 | return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep, | |
51 | flags); | |
52 | #endif | |
53 | return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags); | |
2e892f43 CL |
54 | } |
55 | return __kmalloc(size, flags); | |
56 | } | |
57 | ||
2e892f43 CL |
58 | #ifdef CONFIG_NUMA |
59 | extern void *__kmalloc_node(size_t size, gfp_t flags, int node); | |
6193a2ff | 60 | extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); |
2e892f43 CL |
61 | |
62 | static inline void *kmalloc_node(size_t size, gfp_t flags, int node) | |
63 | { | |
64 | if (__builtin_constant_p(size)) { | |
65 | int i = 0; | |
6cb8f913 CL |
66 | |
67 | if (!size) | |
68 | return ZERO_SIZE_PTR; | |
69 | ||
2e892f43 CL |
70 | #define CACHE(x) \ |
71 | if (size <= x) \ | |
72 | goto found; \ | |
73 | else \ | |
74 | i++; | |
1c61fc40 | 75 | #include <linux/kmalloc_sizes.h> |
2e892f43 | 76 | #undef CACHE |
1cf3eb2f | 77 | return NULL; |
2e892f43 | 78 | found: |
4b51d669 CL |
79 | #ifdef CONFIG_ZONE_DMA |
80 | if (flags & GFP_DMA) | |
81 | return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep, | |
82 | flags, node); | |
83 | #endif | |
84 | return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep, | |
85 | flags, node); | |
2e892f43 CL |
86 | } |
87 | return __kmalloc_node(size, flags, node); | |
88 | } | |
89 | ||
90 | #endif /* CONFIG_NUMA */ | |
91 | ||
92 | #endif /* _LINUX_SLAB_DEF_H */ |