aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-12-29 09:16:24 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-29 09:16:24 -0500
commit2ff9f9d9629bf9530fe2ab8d803d612761ffc059 (patch)
treeb22e3fddffbc0f58b1e1974f4819896d58b7bdaf
parent0f01f07fad4ee11d98fe6faa442afbeb0328a378 (diff)
parenta4900437f3d76761a1646cd90254ccb01714a9ed (diff)
Merge branch 'topic/kmemtrace' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6 into tracing/kmemtrace
-rw-r--r--Documentation/ABI/testing/debugfs-kmemtrace71
-rw-r--r--Documentation/kernel-parameters.txt10
-rw-r--r--Documentation/vm/kmemtrace.txt126
-rw-r--r--MAINTAINERS6
-rw-r--r--include/linux/kmemtrace.h86
-rw-r--r--include/linux/slab.h8
-rw-r--r--include/linux/slab_def.h68
-rw-r--r--include/linux/slob_def.h9
-rw-r--r--include/linux/slub_def.h53
-rw-r--r--init/main.c2
-rw-r--r--lib/Kconfig.debug20
-rw-r--r--mm/Makefile1
-rw-r--r--mm/kmemtrace.c333
-rw-r--r--mm/slab.c79
-rw-r--r--mm/slob.c37
-rw-r--r--mm/slub.c123
16 files changed, 967 insertions, 65 deletions
diff --git a/Documentation/ABI/testing/debugfs-kmemtrace b/Documentation/ABI/testing/debugfs-kmemtrace
new file mode 100644
index 000000000000..5e6a92a02d85
--- /dev/null
+++ b/Documentation/ABI/testing/debugfs-kmemtrace
@@ -0,0 +1,71 @@
1What: /sys/kernel/debug/kmemtrace/
2Date: July 2008
3Contact: Eduard - Gabriel Munteanu <eduard.munteanu@linux360.ro>
4Description:
5
6In kmemtrace-enabled kernels, the following files are created:
7
8/sys/kernel/debug/kmemtrace/
9 cpu<n> (0400) Per-CPU tracing data, see below. (binary)
10 total_overruns (0400) Total number of bytes which were dropped from
11 cpu<n> files because of full buffer condition,
12 non-binary. (text)
13 abi_version (0400) Kernel's kmemtrace ABI version. (text)
14
15Each per-CPU file should be read according to the relay interface. That is,
16the reader should set affinity to that specific CPU and, as currently done by
17the userspace application (though there are other methods), use poll() with
18an infinite timeout before every read(). Otherwise, erroneous data may be
19read. The binary data has the following _core_ format:
20
21 Event ID (1 byte) Unsigned integer, one of:
22 0 - represents an allocation (KMEMTRACE_EVENT_ALLOC)
23 1 - represents a freeing of previously allocated memory
24 (KMEMTRACE_EVENT_FREE)
25 Type ID (1 byte) Unsigned integer, one of:
26 0 - this is a kmalloc() / kfree()
27 1 - this is a kmem_cache_alloc() / kmem_cache_free()
28 2 - this is a __get_free_pages() et al.
29 Event size (2 bytes) Unsigned integer representing the
30 size of this event. Used to extend
31 kmemtrace. Discard the bytes you
32 don't know about.
33 Sequence number (4 bytes) Signed integer used to reorder data
34 logged on SMP machines. Wraparound
35 must be taken into account, although
36 it is unlikely.
37 Caller address (8 bytes) Return address to the caller.
38 Pointer to mem (8 bytes) Pointer to target memory area. Can be
39 NULL, but not all such calls might be
40 recorded.
41
42In case of KMEMTRACE_EVENT_ALLOC events, the next fields follow:
43
44 Requested bytes (8 bytes) Total number of requested bytes,
45 unsigned, must not be zero.
46 Allocated bytes (8 bytes) Total number of actually allocated
47 bytes, unsigned, must not be lower
48 than requested bytes.
49 Requested flags (4 bytes) GFP flags supplied by the caller.
50 Target CPU (4 bytes) Signed integer, valid for event id 1.
51 If equal to -1, target CPU is the same
52 as origin CPU, but the reverse might
53 not be true.
54
55The data is made available in the same endianness the machine has.
56
57Other event ids and type ids may be defined and added. Other fields may be
58added by increasing event size, but see below for details.
59Every modification to the ABI, including new id definitions, are followed
60by bumping the ABI version by one.
61
62Adding new data to the packet (features) is done at the end of the mandatory
63data:
64 Feature size (2 byte)
65 Feature ID (1 byte)
66 Feature data (Feature size - 3 bytes)
67
68
69Users:
70 kmemtrace-user - git://repo.or.cz/kmemtrace-user.git
71
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index a2d8805c03d5..af600c0fe0ec 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -49,6 +49,7 @@ parameter is applicable:
49 ISAPNP ISA PnP code is enabled. 49 ISAPNP ISA PnP code is enabled.
50 ISDN Appropriate ISDN support is enabled. 50 ISDN Appropriate ISDN support is enabled.
51 JOY Appropriate joystick support is enabled. 51 JOY Appropriate joystick support is enabled.
52 KMEMTRACE kmemtrace is enabled.
52 LIBATA Libata driver is enabled 53 LIBATA Libata driver is enabled
53 LP Printer support is enabled. 54 LP Printer support is enabled.
54 LOOP Loopback device support is enabled. 55 LOOP Loopback device support is enabled.
@@ -1033,6 +1034,15 @@ and is between 256 and 4096 characters. It is defined in the file
1033 use the HighMem zone if it exists, and the Normal 1034 use the HighMem zone if it exists, and the Normal
1034 zone if it does not. 1035 zone if it does not.
1035 1036
1037 kmemtrace.enable= [KNL,KMEMTRACE] Format: { yes | no }
1038 Controls whether kmemtrace is enabled
1039 at boot-time.
1040
1041 kmemtrace.subbufs=n [KNL,KMEMTRACE] Overrides the number of
1042 subbufs kmemtrace's relay channel has. Set this
1043 higher than default (KMEMTRACE_N_SUBBUFS in code) if
1044 you experience buffer overruns.
1045
1036 movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter 1046 movablecore=nn[KMG] [KNL,X86-32,IA-64,PPC,X86-64] This parameter
1037 is similar to kernelcore except it specifies the 1047 is similar to kernelcore except it specifies the
1038 amount of memory used for migratable allocations. 1048 amount of memory used for migratable allocations.
diff --git a/Documentation/vm/kmemtrace.txt b/Documentation/vm/kmemtrace.txt
new file mode 100644
index 000000000000..a956d9b7f943
--- /dev/null
+++ b/Documentation/vm/kmemtrace.txt
@@ -0,0 +1,126 @@
1 kmemtrace - Kernel Memory Tracer
2
3 by Eduard - Gabriel Munteanu
4 <eduard.munteanu@linux360.ro>
5
6I. Introduction
7===============
8
9kmemtrace helps kernel developers figure out two things:
101) how different allocators (SLAB, SLUB etc.) perform
112) how kernel code allocates memory and how much
12
13To do this, we trace every allocation and export information to the userspace
14through the relay interface. We export things such as the number of requested
15bytes, the number of bytes actually allocated (i.e. including internal
16fragmentation), whether this is a slab allocation or a plain kmalloc() and so
17on.
18
19The actual analysis is performed by a userspace tool (see section III for
20details on where to get it from). It logs the data exported by the kernel,
21processes it and (as of writing this) can provide the following information:
22- the total amount of memory allocated and fragmentation per call-site
23- the amount of memory allocated and fragmentation per allocation
24- total memory allocated and fragmentation in the collected dataset
25- number of cross-CPU allocation and frees (makes sense in NUMA environments)
26
27Moreover, it can potentially find inconsistent and erroneous behavior in
28kernel code, such as using slab free functions on kmalloc'ed memory or
29allocating less memory than requested (but not truly failed allocations).
30
31kmemtrace also makes provisions for tracing on some arch and analysing the
32data on another.
33
34II. Design and goals
35====================
36
37kmemtrace was designed to handle rather large amounts of data. Thus, it uses
38the relay interface to export whatever is logged to userspace, which then
39stores it. Analysis and reporting is done asynchronously, that is, after the
40data is collected and stored. By design, it allows one to log and analyse
41on different machines and different arches.
42
43As of writing this, the ABI is not considered stable, though it might not
44change much. However, no guarantees are made about compatibility yet. When
45deemed stable, the ABI should still allow easy extension while maintaining
46backward compatibility. This is described further in Documentation/ABI.
47
48Summary of design goals:
49 - allow logging and analysis to be done across different machines
50 - be fast and anticipate usage in high-load environments (*)
51 - be reasonably extensible
52 - make it possible for GNU/Linux distributions to have kmemtrace
53 included in their repositories
54
55(*) - one of the reasons Pekka Enberg's original userspace data analysis
56 tool's code was rewritten from Perl to C (although this is more than a
57 simple conversion)
58
59
60III. Quick usage guide
61======================
62
631) Get a kernel that supports kmemtrace and build it accordingly (i.e. enable
64CONFIG_KMEMTRACE).
65
662) Get the userspace tool and build it:
67$ git-clone git://repo.or.cz/kmemtrace-user.git # current repository
68$ cd kmemtrace-user/
69$ ./autogen.sh
70$ ./configure
71$ make
72
733) Boot the kmemtrace-enabled kernel if you haven't, preferably in the
74'single' runlevel (so that relay buffers don't fill up easily), and run
75kmemtrace:
76# '$' does not mean user, but root here.
77$ mount -t debugfs none /sys/kernel/debug
78$ mount -t proc none /proc
79$ cd path/to/kmemtrace-user/
80$ ./kmemtraced
81Wait a bit, then stop it with CTRL+C.
82$ cat /sys/kernel/debug/kmemtrace/total_overruns # Check if we didn't
83 # overrun, should
84 # be zero.
85$ (Optionally) [Run kmemtrace_check separately on each cpu[0-9]*.out file to
86 check its correctness]
87$ ./kmemtrace-report
88
89Now you should have a nice and short summary of how the allocator performs.
90
91IV. FAQ and known issues
92========================
93
94Q: 'cat /sys/kernel/debug/kmemtrace/total_overruns' is non-zero, how do I fix
95this? Should I worry?
96A: If it's non-zero, this affects kmemtrace's accuracy, depending on how
97large the number is. You can fix it by supplying a higher
98'kmemtrace.subbufs=N' kernel parameter.
99---
100
101Q: kmemtrace_check reports errors, how do I fix this? Should I worry?
102A: This is a bug and should be reported. It can occur for a variety of
103reasons:
104 - possible bugs in relay code
105 - possible misuse of relay by kmemtrace
106 - timestamps being collected unorderly
107Or you may fix it yourself and send us a patch.
108---
109
110Q: kmemtrace_report shows many errors, how do I fix this? Should I worry?
111A: This is a known issue and I'm working on it. These might be true errors
112in kernel code, which may have inconsistent behavior (e.g. allocating memory
113with kmem_cache_alloc() and freeing it with kfree()). Pekka Enberg pointed
114out this behavior may work with SLAB, but may fail with other allocators.
115
116It may also be due to lack of tracing in some unusual allocator functions.
117
118We don't want bug reports regarding this issue yet.
119---
120
121V. See also
122===========
123
124Documentation/kernel-parameters.txt
125Documentation/ABI/testing/debugfs-kmemtrace
126
diff --git a/MAINTAINERS b/MAINTAINERS
index 08d0ab7fa161..857c877eee20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2566,6 +2566,12 @@ M: jason.wessel@windriver.com
2566L: kgdb-bugreport@lists.sourceforge.net 2566L: kgdb-bugreport@lists.sourceforge.net
2567S: Maintained 2567S: Maintained
2568 2568
2569KMEMTRACE
2570P: Eduard - Gabriel Munteanu
2571M: eduard.munteanu@linux360.ro
2572L: linux-kernel@vger.kernel.org
2573S: Maintained
2574
2569KPROBES 2575KPROBES
2570P: Ananth N Mavinakayanahalli 2576P: Ananth N Mavinakayanahalli
2571M: ananth@in.ibm.com 2577M: ananth@in.ibm.com
diff --git a/include/linux/kmemtrace.h b/include/linux/kmemtrace.h
new file mode 100644
index 000000000000..5bea8ead6a6b
--- /dev/null
+++ b/include/linux/kmemtrace.h
@@ -0,0 +1,86 @@
1/*
2 * Copyright (C) 2008 Eduard - Gabriel Munteanu
3 *
4 * This file is released under GPL version 2.
5 */
6
7#ifndef _LINUX_KMEMTRACE_H
8#define _LINUX_KMEMTRACE_H
9
10#ifdef __KERNEL__
11
12#include <linux/types.h>
13#include <linux/marker.h>
14
15enum kmemtrace_type_id {
16 KMEMTRACE_TYPE_KMALLOC = 0, /* kmalloc() or kfree(). */
17 KMEMTRACE_TYPE_CACHE, /* kmem_cache_*(). */
18 KMEMTRACE_TYPE_PAGES, /* __get_free_pages() and friends. */
19};
20
21#ifdef CONFIG_KMEMTRACE
22
23extern void kmemtrace_init(void);
24
25static inline void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
26 unsigned long call_site,
27 const void *ptr,
28 size_t bytes_req,
29 size_t bytes_alloc,
30 gfp_t gfp_flags,
31 int node)
32{
33 trace_mark(kmemtrace_alloc, "type_id %d call_site %lu ptr %lu "
34 "bytes_req %lu bytes_alloc %lu gfp_flags %lu node %d",
35 type_id, call_site, (unsigned long) ptr,
36 (unsigned long) bytes_req, (unsigned long) bytes_alloc,
37 (unsigned long) gfp_flags, node);
38}
39
40static inline void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
41 unsigned long call_site,
42 const void *ptr)
43{
44 trace_mark(kmemtrace_free, "type_id %d call_site %lu ptr %lu",
45 type_id, call_site, (unsigned long) ptr);
46}
47
48#else /* CONFIG_KMEMTRACE */
49
50static inline void kmemtrace_init(void)
51{
52}
53
54static inline void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
55 unsigned long call_site,
56 const void *ptr,
57 size_t bytes_req,
58 size_t bytes_alloc,
59 gfp_t gfp_flags,
60 int node)
61{
62}
63
64static inline void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
65 unsigned long call_site,
66 const void *ptr)
67{
68}
69
70#endif /* CONFIG_KMEMTRACE */
71
72static inline void kmemtrace_mark_alloc(enum kmemtrace_type_id type_id,
73 unsigned long call_site,
74 const void *ptr,
75 size_t bytes_req,
76 size_t bytes_alloc,
77 gfp_t gfp_flags)
78{
79 kmemtrace_mark_alloc_node(type_id, call_site, ptr,
80 bytes_req, bytes_alloc, gfp_flags, -1);
81}
82
83#endif /* __KERNEL__ */
84
85#endif /* _LINUX_KMEMTRACE_H */
86
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 000da12b5cf0..c97ed28559ec 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -253,9 +253,9 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
253 * request comes from. 253 * request comes from.
254 */ 254 */
255#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) 255#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
256extern void *__kmalloc_track_caller(size_t, gfp_t, void*); 256extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);
257#define kmalloc_track_caller(size, flags) \ 257#define kmalloc_track_caller(size, flags) \
258 __kmalloc_track_caller(size, flags, __builtin_return_address(0)) 258 __kmalloc_track_caller(size, flags, _RET_IP_)
259#else 259#else
260#define kmalloc_track_caller(size, flags) \ 260#define kmalloc_track_caller(size, flags) \
261 __kmalloc(size, flags) 261 __kmalloc(size, flags)
@@ -271,10 +271,10 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, void*);
271 * allocation request comes from. 271 * allocation request comes from.
272 */ 272 */
273#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) 273#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB)
274extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); 274extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long);
275#define kmalloc_node_track_caller(size, flags, node) \ 275#define kmalloc_node_track_caller(size, flags, node) \
276 __kmalloc_node_track_caller(size, flags, node, \ 276 __kmalloc_node_track_caller(size, flags, node, \
277 __builtin_return_address(0)) 277 _RET_IP_)
278#else 278#else
279#define kmalloc_node_track_caller(size, flags, node) \ 279#define kmalloc_node_track_caller(size, flags, node) \
280 __kmalloc_node(size, flags, node) 280 __kmalloc_node(size, flags, node)
diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h
index 39c3a5eb8ebe..7555ce99f6d2 100644
--- a/include/linux/slab_def.h
+++ b/include/linux/slab_def.h
@@ -14,6 +14,7 @@
14#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */ 14#include <asm/page.h> /* kmalloc_sizes.h needs PAGE_SIZE */
15#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */ 15#include <asm/cache.h> /* kmalloc_sizes.h needs L1_CACHE_BYTES */
16#include <linux/compiler.h> 16#include <linux/compiler.h>
17#include <linux/kmemtrace.h>
17 18
18/* Size description struct for general caches. */ 19/* Size description struct for general caches. */
19struct cache_sizes { 20struct cache_sizes {
@@ -28,8 +29,26 @@ extern struct cache_sizes malloc_sizes[];
28void *kmem_cache_alloc(struct kmem_cache *, gfp_t); 29void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
29void *__kmalloc(size_t size, gfp_t flags); 30void *__kmalloc(size_t size, gfp_t flags);
30 31
31static inline void *kmalloc(size_t size, gfp_t flags) 32#ifdef CONFIG_KMEMTRACE
33extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags);
34extern size_t slab_buffer_size(struct kmem_cache *cachep);
35#else
36static __always_inline void *
37kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
32{ 38{
39 return kmem_cache_alloc(cachep, flags);
40}
41static inline size_t slab_buffer_size(struct kmem_cache *cachep)
42{
43 return 0;
44}
45#endif
46
47static __always_inline void *kmalloc(size_t size, gfp_t flags)
48{
49 struct kmem_cache *cachep;
50 void *ret;
51
33 if (__builtin_constant_p(size)) { 52 if (__builtin_constant_p(size)) {
34 int i = 0; 53 int i = 0;
35 54
@@ -50,10 +69,17 @@ static inline void *kmalloc(size_t size, gfp_t flags)
50found: 69found:
51#ifdef CONFIG_ZONE_DMA 70#ifdef CONFIG_ZONE_DMA
52 if (flags & GFP_DMA) 71 if (flags & GFP_DMA)
53 return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep, 72 cachep = malloc_sizes[i].cs_dmacachep;
54 flags); 73 else
55#endif 74#endif
56 return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags); 75 cachep = malloc_sizes[i].cs_cachep;
76
77 ret = kmem_cache_alloc_notrace(cachep, flags);
78
79 kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret,
80 size, slab_buffer_size(cachep), flags);
81
82 return ret;
57 } 83 }
58 return __kmalloc(size, flags); 84 return __kmalloc(size, flags);
59} 85}
@@ -62,8 +88,25 @@ found:
62extern void *__kmalloc_node(size_t size, gfp_t flags, int node); 88extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
63extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); 89extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
64 90
65static inline void *kmalloc_node(size_t size, gfp_t flags, int node) 91#ifdef CONFIG_KMEMTRACE
92extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
93 gfp_t flags,
94 int nodeid);
95#else
96static __always_inline void *
97kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
98 gfp_t flags,
99 int nodeid)
100{
101 return kmem_cache_alloc_node(cachep, flags, nodeid);
102}
103#endif
104
105static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
66{ 106{
107 struct kmem_cache *cachep;
108 void *ret;
109
67 if (__builtin_constant_p(size)) { 110 if (__builtin_constant_p(size)) {
68 int i = 0; 111 int i = 0;
69 112
@@ -84,11 +127,18 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
84found: 127found:
85#ifdef CONFIG_ZONE_DMA 128#ifdef CONFIG_ZONE_DMA
86 if (flags & GFP_DMA) 129 if (flags & GFP_DMA)
87 return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep, 130 cachep = malloc_sizes[i].cs_dmacachep;
88 flags, node); 131 else
89#endif 132#endif
90 return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep, 133 cachep = malloc_sizes[i].cs_cachep;
91 flags, node); 134
135 ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
136
137 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_,
138 ret, size, slab_buffer_size(cachep),
139 flags, node);
140
141 return ret;
92 } 142 }
93 return __kmalloc_node(size, flags, node); 143 return __kmalloc_node(size, flags, node);
94} 144}
diff --git a/include/linux/slob_def.h b/include/linux/slob_def.h
index 59a3fa476ab9..0ec00b39d006 100644
--- a/include/linux/slob_def.h
+++ b/include/linux/slob_def.h
@@ -3,14 +3,15 @@
3 3
4void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); 4void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
5 5
6static inline void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) 6static __always_inline void *kmem_cache_alloc(struct kmem_cache *cachep,
7 gfp_t flags)
7{ 8{
8 return kmem_cache_alloc_node(cachep, flags, -1); 9 return kmem_cache_alloc_node(cachep, flags, -1);
9} 10}
10 11
11void *__kmalloc_node(size_t size, gfp_t flags, int node); 12void *__kmalloc_node(size_t size, gfp_t flags, int node);
12 13
13static inline void *kmalloc_node(size_t size, gfp_t flags, int node) 14static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
14{ 15{
15 return __kmalloc_node(size, flags, node); 16 return __kmalloc_node(size, flags, node);
16} 17}
@@ -23,12 +24,12 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
23 * kmalloc is the normal method of allocating memory 24 * kmalloc is the normal method of allocating memory
24 * in the kernel. 25 * in the kernel.
25 */ 26 */
26static inline void *kmalloc(size_t size, gfp_t flags) 27static __always_inline void *kmalloc(size_t size, gfp_t flags)
27{ 28{
28 return __kmalloc_node(size, flags, -1); 29 return __kmalloc_node(size, flags, -1);
29} 30}
30 31
31static inline void *__kmalloc(size_t size, gfp_t flags) 32static __always_inline void *__kmalloc(size_t size, gfp_t flags)
32{ 33{
33 return kmalloc(size, flags); 34 return kmalloc(size, flags);
34} 35}
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 2f5c16b1aacd..dc28432b5b9a 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -10,6 +10,7 @@
10#include <linux/gfp.h> 10#include <linux/gfp.h>
11#include <linux/workqueue.h> 11#include <linux/workqueue.h>
12#include <linux/kobject.h> 12#include <linux/kobject.h>
13#include <linux/kmemtrace.h>
13 14
14enum stat_item { 15enum stat_item {
15 ALLOC_FASTPATH, /* Allocation from cpu slab */ 16 ALLOC_FASTPATH, /* Allocation from cpu slab */
@@ -204,13 +205,31 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size)
204void *kmem_cache_alloc(struct kmem_cache *, gfp_t); 205void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
205void *__kmalloc(size_t size, gfp_t flags); 206void *__kmalloc(size_t size, gfp_t flags);
206 207
208#ifdef CONFIG_KMEMTRACE
209extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags);
210#else
211static __always_inline void *
212kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
213{
214 return kmem_cache_alloc(s, gfpflags);
215}
216#endif
217
207static __always_inline void *kmalloc_large(size_t size, gfp_t flags) 218static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
208{ 219{
209 return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size)); 220 unsigned int order = get_order(size);
221 void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order);
222
223 kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _THIS_IP_, ret,
224 size, PAGE_SIZE << order, flags);
225
226 return ret;
210} 227}
211 228
212static __always_inline void *kmalloc(size_t size, gfp_t flags) 229static __always_inline void *kmalloc(size_t size, gfp_t flags)
213{ 230{
231 void *ret;
232
214 if (__builtin_constant_p(size)) { 233 if (__builtin_constant_p(size)) {
215 if (size > PAGE_SIZE) 234 if (size > PAGE_SIZE)
216 return kmalloc_large(size, flags); 235 return kmalloc_large(size, flags);
@@ -221,7 +240,13 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags)
221 if (!s) 240 if (!s)
222 return ZERO_SIZE_PTR; 241 return ZERO_SIZE_PTR;
223 242
224 return kmem_cache_alloc(s, flags); 243 ret = kmem_cache_alloc_notrace(s, flags);
244
245 kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC,
246 _THIS_IP_, ret,
247 size, s->size, flags);
248
249 return ret;
225 } 250 }
226 } 251 }
227 return __kmalloc(size, flags); 252 return __kmalloc(size, flags);
@@ -231,8 +256,24 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags)
231void *__kmalloc_node(size_t size, gfp_t flags, int node); 256void *__kmalloc_node(size_t size, gfp_t flags, int node);
232void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); 257void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
233 258
259#ifdef CONFIG_KMEMTRACE
260extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
261 gfp_t gfpflags,
262 int node);
263#else
264static __always_inline void *
265kmem_cache_alloc_node_notrace(struct kmem_cache *s,
266 gfp_t gfpflags,
267 int node)
268{
269 return kmem_cache_alloc_node(s, gfpflags, node);
270}
271#endif
272
234static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) 273static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
235{ 274{
275 void *ret;
276
236 if (__builtin_constant_p(size) && 277 if (__builtin_constant_p(size) &&
237 size <= PAGE_SIZE && !(flags & SLUB_DMA)) { 278 size <= PAGE_SIZE && !(flags & SLUB_DMA)) {
238 struct kmem_cache *s = kmalloc_slab(size); 279 struct kmem_cache *s = kmalloc_slab(size);
@@ -240,7 +281,13 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
240 if (!s) 281 if (!s)
241 return ZERO_SIZE_PTR; 282 return ZERO_SIZE_PTR;
242 283
243 return kmem_cache_alloc_node(s, flags, node); 284 ret = kmem_cache_alloc_node_notrace(s, flags, node);
285
286 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
287 _THIS_IP_, ret,
288 size, s->size, flags, node);
289
290 return ret;
244 } 291 }
245 return __kmalloc_node(size, flags, node); 292 return __kmalloc_node(size, flags, node);
246} 293}
diff --git a/init/main.c b/init/main.c
index 17e9757bfde2..9711586aa7c9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -70,6 +70,7 @@
70#include <asm/setup.h> 70#include <asm/setup.h>
71#include <asm/sections.h> 71#include <asm/sections.h>
72#include <asm/cacheflush.h> 72#include <asm/cacheflush.h>
73#include <linux/kmemtrace.h>
73 74
74#ifdef CONFIG_X86_LOCAL_APIC 75#ifdef CONFIG_X86_LOCAL_APIC
75#include <asm/smp.h> 76#include <asm/smp.h>
@@ -654,6 +655,7 @@ asmlinkage void __init start_kernel(void)
654 enable_debug_pagealloc(); 655 enable_debug_pagealloc();
655 cpu_hotplug_init(); 656 cpu_hotplug_init();
656 kmem_cache_init(); 657 kmem_cache_init();
658 kmemtrace_init();
657 debug_objects_mem_init(); 659 debug_objects_mem_init();
658 idr_init_cache(); 660 idr_init_cache();
659 setup_per_cpu_pageset(); 661 setup_per_cpu_pageset();
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index b0f239e443bc..b5417e23ba94 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -803,6 +803,26 @@ config FIREWIRE_OHCI_REMOTE_DMA
803 803
804 If unsure, say N. 804 If unsure, say N.
805 805
806config KMEMTRACE
807 bool "Kernel memory tracer (kmemtrace)"
808 depends on RELAY && DEBUG_FS && MARKERS
809 help
810 kmemtrace provides tracing for slab allocator functions, such as
811 kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected
812 data is then fed to the userspace application in order to analyse
813 allocation hotspots, internal fragmentation and so on, making it
814 possible to see how well an allocator performs, as well as debug
815 and profile kernel code.
816
817 This requires an userspace application to use. See
818 Documentation/vm/kmemtrace.txt for more information.
819
820 Saying Y will make the kernel somewhat larger and slower. However,
821 if you disable kmemtrace at run-time or boot-time, the performance
822 impact is minimal (depending on the arch the kernel is built for).
823
824 If unsure, say N.
825
806menuconfig BUILD_DOCSRC 826menuconfig BUILD_DOCSRC
807 bool "Build targets in Documentation/ tree" 827 bool "Build targets in Documentation/ tree"
808 depends on HEADERS_CHECK 828 depends on HEADERS_CHECK
diff --git a/mm/Makefile b/mm/Makefile
index c06b45a1ff5f..3782eb66d4b3 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -34,3 +34,4 @@ obj-$(CONFIG_MIGRATION) += migrate.o
34obj-$(CONFIG_SMP) += allocpercpu.o 34obj-$(CONFIG_SMP) += allocpercpu.o
35obj-$(CONFIG_QUICKLIST) += quicklist.o 35obj-$(CONFIG_QUICKLIST) += quicklist.o
36obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o 36obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
37obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
diff --git a/mm/kmemtrace.c b/mm/kmemtrace.c
new file mode 100644
index 000000000000..2a70a805027c
--- /dev/null
+++ b/mm/kmemtrace.c
@@ -0,0 +1,333 @@
1/*
2 * Copyright (C) 2008 Pekka Enberg, Eduard - Gabriel Munteanu
3 *
4 * This file is released under GPL version 2.
5 */
6
7#include <linux/string.h>
8#include <linux/debugfs.h>
9#include <linux/relay.h>
10#include <linux/module.h>
11#include <linux/marker.h>
12#include <linux/gfp.h>
13#include <linux/kmemtrace.h>
14
15#define KMEMTRACE_SUBBUF_SIZE 524288
16#define KMEMTRACE_DEF_N_SUBBUFS 20
17
18static struct rchan *kmemtrace_chan;
19static u32 kmemtrace_buf_overruns;
20
21static unsigned int kmemtrace_n_subbufs;
22
23/* disabled by default */
24static unsigned int kmemtrace_enabled;
25
26/*
27 * The sequence number is used for reordering kmemtrace packets
28 * in userspace, since they are logged as per-CPU data.
29 *
30 * atomic_t should always be a 32-bit signed integer. Wraparound is not
31 * likely to occur, but userspace can deal with it by expecting a certain
32 * sequence number in the next packet that will be read.
33 */
34static atomic_t kmemtrace_seq_num;
35
36#define KMEMTRACE_ABI_VERSION 1
37
38static u32 kmemtrace_abi_version __read_mostly = KMEMTRACE_ABI_VERSION;
39
40enum kmemtrace_event_id {
41 KMEMTRACE_EVENT_ALLOC = 0,
42 KMEMTRACE_EVENT_FREE,
43};
44
45struct kmemtrace_event {
46 u8 event_id;
47 u8 type_id;
48 u16 event_size;
49 s32 seq_num;
50 u64 call_site;
51 u64 ptr;
52} __attribute__ ((__packed__));
53
54struct kmemtrace_stats_alloc {
55 u64 bytes_req;
56 u64 bytes_alloc;
57 u32 gfp_flags;
58 s32 numa_node;
59} __attribute__ ((__packed__));
60
61static void kmemtrace_probe_alloc(void *probe_data, void *call_data,
62 const char *format, va_list *args)
63{
64 unsigned long flags;
65 struct kmemtrace_event *ev;
66 struct kmemtrace_stats_alloc *stats;
67 void *buf;
68
69 local_irq_save(flags);
70
71 buf = relay_reserve(kmemtrace_chan,
72 sizeof(struct kmemtrace_event) +
73 sizeof(struct kmemtrace_stats_alloc));
74 if (!buf)
75 goto failed;
76
77 /*
78 * Don't convert this to use structure initializers,
79 * C99 does not guarantee the rvalues evaluation order.
80 */
81
82 ev = buf;
83 ev->event_id = KMEMTRACE_EVENT_ALLOC;
84 ev->type_id = va_arg(*args, int);
85 ev->event_size = sizeof(struct kmemtrace_event) +
86 sizeof(struct kmemtrace_stats_alloc);
87 ev->seq_num = atomic_add_return(1, &kmemtrace_seq_num);
88 ev->call_site = va_arg(*args, unsigned long);
89 ev->ptr = va_arg(*args, unsigned long);
90
91 stats = buf + sizeof(struct kmemtrace_event);
92 stats->bytes_req = va_arg(*args, unsigned long);
93 stats->bytes_alloc = va_arg(*args, unsigned long);
94 stats->gfp_flags = va_arg(*args, unsigned long);
95 stats->numa_node = va_arg(*args, int);
96
97failed:
98 local_irq_restore(flags);
99}
100
101static void kmemtrace_probe_free(void *probe_data, void *call_data,
102 const char *format, va_list *args)
103{
104 unsigned long flags;
105 struct kmemtrace_event *ev;
106
107 local_irq_save(flags);
108
109 ev = relay_reserve(kmemtrace_chan, sizeof(struct kmemtrace_event));
110 if (!ev)
111 goto failed;
112
113 /*
114 * Don't convert this to use structure initializers,
115 * C99 does not guarantee the rvalues evaluation order.
116 */
117 ev->event_id = KMEMTRACE_EVENT_FREE;
118 ev->type_id = va_arg(*args, int);
119 ev->event_size = sizeof(struct kmemtrace_event);
120 ev->seq_num = atomic_add_return(1, &kmemtrace_seq_num);
121 ev->call_site = va_arg(*args, unsigned long);
122 ev->ptr = va_arg(*args, unsigned long);
123
124failed:
125 local_irq_restore(flags);
126}
127
128static struct dentry *
129kmemtrace_create_buf_file(const char *filename, struct dentry *parent,
130 int mode, struct rchan_buf *buf, int *is_global)
131{
132 return debugfs_create_file(filename, mode, parent, buf,
133 &relay_file_operations);
134}
135
136static int kmemtrace_remove_buf_file(struct dentry *dentry)
137{
138 debugfs_remove(dentry);
139
140 return 0;
141}
142
143static int kmemtrace_subbuf_start(struct rchan_buf *buf,
144 void *subbuf,
145 void *prev_subbuf,
146 size_t prev_padding)
147{
148 if (relay_buf_full(buf)) {
149 /*
150 * We know it's not SMP-safe, but neither
151 * debugfs_create_u32() is.
152 */
153 kmemtrace_buf_overruns++;
154 return 0;
155 }
156
157 return 1;
158}
159
160static struct rchan_callbacks relay_callbacks = {
161 .create_buf_file = kmemtrace_create_buf_file,
162 .remove_buf_file = kmemtrace_remove_buf_file,
163 .subbuf_start = kmemtrace_subbuf_start,
164};
165
166static struct dentry *kmemtrace_dir;
167static struct dentry *kmemtrace_overruns_dentry;
168static struct dentry *kmemtrace_abi_version_dentry;
169
170static struct dentry *kmemtrace_enabled_dentry;
171
172static int kmemtrace_start_probes(void)
173{
174 int err;
175
176 err = marker_probe_register("kmemtrace_alloc", "type_id %d "
177 "call_site %lu ptr %lu "
178 "bytes_req %lu bytes_alloc %lu "
179 "gfp_flags %lu node %d",
180 kmemtrace_probe_alloc, NULL);
181 if (err)
182 return err;
183 err = marker_probe_register("kmemtrace_free", "type_id %d "
184 "call_site %lu ptr %lu",
185 kmemtrace_probe_free, NULL);
186
187 return err;
188}
189
190static void kmemtrace_stop_probes(void)
191{
192 marker_probe_unregister("kmemtrace_alloc",
193 kmemtrace_probe_alloc, NULL);
194 marker_probe_unregister("kmemtrace_free",
195 kmemtrace_probe_free, NULL);
196}
197
198static int kmemtrace_enabled_get(void *data, u64 *val)
199{
200 *val = *((int *) data);
201
202 return 0;
203}
204
205static int kmemtrace_enabled_set(void *data, u64 val)
206{
207 u64 old_val = kmemtrace_enabled;
208
209 *((int *) data) = !!val;
210
211 if (old_val == val)
212 return 0;
213 if (val)
214 kmemtrace_start_probes();
215 else
216 kmemtrace_stop_probes();
217
218 return 0;
219}
220
221DEFINE_SIMPLE_ATTRIBUTE(kmemtrace_enabled_fops,
222 kmemtrace_enabled_get,
223 kmemtrace_enabled_set, "%llu\n");
224
225static void kmemtrace_cleanup(void)
226{
227 if (kmemtrace_enabled_dentry)
228 debugfs_remove(kmemtrace_enabled_dentry);
229
230 kmemtrace_stop_probes();
231
232 if (kmemtrace_abi_version_dentry)
233 debugfs_remove(kmemtrace_abi_version_dentry);
234 if (kmemtrace_overruns_dentry)
235 debugfs_remove(kmemtrace_overruns_dentry);
236
237 relay_close(kmemtrace_chan);
238 kmemtrace_chan = NULL;
239
240 if (kmemtrace_dir)
241 debugfs_remove(kmemtrace_dir);
242}
243
244static int __init kmemtrace_setup_late(void)
245{
246 if (!kmemtrace_chan)
247 goto failed;
248
249 kmemtrace_dir = debugfs_create_dir("kmemtrace", NULL);
250 if (!kmemtrace_dir)
251 goto cleanup;
252
253 kmemtrace_abi_version_dentry =
254 debugfs_create_u32("abi_version", S_IRUSR,
255 kmemtrace_dir, &kmemtrace_abi_version);
256 kmemtrace_overruns_dentry =
257 debugfs_create_u32("total_overruns", S_IRUSR,
258 kmemtrace_dir, &kmemtrace_buf_overruns);
259 if (!kmemtrace_overruns_dentry || !kmemtrace_abi_version_dentry)
260 goto cleanup;
261
262 kmemtrace_enabled_dentry =
263 debugfs_create_file("enabled", S_IRUSR | S_IWUSR,
264 kmemtrace_dir, &kmemtrace_enabled,
265 &kmemtrace_enabled_fops);
266 if (!kmemtrace_enabled_dentry)
267 goto cleanup;
268
269 if (relay_late_setup_files(kmemtrace_chan, "cpu", kmemtrace_dir))
270 goto cleanup;
271
272 printk(KERN_INFO "kmemtrace: fully up.\n");
273
274 return 0;
275
276cleanup:
277 kmemtrace_cleanup();
278failed:
279 return 1;
280}
281late_initcall(kmemtrace_setup_late);
282
283static int __init kmemtrace_set_boot_enabled(char *str)
284{
285 if (!str)
286 return -EINVAL;
287
288 if (!strcmp(str, "yes"))
289 kmemtrace_enabled = 1;
290 else if (!strcmp(str, "no"))
291 kmemtrace_enabled = 0;
292 else
293 return -EINVAL;
294
295 return 0;
296}
297early_param("kmemtrace.enable", kmemtrace_set_boot_enabled);
298
299static int __init kmemtrace_set_subbufs(char *str)
300{
301 get_option(&str, &kmemtrace_n_subbufs);
302 return 0;
303}
304early_param("kmemtrace.subbufs", kmemtrace_set_subbufs);
305
306void kmemtrace_init(void)
307{
308 if (!kmemtrace_n_subbufs)
309 kmemtrace_n_subbufs = KMEMTRACE_DEF_N_SUBBUFS;
310
311 kmemtrace_chan = relay_open(NULL, NULL, KMEMTRACE_SUBBUF_SIZE,
312 kmemtrace_n_subbufs, &relay_callbacks,
313 NULL);
314 if (!kmemtrace_chan) {
315 printk(KERN_ERR "kmemtrace: could not open relay channel.\n");
316 return;
317 }
318
319 if (!kmemtrace_enabled) {
320 printk(KERN_INFO "kmemtrace: disabled. Pass "
321 "kemtrace.enable=yes as kernel parameter for "
322 "boot-time tracing.\n");
323 return;
324 }
325 if (kmemtrace_start_probes()) {
326 printk(KERN_ERR "kmemtrace: could not register marker probes!\n");
327 kmemtrace_cleanup();
328 return;
329 }
330
331 printk(KERN_INFO "kmemtrace: enabled.\n");
332}
333
diff --git a/mm/slab.c b/mm/slab.c
index 09187517f9dc..b6d9b8cdefa9 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -112,6 +112,7 @@
112#include <linux/rtmutex.h> 112#include <linux/rtmutex.h>
113#include <linux/reciprocal_div.h> 113#include <linux/reciprocal_div.h>
114#include <linux/debugobjects.h> 114#include <linux/debugobjects.h>
115#include <linux/kmemtrace.h>
115 116
116#include <asm/cacheflush.h> 117#include <asm/cacheflush.h>
117#include <asm/tlbflush.h> 118#include <asm/tlbflush.h>
@@ -568,6 +569,14 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp)
568 569
569#endif 570#endif
570 571
572#ifdef CONFIG_KMEMTRACE
573size_t slab_buffer_size(struct kmem_cache *cachep)
574{
575 return cachep->buffer_size;
576}
577EXPORT_SYMBOL(slab_buffer_size);
578#endif
579
571/* 580/*
572 * Do not go above this order unless 0 objects fit into the slab. 581 * Do not go above this order unless 0 objects fit into the slab.
573 */ 582 */
@@ -3613,10 +3622,23 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
3613 */ 3622 */
3614void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) 3623void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
3615{ 3624{
3616 return __cache_alloc(cachep, flags, __builtin_return_address(0)); 3625 void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
3626
3627 kmemtrace_mark_alloc(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
3628 obj_size(cachep), cachep->buffer_size, flags);
3629
3630 return ret;
3617} 3631}
3618EXPORT_SYMBOL(kmem_cache_alloc); 3632EXPORT_SYMBOL(kmem_cache_alloc);
3619 3633
3634#ifdef CONFIG_KMEMTRACE
3635void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
3636{
3637 return __cache_alloc(cachep, flags, __builtin_return_address(0));
3638}
3639EXPORT_SYMBOL(kmem_cache_alloc_notrace);
3640#endif
3641
3620/** 3642/**
3621 * kmem_ptr_validate - check if an untrusted pointer might be a slab entry. 3643 * kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
3622 * @cachep: the cache we're checking against 3644 * @cachep: the cache we're checking against
@@ -3661,23 +3683,47 @@ out:
3661#ifdef CONFIG_NUMA 3683#ifdef CONFIG_NUMA
3662void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) 3684void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
3663{ 3685{
3664 return __cache_alloc_node(cachep, flags, nodeid, 3686 void *ret = __cache_alloc_node(cachep, flags, nodeid,
3665 __builtin_return_address(0)); 3687 __builtin_return_address(0));
3688
3689 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
3690 obj_size(cachep), cachep->buffer_size,
3691 flags, nodeid);
3692
3693 return ret;
3666} 3694}
3667EXPORT_SYMBOL(kmem_cache_alloc_node); 3695EXPORT_SYMBOL(kmem_cache_alloc_node);
3668 3696
3697#ifdef CONFIG_KMEMTRACE
3698void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
3699 gfp_t flags,
3700 int nodeid)
3701{
3702 return __cache_alloc_node(cachep, flags, nodeid,
3703 __builtin_return_address(0));
3704}
3705EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
3706#endif
3707
3669static __always_inline void * 3708static __always_inline void *
3670__do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) 3709__do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
3671{ 3710{
3672 struct kmem_cache *cachep; 3711 struct kmem_cache *cachep;
3712 void *ret;
3673 3713
3674 cachep = kmem_find_general_cachep(size, flags); 3714 cachep = kmem_find_general_cachep(size, flags);
3675 if (unlikely(ZERO_OR_NULL_PTR(cachep))) 3715 if (unlikely(ZERO_OR_NULL_PTR(cachep)))
3676 return cachep; 3716 return cachep;
3677 return kmem_cache_alloc_node(cachep, flags, node); 3717 ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
3718
3719 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
3720 (unsigned long) caller, ret,
3721 size, cachep->buffer_size, flags, node);
3722
3723 return ret;
3678} 3724}
3679 3725
3680#ifdef CONFIG_DEBUG_SLAB 3726#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
3681void *__kmalloc_node(size_t size, gfp_t flags, int node) 3727void *__kmalloc_node(size_t size, gfp_t flags, int node)
3682{ 3728{
3683 return __do_kmalloc_node(size, flags, node, 3729 return __do_kmalloc_node(size, flags, node,
@@ -3686,9 +3732,9 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node)
3686EXPORT_SYMBOL(__kmalloc_node); 3732EXPORT_SYMBOL(__kmalloc_node);
3687 3733
3688void *__kmalloc_node_track_caller(size_t size, gfp_t flags, 3734void *__kmalloc_node_track_caller(size_t size, gfp_t flags,
3689 int node, void *caller) 3735 int node, unsigned long caller)
3690{ 3736{
3691 return __do_kmalloc_node(size, flags, node, caller); 3737 return __do_kmalloc_node(size, flags, node, (void *)caller);
3692} 3738}
3693EXPORT_SYMBOL(__kmalloc_node_track_caller); 3739EXPORT_SYMBOL(__kmalloc_node_track_caller);
3694#else 3740#else
@@ -3710,6 +3756,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
3710 void *caller) 3756 void *caller)
3711{ 3757{
3712 struct kmem_cache *cachep; 3758 struct kmem_cache *cachep;
3759 void *ret;
3713 3760
3714 /* If you want to save a few bytes .text space: replace 3761 /* If you want to save a few bytes .text space: replace
3715 * __ with kmem_. 3762 * __ with kmem_.
@@ -3719,20 +3766,26 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
3719 cachep = __find_general_cachep(size, flags); 3766 cachep = __find_general_cachep(size, flags);
3720 if (unlikely(ZERO_OR_NULL_PTR(cachep))) 3767 if (unlikely(ZERO_OR_NULL_PTR(cachep)))
3721 return cachep; 3768 return cachep;
3722 return __cache_alloc(cachep, flags, caller); 3769 ret = __cache_alloc(cachep, flags, caller);
3770
3771 kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC,
3772 (unsigned long) caller, ret,
3773 size, cachep->buffer_size, flags);
3774
3775 return ret;
3723} 3776}
3724 3777
3725 3778
3726#ifdef CONFIG_DEBUG_SLAB 3779#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
3727void *__kmalloc(size_t size, gfp_t flags) 3780void *__kmalloc(size_t size, gfp_t flags)
3728{ 3781{
3729 return __do_kmalloc(size, flags, __builtin_return_address(0)); 3782 return __do_kmalloc(size, flags, __builtin_return_address(0));
3730} 3783}
3731EXPORT_SYMBOL(__kmalloc); 3784EXPORT_SYMBOL(__kmalloc);
3732 3785
3733void *__kmalloc_track_caller(size_t size, gfp_t flags, void *caller) 3786void *__kmalloc_track_caller(size_t size, gfp_t flags, unsigned long caller)
3734{ 3787{
3735 return __do_kmalloc(size, flags, caller); 3788 return __do_kmalloc(size, flags, (void *)caller);
3736} 3789}
3737EXPORT_SYMBOL(__kmalloc_track_caller); 3790EXPORT_SYMBOL(__kmalloc_track_caller);
3738 3791
@@ -3762,6 +3815,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
3762 debug_check_no_obj_freed(objp, obj_size(cachep)); 3815 debug_check_no_obj_freed(objp, obj_size(cachep));
3763 __cache_free(cachep, objp); 3816 __cache_free(cachep, objp);
3764 local_irq_restore(flags); 3817 local_irq_restore(flags);
3818
3819 kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, objp);
3765} 3820}
3766EXPORT_SYMBOL(kmem_cache_free); 3821EXPORT_SYMBOL(kmem_cache_free);
3767 3822
@@ -3788,6 +3843,8 @@ void kfree(const void *objp)
3788 debug_check_no_obj_freed(objp, obj_size(c)); 3843 debug_check_no_obj_freed(objp, obj_size(c));
3789 __cache_free(c, (void *)objp); 3844 __cache_free(c, (void *)objp);
3790 local_irq_restore(flags); 3845 local_irq_restore(flags);
3846
3847 kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, objp);
3791} 3848}
3792EXPORT_SYMBOL(kfree); 3849EXPORT_SYMBOL(kfree);
3793 3850
diff --git a/mm/slob.c b/mm/slob.c
index bf7e8fc3aed8..0f1a49f40690 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -65,6 +65,7 @@
65#include <linux/module.h> 65#include <linux/module.h>
66#include <linux/rcupdate.h> 66#include <linux/rcupdate.h>
67#include <linux/list.h> 67#include <linux/list.h>
68#include <linux/kmemtrace.h>
68#include <asm/atomic.h> 69#include <asm/atomic.h>
69 70
70/* 71/*
@@ -463,27 +464,38 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
463{ 464{
464 unsigned int *m; 465 unsigned int *m;
465 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN); 466 int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
467 void *ret;
466 468
467 if (size < PAGE_SIZE - align) { 469 if (size < PAGE_SIZE - align) {
468 if (!size) 470 if (!size)
469 return ZERO_SIZE_PTR; 471 return ZERO_SIZE_PTR;
470 472
471 m = slob_alloc(size + align, gfp, align, node); 473 m = slob_alloc(size + align, gfp, align, node);
474
472 if (!m) 475 if (!m)
473 return NULL; 476 return NULL;
474 *m = size; 477 *m = size;
475 return (void *)m + align; 478 ret = (void *)m + align;
479
480 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
481 _RET_IP_, ret,
482 size, size + align, gfp, node);
476 } else { 483 } else {
477 void *ret; 484 unsigned int order = get_order(size);
478 485
479 ret = slob_new_page(gfp | __GFP_COMP, get_order(size), node); 486 ret = slob_new_page(gfp | __GFP_COMP, order, node);
480 if (ret) { 487 if (ret) {
481 struct page *page; 488 struct page *page;
482 page = virt_to_page(ret); 489 page = virt_to_page(ret);
483 page->private = size; 490 page->private = size;
484 } 491 }
485 return ret; 492
493 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
494 _RET_IP_, ret,
495 size, PAGE_SIZE << order, gfp, node);
486 } 496 }
497
498 return ret;
487} 499}
488EXPORT_SYMBOL(__kmalloc_node); 500EXPORT_SYMBOL(__kmalloc_node);
489 501
@@ -501,6 +513,8 @@ void kfree(const void *block)
501 slob_free(m, *m + align); 513 slob_free(m, *m + align);
502 } else 514 } else
503 put_page(&sp->page); 515 put_page(&sp->page);
516
517 kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, block);
504} 518}
505EXPORT_SYMBOL(kfree); 519EXPORT_SYMBOL(kfree);
506 520
@@ -569,10 +583,19 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
569{ 583{
570 void *b; 584 void *b;
571 585
572 if (c->size < PAGE_SIZE) 586 if (c->size < PAGE_SIZE) {
573 b = slob_alloc(c->size, flags, c->align, node); 587 b = slob_alloc(c->size, flags, c->align, node);
574 else 588 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE,
589 _RET_IP_, b, c->size,
590 SLOB_UNITS(c->size) * SLOB_UNIT,
591 flags, node);
592 } else {
575 b = slob_new_page(flags, get_order(c->size), node); 593 b = slob_new_page(flags, get_order(c->size), node);
594 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE,
595 _RET_IP_, b, c->size,
596 PAGE_SIZE << get_order(c->size),
597 flags, node);
598 }
576 599
577 if (c->ctor) 600 if (c->ctor)
578 c->ctor(b); 601 c->ctor(b);
@@ -608,6 +631,8 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
608 } else { 631 } else {
609 __kmem_cache_free(b, c->size); 632 __kmem_cache_free(b, c->size);
610 } 633 }
634
635 kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, b);
611} 636}
612EXPORT_SYMBOL(kmem_cache_free); 637EXPORT_SYMBOL(kmem_cache_free);
613 638
diff --git a/mm/slub.c b/mm/slub.c
index a2cd47d89e0a..4cd7bfd2ab2c 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -24,6 +24,7 @@
24#include <linux/kallsyms.h> 24#include <linux/kallsyms.h>
25#include <linux/memory.h> 25#include <linux/memory.h>
26#include <linux/math64.h> 26#include <linux/math64.h>
27#include <linux/kmemtrace.h>
27 28
28/* 29/*
29 * Lock order: 30 * Lock order:
@@ -178,7 +179,7 @@ static LIST_HEAD(slab_caches);
178 * Tracking user of a slab. 179 * Tracking user of a slab.
179 */ 180 */
180struct track { 181struct track {
181 void *addr; /* Called from address */ 182 unsigned long addr; /* Called from address */
182 int cpu; /* Was running on cpu */ 183 int cpu; /* Was running on cpu */
183 int pid; /* Pid context */ 184 int pid; /* Pid context */
184 unsigned long when; /* When did the operation occur */ 185 unsigned long when; /* When did the operation occur */
@@ -367,7 +368,7 @@ static struct track *get_track(struct kmem_cache *s, void *object,
367} 368}
368 369
369static void set_track(struct kmem_cache *s, void *object, 370static void set_track(struct kmem_cache *s, void *object,
370 enum track_item alloc, void *addr) 371 enum track_item alloc, unsigned long addr)
371{ 372{
372 struct track *p; 373 struct track *p;
373 374
@@ -391,8 +392,8 @@ static void init_tracking(struct kmem_cache *s, void *object)
391 if (!(s->flags & SLAB_STORE_USER)) 392 if (!(s->flags & SLAB_STORE_USER))
392 return; 393 return;
393 394
394 set_track(s, object, TRACK_FREE, NULL); 395 set_track(s, object, TRACK_FREE, 0UL);
395 set_track(s, object, TRACK_ALLOC, NULL); 396 set_track(s, object, TRACK_ALLOC, 0UL);
396} 397}
397 398
398static void print_track(const char *s, struct track *t) 399static void print_track(const char *s, struct track *t)
@@ -401,7 +402,7 @@ static void print_track(const char *s, struct track *t)
401 return; 402 return;
402 403
403 printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n", 404 printk(KERN_ERR "INFO: %s in %pS age=%lu cpu=%u pid=%d\n",
404 s, t->addr, jiffies - t->when, t->cpu, t->pid); 405 s, (void *)t->addr, jiffies - t->when, t->cpu, t->pid);
405} 406}
406 407
407static void print_tracking(struct kmem_cache *s, void *object) 408static void print_tracking(struct kmem_cache *s, void *object)
@@ -866,7 +867,7 @@ static void setup_object_debug(struct kmem_cache *s, struct page *page,
866} 867}
867 868
868static int alloc_debug_processing(struct kmem_cache *s, struct page *page, 869static int alloc_debug_processing(struct kmem_cache *s, struct page *page,
869 void *object, void *addr) 870 void *object, unsigned long addr)
870{ 871{
871 if (!check_slab(s, page)) 872 if (!check_slab(s, page))
872 goto bad; 873 goto bad;
@@ -906,7 +907,7 @@ bad:
906} 907}
907 908
908static int free_debug_processing(struct kmem_cache *s, struct page *page, 909static int free_debug_processing(struct kmem_cache *s, struct page *page,
909 void *object, void *addr) 910 void *object, unsigned long addr)
910{ 911{
911 if (!check_slab(s, page)) 912 if (!check_slab(s, page))
912 goto fail; 913 goto fail;
@@ -1029,10 +1030,10 @@ static inline void setup_object_debug(struct kmem_cache *s,
1029 struct page *page, void *object) {} 1030 struct page *page, void *object) {}
1030 1031
1031static inline int alloc_debug_processing(struct kmem_cache *s, 1032static inline int alloc_debug_processing(struct kmem_cache *s,
1032 struct page *page, void *object, void *addr) { return 0; } 1033 struct page *page, void *object, unsigned long addr) { return 0; }
1033 1034
1034static inline int free_debug_processing(struct kmem_cache *s, 1035static inline int free_debug_processing(struct kmem_cache *s,
1035 struct page *page, void *object, void *addr) { return 0; } 1036 struct page *page, void *object, unsigned long addr) { return 0; }
1036 1037
1037static inline int slab_pad_check(struct kmem_cache *s, struct page *page) 1038static inline int slab_pad_check(struct kmem_cache *s, struct page *page)
1038 { return 1; } 1039 { return 1; }
@@ -1499,8 +1500,8 @@ static inline int node_match(struct kmem_cache_cpu *c, int node)
1499 * we need to allocate a new slab. This is the slowest path since it involves 1500 * we need to allocate a new slab. This is the slowest path since it involves
1500 * a call to the page allocator and the setup of a new slab. 1501 * a call to the page allocator and the setup of a new slab.
1501 */ 1502 */
1502static void *__slab_alloc(struct kmem_cache *s, 1503static void *__slab_alloc(struct kmem_cache *s, gfp_t gfpflags, int node,
1503 gfp_t gfpflags, int node, void *addr, struct kmem_cache_cpu *c) 1504 unsigned long addr, struct kmem_cache_cpu *c)
1504{ 1505{
1505 void **object; 1506 void **object;
1506 struct page *new; 1507 struct page *new;
@@ -1584,7 +1585,7 @@ debug:
1584 * Otherwise we can simply pick the next object from the lockless free list. 1585 * Otherwise we can simply pick the next object from the lockless free list.
1585 */ 1586 */
1586static __always_inline void *slab_alloc(struct kmem_cache *s, 1587static __always_inline void *slab_alloc(struct kmem_cache *s,
1587 gfp_t gfpflags, int node, void *addr) 1588 gfp_t gfpflags, int node, unsigned long addr)
1588{ 1589{
1589 void **object; 1590 void **object;
1590 struct kmem_cache_cpu *c; 1591 struct kmem_cache_cpu *c;
@@ -1613,18 +1614,46 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
1613 1614
1614void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) 1615void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
1615{ 1616{
1616 return slab_alloc(s, gfpflags, -1, __builtin_return_address(0)); 1617 void *ret = slab_alloc(s, gfpflags, -1, _RET_IP_);
1618
1619 kmemtrace_mark_alloc(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
1620 s->objsize, s->size, gfpflags);
1621
1622 return ret;
1617} 1623}
1618EXPORT_SYMBOL(kmem_cache_alloc); 1624EXPORT_SYMBOL(kmem_cache_alloc);
1619 1625
1626#ifdef CONFIG_KMEMTRACE
1627void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
1628{
1629 return slab_alloc(s, gfpflags, -1, _RET_IP_);
1630}
1631EXPORT_SYMBOL(kmem_cache_alloc_notrace);
1632#endif
1633
1620#ifdef CONFIG_NUMA 1634#ifdef CONFIG_NUMA
1621void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) 1635void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
1622{ 1636{
1623 return slab_alloc(s, gfpflags, node, __builtin_return_address(0)); 1637 void *ret = slab_alloc(s, gfpflags, node, _RET_IP_);
1638
1639 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret,
1640 s->objsize, s->size, gfpflags, node);
1641
1642 return ret;
1624} 1643}
1625EXPORT_SYMBOL(kmem_cache_alloc_node); 1644EXPORT_SYMBOL(kmem_cache_alloc_node);
1626#endif 1645#endif
1627 1646
1647#ifdef CONFIG_KMEMTRACE
1648void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
1649 gfp_t gfpflags,
1650 int node)
1651{
1652 return slab_alloc(s, gfpflags, node, _RET_IP_);
1653}
1654EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
1655#endif
1656
1628/* 1657/*
1629 * Slow patch handling. This may still be called frequently since objects 1658 * Slow patch handling. This may still be called frequently since objects
1630 * have a longer lifetime than the cpu slabs in most processing loads. 1659 * have a longer lifetime than the cpu slabs in most processing loads.
@@ -1634,7 +1663,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
1634 * handling required then we can return immediately. 1663 * handling required then we can return immediately.
1635 */ 1664 */
1636static void __slab_free(struct kmem_cache *s, struct page *page, 1665static void __slab_free(struct kmem_cache *s, struct page *page,
1637 void *x, void *addr, unsigned int offset) 1666 void *x, unsigned long addr, unsigned int offset)
1638{ 1667{
1639 void *prior; 1668 void *prior;
1640 void **object = (void *)x; 1669 void **object = (void *)x;
@@ -1704,7 +1733,7 @@ debug:
1704 * with all sorts of special processing. 1733 * with all sorts of special processing.
1705 */ 1734 */
1706static __always_inline void slab_free(struct kmem_cache *s, 1735static __always_inline void slab_free(struct kmem_cache *s,
1707 struct page *page, void *x, void *addr) 1736 struct page *page, void *x, unsigned long addr)
1708{ 1737{
1709 void **object = (void *)x; 1738 void **object = (void *)x;
1710 struct kmem_cache_cpu *c; 1739 struct kmem_cache_cpu *c;
@@ -1731,7 +1760,9 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
1731 1760
1732 page = virt_to_head_page(x); 1761 page = virt_to_head_page(x);
1733 1762
1734 slab_free(s, page, x, __builtin_return_address(0)); 1763 slab_free(s, page, x, _RET_IP_);
1764
1765 kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, x);
1735} 1766}
1736EXPORT_SYMBOL(kmem_cache_free); 1767EXPORT_SYMBOL(kmem_cache_free);
1737 1768
@@ -2650,6 +2681,7 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
2650void *__kmalloc(size_t size, gfp_t flags) 2681void *__kmalloc(size_t size, gfp_t flags)
2651{ 2682{
2652 struct kmem_cache *s; 2683 struct kmem_cache *s;
2684 void *ret;
2653 2685
2654 if (unlikely(size > PAGE_SIZE)) 2686 if (unlikely(size > PAGE_SIZE))
2655 return kmalloc_large(size, flags); 2687 return kmalloc_large(size, flags);
@@ -2659,7 +2691,12 @@ void *__kmalloc(size_t size, gfp_t flags)
2659 if (unlikely(ZERO_OR_NULL_PTR(s))) 2691 if (unlikely(ZERO_OR_NULL_PTR(s)))
2660 return s; 2692 return s;
2661 2693
2662 return slab_alloc(s, flags, -1, __builtin_return_address(0)); 2694 ret = slab_alloc(s, flags, -1, _RET_IP_);
2695
2696 kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, ret,
2697 size, s->size, flags);
2698
2699 return ret;
2663} 2700}
2664EXPORT_SYMBOL(__kmalloc); 2701EXPORT_SYMBOL(__kmalloc);
2665 2702
@@ -2678,16 +2715,30 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
2678void *__kmalloc_node(size_t size, gfp_t flags, int node) 2715void *__kmalloc_node(size_t size, gfp_t flags, int node)
2679{ 2716{
2680 struct kmem_cache *s; 2717 struct kmem_cache *s;
2718 void *ret;
2681 2719
2682 if (unlikely(size > PAGE_SIZE)) 2720 if (unlikely(size > PAGE_SIZE)) {
2683 return kmalloc_large_node(size, flags, node); 2721 ret = kmalloc_large_node(size, flags, node);
2722
2723 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC,
2724 _RET_IP_, ret,
2725 size, PAGE_SIZE << get_order(size),
2726 flags, node);
2727
2728 return ret;
2729 }
2684 2730
2685 s = get_slab(size, flags); 2731 s = get_slab(size, flags);
2686 2732
2687 if (unlikely(ZERO_OR_NULL_PTR(s))) 2733 if (unlikely(ZERO_OR_NULL_PTR(s)))
2688 return s; 2734 return s;
2689 2735
2690 return slab_alloc(s, flags, node, __builtin_return_address(0)); 2736 ret = slab_alloc(s, flags, node, _RET_IP_);
2737
2738 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, ret,
2739 size, s->size, flags, node);
2740
2741 return ret;
2691} 2742}
2692EXPORT_SYMBOL(__kmalloc_node); 2743EXPORT_SYMBOL(__kmalloc_node);
2693#endif 2744#endif
@@ -2744,7 +2795,9 @@ void kfree(const void *x)
2744 put_page(page); 2795 put_page(page);
2745 return; 2796 return;
2746 } 2797 }
2747 slab_free(page->slab, page, object, __builtin_return_address(0)); 2798 slab_free(page->slab, page, object, _RET_IP_);
2799
2800 kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, x);
2748} 2801}
2749EXPORT_SYMBOL(kfree); 2802EXPORT_SYMBOL(kfree);
2750 2803
@@ -3202,9 +3255,10 @@ static struct notifier_block __cpuinitdata slab_notifier = {
3202 3255
3203#endif 3256#endif
3204 3257
3205void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller) 3258void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, unsigned long caller)
3206{ 3259{
3207 struct kmem_cache *s; 3260 struct kmem_cache *s;
3261 void *ret;
3208 3262
3209 if (unlikely(size > PAGE_SIZE)) 3263 if (unlikely(size > PAGE_SIZE))
3210 return kmalloc_large(size, gfpflags); 3264 return kmalloc_large(size, gfpflags);
@@ -3214,13 +3268,20 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
3214 if (unlikely(ZERO_OR_NULL_PTR(s))) 3268 if (unlikely(ZERO_OR_NULL_PTR(s)))
3215 return s; 3269 return s;
3216 3270
3217 return slab_alloc(s, gfpflags, -1, caller); 3271 ret = slab_alloc(s, gfpflags, -1, caller);
3272
3273 /* Honor the call site pointer we recieved. */
3274 kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, caller, ret, size,
3275 s->size, gfpflags);
3276
3277 return ret;
3218} 3278}
3219 3279
3220void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, 3280void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
3221 int node, void *caller) 3281 int node, unsigned long caller)
3222{ 3282{
3223 struct kmem_cache *s; 3283 struct kmem_cache *s;
3284 void *ret;
3224 3285
3225 if (unlikely(size > PAGE_SIZE)) 3286 if (unlikely(size > PAGE_SIZE))
3226 return kmalloc_large_node(size, gfpflags, node); 3287 return kmalloc_large_node(size, gfpflags, node);
@@ -3230,7 +3291,13 @@ void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
3230 if (unlikely(ZERO_OR_NULL_PTR(s))) 3291 if (unlikely(ZERO_OR_NULL_PTR(s)))
3231 return s; 3292 return s;
3232 3293
3233 return slab_alloc(s, gfpflags, node, caller); 3294 ret = slab_alloc(s, gfpflags, node, caller);
3295
3296 /* Honor the call site pointer we recieved. */
3297 kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, caller, ret,
3298 size, s->size, gfpflags, node);
3299
3300 return ret;
3234} 3301}
3235 3302
3236#ifdef CONFIG_SLUB_DEBUG 3303#ifdef CONFIG_SLUB_DEBUG
@@ -3429,7 +3496,7 @@ static void resiliency_test(void) {};
3429 3496
3430struct location { 3497struct location {
3431 unsigned long count; 3498 unsigned long count;
3432 void *addr; 3499 unsigned long addr;
3433 long long sum_time; 3500 long long sum_time;
3434 long min_time; 3501 long min_time;
3435 long max_time; 3502 long max_time;
@@ -3477,7 +3544,7 @@ static int add_location(struct loc_track *t, struct kmem_cache *s,
3477{ 3544{
3478 long start, end, pos; 3545 long start, end, pos;
3479 struct location *l; 3546 struct location *l;
3480 void *caddr; 3547 unsigned long caddr;
3481 unsigned long age = jiffies - track->when; 3548 unsigned long age = jiffies - track->when;
3482 3549
3483 start = -1; 3550 start = -1;