slab_def.h 3.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#ifndef _LINUX_SLAB_DEF_H
#define	_LINUX_SLAB_DEF_H

/*
 * Definitions unique to the original Linux SLAB allocator.
 *
 * What we provide here is a way to optimize the frequent kmalloc
 * calls in the kernel by selecting the appropriate general cache
 * if kmalloc was called with a size that can be established at
 * compile time.
 */

#include <linux/init.h>
#include <asm/page.h>		/* kmalloc_sizes.h needs PAGE_SIZE */
#include <asm/cache.h>		/* kmalloc_sizes.h needs L1_CACHE_BYTES */
#include <linux/compiler.h>
17
#include <trace/kmemtrace.h>
18 19 20 21 22

/* Size description struct for general caches. */
struct cache_sizes {
	size_t		 	cs_size;
	struct kmem_cache	*cs_cachep;
23
#ifdef CONFIG_ZONE_DMA
24
	struct kmem_cache	*cs_dmacachep;
25
#endif
26 27 28
};
extern struct cache_sizes malloc_sizes[];

P
Paul Mundt 已提交
29 30 31
void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
void *__kmalloc(size_t size, gfp_t flags);

E
Eduard - Gabriel Munteanu 已提交
32 33 34 35 36 37
#ifdef CONFIG_KMEMTRACE
extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags);
extern size_t slab_buffer_size(struct kmem_cache *cachep);
#else
static __always_inline void *
kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
38
{
E
Eduard - Gabriel Munteanu 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51
	return kmem_cache_alloc(cachep, flags);
}
static inline size_t slab_buffer_size(struct kmem_cache *cachep)
{
	return 0;
}
#endif

static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
	struct kmem_cache *cachep;
	void *ret;

52 53
	if (__builtin_constant_p(size)) {
		int i = 0;
54 55 56 57

		if (!size)
			return ZERO_SIZE_PTR;

58 59 60 61 62
#define CACHE(x) \
		if (size <= x) \
			goto found; \
		else \
			i++;
63
#include <linux/kmalloc_sizes.h>
64 65 66 67 68 69
#undef CACHE
		{
			extern void __you_cannot_kmalloc_that_much(void);
			__you_cannot_kmalloc_that_much();
		}
found:
70 71
#ifdef CONFIG_ZONE_DMA
		if (flags & GFP_DMA)
E
Eduard - Gabriel Munteanu 已提交
72 73
			cachep = malloc_sizes[i].cs_dmacachep;
		else
74
#endif
E
Eduard - Gabriel Munteanu 已提交
75 76 77 78 79 80 81 82
			cachep = malloc_sizes[i].cs_cachep;

		ret = kmem_cache_alloc_notrace(cachep, flags);

		kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret,
				     size, slab_buffer_size(cachep), flags);

		return ret;
83 84 85 86 87 88
	}
	return __kmalloc(size, flags);
}

#ifdef CONFIG_NUMA
extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
P
Paul Mundt 已提交
89
extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
90

E
Eduard - Gabriel Munteanu 已提交
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#ifdef CONFIG_KMEMTRACE
extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
					   gfp_t flags,
					   int nodeid);
#else
static __always_inline void *
kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
			      gfp_t flags,
			      int nodeid)
{
	return kmem_cache_alloc_node(cachep, flags, nodeid);
}
#endif

static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
106
{
E
Eduard - Gabriel Munteanu 已提交
107 108 109
	struct kmem_cache *cachep;
	void *ret;

110 111
	if (__builtin_constant_p(size)) {
		int i = 0;
112 113 114 115

		if (!size)
			return ZERO_SIZE_PTR;

116 117 118 119 120
#define CACHE(x) \
		if (size <= x) \
			goto found; \
		else \
			i++;
121
#include <linux/kmalloc_sizes.h>
122 123 124 125 126 127
#undef CACHE
		{
			extern void __you_cannot_kmalloc_that_much(void);
			__you_cannot_kmalloc_that_much();
		}
found:
128 129
#ifdef CONFIG_ZONE_DMA
		if (flags & GFP_DMA)
E
Eduard - Gabriel Munteanu 已提交
130 131
			cachep = malloc_sizes[i].cs_dmacachep;
		else
132
#endif
E
Eduard - Gabriel Munteanu 已提交
133 134 135 136 137 138 139 140 141
			cachep = malloc_sizes[i].cs_cachep;

		ret = kmem_cache_alloc_node_notrace(cachep, flags, node);

		kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_,
					  ret, size, slab_buffer_size(cachep),
					  flags, node);

		return ret;
142 143 144 145 146 147 148
	}
	return __kmalloc_node(size, flags, node);
}

#endif	/* CONFIG_NUMA */

#endif	/* _LINUX_SLAB_DEF_H */