aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/slab.h26
-rw-r--r--mm/slab.c13
-rw-r--r--mm/util.c6
-rw-r--r--net/core/skbuff.c3
4 files changed, 31 insertions, 17 deletions
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 70be57d8ae0d..c4947b8a2c03 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -77,13 +77,6 @@ struct cache_sizes {
77extern struct cache_sizes malloc_sizes[]; 77extern struct cache_sizes malloc_sizes[];
78 78
79extern void *__kmalloc(size_t, gfp_t); 79extern void *__kmalloc(size_t, gfp_t);
80#ifndef CONFIG_DEBUG_SLAB
81#define ____kmalloc(size, flags) __kmalloc(size, flags)
82#else
83extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
84#define ____kmalloc(size, flags) \
85 __kmalloc_track_caller(size, flags, __builtin_return_address(0))
86#endif
87 80
88/** 81/**
89 * kmalloc - allocate memory 82 * kmalloc - allocate memory
@@ -153,6 +146,23 @@ found:
153 return __kmalloc(size, flags); 146 return __kmalloc(size, flags);
154} 147}
155 148
149/*
150 * kmalloc_track_caller is a special version of kmalloc that records the
151 * calling function of the routine calling it for slab leak tracking instead
152 * of just the calling function (confusing, eh?).
153 * It's useful when the call to kmalloc comes from a widely-used standard
154 * allocator where we care about the real place the memory allocation
155 * request comes from.
156 */
157#ifndef CONFIG_DEBUG_SLAB
158#define kmalloc_track_caller(size, flags) \
159 __kmalloc(size, flags)
160#else
161extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
162#define kmalloc_track_caller(size, flags) \
163 __kmalloc_track_caller(size, flags, __builtin_return_address(0))
164#endif
165
156extern void *__kzalloc(size_t, gfp_t); 166extern void *__kzalloc(size_t, gfp_t);
157 167
158/** 168/**
@@ -271,7 +281,7 @@ static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
271#define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f) 281#define kmem_cache_alloc_node(c, f, n) kmem_cache_alloc(c, f)
272#define kmalloc_node(s, f, n) kmalloc(s, f) 282#define kmalloc_node(s, f, n) kmalloc(s, f)
273#define kzalloc(s, f) __kzalloc(s, f) 283#define kzalloc(s, f) __kzalloc(s, f)
274#define ____kmalloc kmalloc 284#define kmalloc_track_caller kmalloc
275 285
276#endif /* CONFIG_SLOB */ 286#endif /* CONFIG_SLOB */
277 287
diff --git a/mm/slab.c b/mm/slab.c
index 3dbd6f4e7477..c23b99250df2 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3488,22 +3488,25 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
3488} 3488}
3489 3489
3490 3490
3491#ifdef CONFIG_DEBUG_SLAB
3491void *__kmalloc(size_t size, gfp_t flags) 3492void *__kmalloc(size_t size, gfp_t flags)
3492{ 3493{
3493#ifndef CONFIG_DEBUG_SLAB
3494 return __do_kmalloc(size, flags, NULL);
3495#else
3496 return __do_kmalloc(size, flags, __builtin_return_address(0)); 3494 return __do_kmalloc(size, flags, __builtin_return_address(0));
3497#endif
3498} 3495}
3499EXPORT_SYMBOL(__kmalloc); 3496EXPORT_SYMBOL(__kmalloc);
3500 3497
3501#ifdef CONFIG_DEBUG_SLAB
3502void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller) 3498void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller)
3503{ 3499{
3504 return __do_kmalloc(size, flags, caller); 3500 return __do_kmalloc(size, flags, caller);
3505} 3501}
3506EXPORT_SYMBOL(__kmalloc_track_caller); 3502EXPORT_SYMBOL(__kmalloc_track_caller);
3503
3504#else
3505void *__kmalloc(size_t size, gfp_t flags)
3506{
3507 return __do_kmalloc(size, flags, NULL);
3508}
3509EXPORT_SYMBOL(__kmalloc);
3507#endif 3510#endif
3508 3511
3509/** 3512/**
diff --git a/mm/util.c b/mm/util.c
index e14fa84ef39a..ace2aea69f1a 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -11,7 +11,7 @@
11 */ 11 */
12void *__kzalloc(size_t size, gfp_t flags) 12void *__kzalloc(size_t size, gfp_t flags)
13{ 13{
14 void *ret = ____kmalloc(size, flags); 14 void *ret = kmalloc_track_caller(size, flags);
15 if (ret) 15 if (ret)
16 memset(ret, 0, size); 16 memset(ret, 0, size);
17 return ret; 17 return ret;
@@ -33,7 +33,7 @@ char *kstrdup(const char *s, gfp_t gfp)
33 return NULL; 33 return NULL;
34 34
35 len = strlen(s) + 1; 35 len = strlen(s) + 1;
36 buf = ____kmalloc(len, gfp); 36 buf = kmalloc_track_caller(len, gfp);
37 if (buf) 37 if (buf)
38 memcpy(buf, s, len); 38 memcpy(buf, s, len);
39 return buf; 39 return buf;
@@ -51,7 +51,7 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)
51{ 51{
52 void *p; 52 void *p;
53 53
54 p = ____kmalloc(len, gfp); 54 p = kmalloc_track_caller(len, gfp);
55 if (p) 55 if (p)
56 memcpy(p, src, len); 56 memcpy(p, src, len);
57 return p; 57 return p;
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index c448c7f6fde2..3c23760c5827 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -156,7 +156,8 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
156 156
157 /* Get the DATA. Size must match skb_add_mtu(). */ 157 /* Get the DATA. Size must match skb_add_mtu(). */
158 size = SKB_DATA_ALIGN(size); 158 size = SKB_DATA_ALIGN(size);
159 data = ____kmalloc(size + sizeof(struct skb_shared_info), gfp_mask); 159 data = kmalloc_track_caller(size + sizeof(struct skb_shared_info),
160 gfp_mask);
160 if (!data) 161 if (!data)
161 goto nodata; 162 goto nodata;
162 163