slab_def.h 3.1 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 <linux/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
#undef CACHE
65
		return NULL;
66
found:
67 68
#ifdef CONFIG_ZONE_DMA
		if (flags & GFP_DMA)
E
Eduard - Gabriel Munteanu 已提交
69 70
			cachep = malloc_sizes[i].cs_dmacachep;
		else
71
#endif
E
Eduard - Gabriel Munteanu 已提交
72 73 74 75
			cachep = malloc_sizes[i].cs_cachep;

		ret = kmem_cache_alloc_notrace(cachep, flags);

76 77
		trace_kmalloc(_THIS_IP_, ret,
			      size, slab_buffer_size(cachep), flags);
E
Eduard - Gabriel Munteanu 已提交
78 79

		return ret;
80 81 82 83 84 85
	}
	return __kmalloc(size, flags);
}

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

E
Eduard - Gabriel Munteanu 已提交
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
#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)
103
{
E
Eduard - Gabriel Munteanu 已提交
104 105 106
	struct kmem_cache *cachep;
	void *ret;

107 108
	if (__builtin_constant_p(size)) {
		int i = 0;
109 110 111 112

		if (!size)
			return ZERO_SIZE_PTR;

113 114 115 116 117
#define CACHE(x) \
		if (size <= x) \
			goto found; \
		else \
			i++;
118
#include <linux/kmalloc_sizes.h>
119
#undef CACHE
120
		return NULL;
121
found:
122 123
#ifdef CONFIG_ZONE_DMA
		if (flags & GFP_DMA)
E
Eduard - Gabriel Munteanu 已提交
124 125
			cachep = malloc_sizes[i].cs_dmacachep;
		else
126
#endif
E
Eduard - Gabriel Munteanu 已提交
127 128 129 130
			cachep = malloc_sizes[i].cs_cachep;

		ret = kmem_cache_alloc_node_notrace(cachep, flags, node);

131 132 133
		trace_kmalloc_node(_THIS_IP_, ret,
				   size, slab_buffer_size(cachep),
				   flags, node);
E
Eduard - Gabriel Munteanu 已提交
134 135

		return ret;
136 137 138 139 140 141 142
	}
	return __kmalloc_node(size, flags, node);
}

#endif	/* CONFIG_NUMA */

#endif	/* _LINUX_SLAB_DEF_H */