Skip to contentSkip to conversation

kmemtrace: Core implementation.

RFC PATCH In review Eduard - Gabriel Munteanu 4 participants 30 messages Jul 10, 2008 – Jul 15, 2008 5 messages not in the archive

Subsystems (5)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

RFC PATCH 1/5 kmemtrace: Core implementation.

kmemtrace provides tracing for slab allocator functions, such as kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected data is then fed to the userspace application in order to analyse allocation hotspots, internal fragmentation and so on, making it possible to see how well an allocator performs, as well as debug and profile kernel code.

---
 MAINTAINERS               |    6 ++
 include/linux/kmemtrace.h |  110 +++++++++++++++++++++++
 init/main.c               |    2 +
 lib/Kconfig.debug         |    4 +
 mm/Makefile               |    2 +-
 mm/kmemtrace.c            |  213 +++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 336 insertions(+), 1 deletions(-)
 create mode 100644 include/linux/kmemtrace.h
 create mode 100644 mm/kmemtrace.c
MAINTAINERS +6 -0
index 6476125..87a743a 100644
@@ -2425,6 +2425,12 @@ M:	[email protected]
 L:	[email protected]
 S:	Maintained
 
+KMEMTRACE
+P:	Eduard - Gabriel Munteanu
+M:	[email protected]
+L:	[email protected]
+S:	Maintained
+
 KPROBES
 P:	Ananth N Mavinakayanahalli
 M:	[email protected]
include/linux/kmemtrace.h new file +110 -0

110 lines not on this page · raw message

init/main.c +2 -0
index 057f364..c00659c 100644
@@ -66,6 +66,7 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 #include <asm/cacheflush.h>
+#include <linux/kmemtrace.h>
 
 #ifdef CONFIG_X86_LOCAL_APIC
 #include <asm/smp.h>
@@ -641,6 +642,7 @@ asmlinkage void __init start_kernel(void)
 	enable_debug_pagealloc();
 	cpu_hotplug_init();
 	kmem_cache_init();
+	kmemtrace_init();
 	debug_objects_mem_init();
 	idr_init_cache();
 	setup_per_cpu_pageset();
lib/Kconfig.debug +4 -0
index d2099f4..6bacab5 100644
@@ -674,6 +674,10 @@ config FIREWIRE_OHCI_REMOTE_DMA
 
 	  If unsure, say N.
 
+config KMEMTRACE
+	bool "Kernel memory tracer"
+	depends on RELAY && DEBUG_FS && MARKERS
+
 source "samples/Kconfig"
 
 source "lib/Kconfig.kgdb"
mm/Makefile +1 -1
index 18c143b..d88a3bc 100644
@@ -33,4 +33,4 @@ obj-$(CONFIG_MIGRATION) += migrate.o
 obj-$(CONFIG_SMP) += allocpercpu.o
 obj-$(CONFIG_QUICKLIST) += quicklist.o
 obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o
-
+obj-$(CONFIG_KMEMTRACE) += kmemtrace.o
mm/kmemtrace.c new file +213 -0

213 lines not on this page · raw message

Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#2 lore raw

Hi Eduard-Gabriel,

Quoted 29 lines · Eduard - Gabriel Munteanu

kmemtrace provides tracing for slab allocator functions, such as kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected data is then fed to the userspace application in order to analyse allocation hotspots, internal fragmentation and so on, making it possible to see how well an allocator performs, as well as debug and profile kernel code.

new file mode 100644
index 0000000..11cd8e2

include/linux/kmemtrace.h new file +16 -0
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ *
+ * This file is released under GPL version 2.
+ */
+
+#ifndef _LINUX_KMEMTRACE_H
+#define _LINUX_KMEMTRACE_H
+
+#include <linux/types.h>
+
+/* ABI definition starts here. */
+
+#define KMEMTRACE_ABI_VERSION          1
+
+enum kmemtrace_event_id {

include/linux/kmemtrace.h line 26

Quoted 10 lines
include/linux/kmemtrace.h new file +10 -0
+       KMEMTRACE_EVENT_NULL = 0,       /* Erroneous event. */
+       KMEMTRACE_EVENT_ALLOC,
+       KMEMTRACE_EVENT_FREE,
+};
+
+enum kmemtrace_kind_id {
+       KMEMTRACE_KIND_KERNEL = 0,      /* kmalloc() / kfree(). */
+       KMEMTRACE_KIND_CACHE,           /* kmem_cache_*(). */
+       KMEMTRACE_KIND_PAGES,           /* __get_free_pages() and friends. */
+};

Can we do s/kind/type/, please? Also, the names "kernel" and "cache" are confusing. Can we just call them "kmalloc" and "kmem_cache" instead?

include/linux/kmemtrace.h line 38

Quoted 12 lines
include/linux/kmemtrace.h new file +12 -0
+
+struct kmemtrace_event {
+       __u16           event_id;       /* Allocate or free? */
+       __u16           kind_id;        /* Kind of allocation/free. */
+       __s32           node;           /* Target CPU. */
+       __u64           call_site;      /* Caller address. */
+       __u64           ptr;            /* Pointer to allocation. */
+       __u64           bytes_req;      /* Number of bytes requested. */
+       __u64           bytes_alloc;    /* Number of bytes allocated. */
+       __u64           gfp_flags;      /* Requested flags. */
+       __s64           timestamp;      /* When the operation occured in ns. */
+} __attribute__ ((__packed__));

Why do you need to use the __packed__ attribute here? Looks like the struct is already laid out properly.

include/linux/kmemtrace.h line 40

Quoted 2 lines
include/linux/kmemtrace.h new file +2 -0
+
+/* End of ABI definition. */

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
Quoted 41 lines · On Fri, 11 Jul 2008 11:41:20 +0300 "Pekka Enberg" <[email protected]>…

Hi Eduard-Gabriel,

Quoted 37 lines · Eduard - Gabriel Munteanu

kmemtrace provides tracing for slab allocator functions, such as kmalloc, kfree, kmem_cache_alloc, kmem_cache_free etc.. Collected data is then fed to the userspace application in order to analyse allocation hotspots, internal fragmentation and so on, making it possible to see how well an allocator performs, as well as debug and profile kernel code.

Signed-off-by: Eduard - Gabriel Munteanu
<[email protected]>

new file mode 100644
index 0000000..11cd8e2

include/linux/kmemtrace.h new file +22 -0
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 Eduard - Gabriel Munteanu
+ *
+ * This file is released under GPL version 2.
+ */
+
+#ifndef _LINUX_KMEMTRACE_H
+#define _LINUX_KMEMTRACE_H
+
+#include <linux/types.h>
+
+/* ABI definition starts here. */
+
+#define KMEMTRACE_ABI_VERSION          1
+
+enum kmemtrace_event_id {
+       KMEMTRACE_EVENT_NULL = 0,       /* Erroneous event. */
+       KMEMTRACE_EVENT_ALLOC,
+       KMEMTRACE_EVENT_FREE,
+};
+
+enum kmemtrace_kind_id {
Quoted 8 lines
Quoted 4 lines
include/linux/kmemtrace.h new file +3 -0
+       KMEMTRACE_KIND_KERNEL = 0,      /* kmalloc() / kfree(). */
+       KMEMTRACE_KIND_CACHE,           /* kmem_cache_*(). */
+       KMEMTRACE_KIND_PAGES,           /* __get_free_pages() and

friends. */ +};

Can we do s/kind/type/, please? Also, the names "kernel" and "cache" are confusing. Can we just call them "kmalloc" and "kmem_cache" instead?

Sure. I thought "type" would be too confusing.

Regarding the use of "kmalloc" and "kmem_cache", I'd have a few objections:
1. "kmalloc" is ambiguous and may mislead some people into thinking that such a type is inappropriate for kfree().
2. "kmem_cache" seemed way too long. The tracing function calls are already kinda long.

Quoted 10 lines
Quoted 10 lines
include/linux/kmemtrace.h new file +4 -0
+
+struct kmemtrace_event {
+       __u16           event_id;       /* Allocate or free? */
+       __u16           kind_id;        /* Kind of allocation/free.

*/

include/linux/kmemtrace.h new file +4 -0
+       __s32           node;           /* Target CPU. */
+       __u64           call_site;      /* Caller address. */
+       __u64           ptr;            /* Pointer to allocation. */
+       __u64           bytes_req;      /* Number of bytes

requested. */

Quoted 8 lines
Quoted 5 lines

+ __u64 bytes_alloc; /* Number of bytes
allocated. */

include/linux/kmemtrace.h new file +2 -0
+       __u64           gfp_flags;      /* Requested flags. */
+       __s64           timestamp;      /* When the operation

occured in ns. */ +} __attribute__ ((__packed__));

Why do you need to use the __packed__ attribute here? Looks like the struct is already laid out properly.

__packed__ doesn't hurt and will keep us from getting fried when doing cross-platform tracing (e.g. trace on ARM, analyze on x86) in case the ABI changes. It's also a reminder that it's best to keep the structure packed tight and avoid alignment.

Quoted 2 lines

include/linux/kmemtrace.h

Quoted 2 lines
include/linux/kmemtrace.h new file +2 -0
+
+/* End of ABI definition. */

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

A message that is not in the archive (sent off-list or not yet received): [email protected]

#5 lore raw

RFC PATCH 2/5 Add new GFP flag __GFP_NOTRACE.

__GFP_NOTRACE turns off allocator tracing for that particular allocation.

This is used by kmemtrace to correctly classify different kinds of allocations, without recording one event multiple times. Example: SLAB's kmalloc() calls kmem_cache_alloc(), but we want to record this only as a kmalloc.

---
 include/linux/gfp.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
include/linux/gfp.h +1 -0
index b414be3..693a5a9 100644
@@ -43,6 +43,7 @@ struct vm_area_struct;
 #define __GFP_REPEAT	((__force gfp_t)0x400u)	/* See above */
 #define __GFP_NOFAIL	((__force gfp_t)0x800u)	/* See above */
 #define __GFP_NORETRY	((__force gfp_t)0x1000u)/* See above */
+#define __GFP_NOTRACE	((__force gfp_t)0x2000u) /* Inhibit tracing this. */
 #define __GFP_COMP	((__force gfp_t)0x4000u)/* Add compound page metadata */
 #define __GFP_ZERO	((__force gfp_t)0x8000u)/* Return zeroed page on success */
 #define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#6 lore raw

Re: [RFC PATCH 2/5] Add new GFP flag __GFP_NOTRACE.

Hi Eduard-Gabriel,

Quoted 8 lines · Eduard - Gabriel Munteanu

__GFP_NOTRACE turns off allocator tracing for that particular allocation.

This is used by kmemtrace to correctly classify different kinds of allocations, without recording one event multiple times. Example: SLAB's kmalloc() calls kmem_cache_alloc(), but we want to record this only as a kmalloc.

I don't like this approach. I think you can just place the hooks in the proper place in SLAB to avoid this?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw

Re: [RFC PATCH 2/5] Add new GFP flag __GFP_NOTRACE.

In reply to Eduard - Gabriel Munteanu
Quoted 4 lines · Eduard - Gabriel Munteanu

This is used by kmemtrace to correctly classify different kinds of allocations, without recording one event multiple times. Example: SLAB's kmalloc() calls kmem_cache_alloc(), but we want to record this only as a kmalloc.

Well then I guess we need to put the recording logic into kmem_cache_alloc?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#8 lore raw

Re: [RFC PATCH 2/5] Add new GFP flag __GFP_NOTRACE.

Quoted 9 lines · On Fri, 11 Jul 2008 09:41:20 -0500 Christoph Lameter <[email protected]>…
Quoted 4 lines · Eduard - Gabriel Munteanu

This is used by kmemtrace to correctly classify different kinds of allocations, without recording one event multiple times. Example:
SLAB's kmalloc() calls kmem_cache_alloc(), but we want to record this only as a kmalloc.

Well then I guess we need to put the recording logic into kmem_cache_alloc?

Okay, will do it another way. I thought there may be other legitimate uses of something like __GFP_NOTRACE.

Eduard

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

A message that is not in the archive (sent off-list or not yet received): [email protected]

#10 lore raw

RFC PATCH 3/5 kmemtrace: SLAB hooks.

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

---
 include/linux/slab_def.h |   16 +++++++++++++---
 mm/slab.c                |   35 +++++++++++++++++++++++++++++------
 2 files changed, 42 insertions(+), 9 deletions(-)
include/linux/slab_def.h +13 -3
index 39c3a5e..89d0cca 100644
@@ -14,6 +14,7 @@
 #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>
+#include <linux/kmemtrace.h>
 
 /* Size description struct for general caches. */
 struct cache_sizes {
@@ -30,6 +31,8 @@ void *__kmalloc(size_t size, gfp_t flags);
 
 static inline void *kmalloc(size_t size, gfp_t flags)
 {
+	void *ret;
+	
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -50,10 +53,17 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
-						flags);
+			ret = kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
+					       flags | __GFP_NOTRACE);
+		else
 #endif
-		return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
+			ret = kmem_cache_alloc(malloc_sizes[i].cs_cachep,
+					       flags | __GFP_NOTRACE);
+
+		kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+				     size, malloc_sizes[i].cs_size, flags);
+
+		return ret;
 	}
 	return __kmalloc(size, flags);
 }
mm/slab.c +29 -6
index 046607f..29f0599 100644
@@ -111,6 +111,7 @@
 #include	<linux/rtmutex.h>
 #include	<linux/reciprocal_div.h>
 #include	<linux/debugobjects.h>
+#include	<linux/kmemtrace.h>
 
 #include	<asm/cacheflush.h>
 #include	<asm/tlbflush.h>
@@ -3621,7 +3622,12 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
  */
 void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
-	return __cache_alloc(cachep, flags, __builtin_return_address(0));
+	void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
+
+	kmemtrace_mark_alloc(KMEMTRACE_KIND_CACHE, _RET_IP_, ret,
+			     obj_size(cachep), obj_size(cachep), flags);
+
+	return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
@@ -3669,8 +3675,14 @@ out:
 #ifdef CONFIG_NUMA
 void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
 {
-	return __cache_alloc_node(cachep, flags, nodeid,
-			__builtin_return_address(0));
+	void *ret = __cache_alloc_node(cachep, flags, nodeid,
+				       __builtin_return_address(0));
+	
+	kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE, _RET_IP_, ret,
+				  obj_size(cachep), obj_size(cachep),
+				  flags, nodeid);
+
+	return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 
@@ -3718,6 +3730,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
 					  void *caller)
 {
 	struct kmem_cache *cachep;
+	void *ret;
 
 	/* If you want to save a few bytes .text space: replace
 	 * __ with kmem_.
@@ -3726,12 +3739,18 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags,
 	 */
 	cachep = __find_general_cachep(size, flags);
 	if (unlikely(ZERO_OR_NULL_PTR(cachep)))
-		return cachep;
-	return __cache_alloc(cachep, flags, caller);
+		ret = cachep;
+	else {
+		ret = __cache_alloc(cachep, flags, caller);
+		kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, caller, ret,
+				     size, cachep->buffer_size, flags);
+	}
+
+	return ret;
 }
 
 
-#ifdef CONFIG_DEBUG_SLAB
+#if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE)
 void *__kmalloc(size_t size, gfp_t flags)
 {
 	return __do_kmalloc(size, flags, __builtin_return_address(0));
@@ -3770,6 +3789,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp)
 		debug_check_no_obj_freed(objp, obj_size(cachep));
 	__cache_free(cachep, objp);
 	local_irq_restore(flags);
+
+	kmemtrace_mark_free(KMEMTRACE_KIND_CACHE, _RET_IP_, objp);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
@@ -3796,6 +3817,8 @@ void kfree(const void *objp)
 	debug_check_no_obj_freed(objp, obj_size(c));
 	__cache_free(c, (void *)objp);
 	local_irq_restore(flags);
+
+	kmemtrace_mark_free(KMEMTRACE_KIND_KERNEL, _RET_IP_, objp);
 }
 EXPORT_SYMBOL(kfree);
 
Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#11 lore raw

Re: [RFC PATCH 3/5] kmemtrace: SLAB hooks.

Hi Eduard-Gabriel,

Quoted 18 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

static inline void *kmalloc(size_t size, gfp_t flags) {

include/linux/slab_def.h +4 -2
+       void *ret;
+
       if (__builtin_constant_p(size)) {
               int i = 0;
@@ -50,10 +53,17 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 found:
 #ifdef CONFIG_ZONE_DMA
               if (flags & GFP_DMA)
-                       return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
-                                               flags);
+                       ret = kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
+                                              flags | __GFP_NOTRACE);

include/linux/slab_def.h static inline void *kmalloc(size_t size, gfp_t flags) · line 66

Quoted 10 lines
include/linux/slab_def.h +8 -1
+               else
 #endif
-               return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
+                       ret = kmem_cache_alloc(malloc_sizes[i].cs_cachep,
+                                              flags | __GFP_NOTRACE);
+
+               kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+                                    size, malloc_sizes[i].cs_size, flags);
+
+               return ret;

I think this would be cleaner if you'd simply add a new __kmem_cache_alloc() entry point in SLAB that takes the "kind" as an argument. That way you wouldn't have to play tricks with GFP flags.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#12 lore raw

PATCH 1/1 kmemtrace: SLAB hooks.

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

---

Dropped the __GFP_NOTRACE thing. Also fixed NUMA tracing and some whitespace errors.

What do you think?

 include/linux/slab_def.h |   56 +++++++++++++++++++++++++++++++++++++-----
 mm/slab.c                |   61 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 104 insertions(+), 13 deletions(-)
include/linux/slab_def.h +49 -7
index 39c3a5e..040fe72 100644
@@ -14,6 +14,7 @@
 #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>
+#include <linux/kmemtrace.h>
 
 /* Size description struct for general caches. */
 struct cache_sizes {
@@ -28,8 +29,20 @@ extern struct cache_sizes malloc_sizes[];
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
+#else
+static inline void *__kmem_cache_alloc(struct kmem_cache *cachep,
+				       gfp_t flags)
+{
+	return __kmem_cache_alloc(cachep, flags);
+}
+#endif
+
 static inline void *kmalloc(size_t size, gfp_t flags)
 {
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -50,10 +63,17 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
-						flags);
+			ret = __kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
+						 flags);
+		else
 #endif
-		return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
+			ret = __kmem_cache_alloc(malloc_sizes[i].cs_cachep,
+						 flags);
+
+		kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+				     size, malloc_sizes[i].cs_size, flags);
+
+		return ret;
 	}
 	return __kmalloc(size, flags);
 }
@@ -62,8 +82,23 @@ found:
 extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
 extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc_node(struct kmem_cache *cachep,
+				     gfp_t flags,
+				     int nodeid);
+#else
+static inline void *__kmem_cache_alloc_node(struct kmem_cache *cachep,
+					    gfp_t flags,
+					    int nodeid)
+{
+	return kmem_cache_alloc_node(cachep, flags, nodeid);
+}
+#endif
+
 static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -84,11 +119,18 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep,
-						flags, node);
+			ret = __kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep,
+						      flags, node);
+		else
 #endif
-		return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep,
-						flags, node);
+			ret =  __kmem_cache_alloc_node(malloc_sizes[i].cs_cachep,
+						       flags, node);
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL, _THIS_IP_,
+					  ret, size, malloc_sizes[i].cs_size,
+					  flags, node);
+
+		return ret;
 	}
 	return __kmalloc_node(size, flags, node);
 }
mm/slab.c +55 -6

120 lines not on this page · raw message

Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#13 lore raw

Re: [PATCH] kmemtrace: SLAB hooks.

Hi Eduard-Gabriel,

Quoted 4 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

include/linux/slab_def.h extern struct cache_sizes malloc_sizes[]; · line 38

Quoted 10 lines
include/linux/slab_def.h +7 -0
@@ -28,8 +29,20 @@ extern struct cache_sizes malloc_sizes[];
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
+#else
+static inline void *__kmem_cache_alloc(struct kmem_cache *cachep,
+				       gfp_t flags)
+{
+	return __kmem_cache_alloc(cachep, flags);

Looks as if the function calls itself i>>?recursively?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#14 lore raw

Re: [PATCH] kmemtrace: SLAB hooks.

Quoted 10 lines · Pekka Enberg

Hi Eduard-Gabriel,

Quoted 7 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

include/linux/slab_def.h +0 -0
@@ -28,8 +29,20 @@ extern struct cache_sizes malloc_sizes[];
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
Quoted 10 lines

include/linux/slab_def.h extern struct cache_sizes malloc_sizes[]; · line 38

Quoted 7 lines
include/linux/slab_def.h +7 -0
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
+#else
+static inline void *__kmem_cache_alloc(struct kmem_cache *cachep,
+				       gfp_t flags)
+{
+	return __kmem_cache_alloc(cachep, flags);

Looks as if the function calls itself i>>?recursively?

Code not tested? Are you sure you configured for slab?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#15 lore raw

Re: [PATCH] kmemtrace: SLAB hooks.

Quoted 4 lines · On Mon, 14 Jul 2008 11:32:25 -0500 Christoph Lameter <[email protected]>…
Quoted 2 lines

Looks as if the function calls itself i>>?recursively?

Code not tested? Are you sure you configured for slab?

This was a stupid typo on my part. I tested, but only with CONFIG_KMEMTRACE, which took the 'extern' ifdef branch. I'll resubmit in a few minutes.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#16 lore raw

PATCH RESEND 1/1 kmemtrace: SLAB hooks.

In reply to Christoph Lameter

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

---

Okay, the rationale is this:
1. When CONFIG_KMEMTRACE is set, __kmem_cache_alloc is defined in mm/slab.c, where it does not call tracers.
2. When CONFIG_KMEMTRACE is _not_ set, __kmem_cache_alloc goes through the usual kmem_cache_alloc, which contains tracers, but are no-ops because CONFIG_KMEMTRACE is not set.

Therefore, in any case, __kmem_cache_alloc does not do tracing.

Hope this makes sense.

 include/linux/slab_def.h |   56 +++++++++++++++++++++++++++++++++++++-----
 mm/slab.c                |   61 +++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 104 insertions(+), 13 deletions(-)
include/linux/slab_def.h +49 -7
index 39c3a5e..758803f 100644
@@ -14,6 +14,7 @@
 #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>
+#include <linux/kmemtrace.h>
 
 /* Size description struct for general caches. */
 struct cache_sizes {
@@ -28,8 +29,20 @@ extern struct cache_sizes malloc_sizes[];
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
+#else
+static inline void *__kmem_cache_alloc(struct kmem_cache *cachep,
+				       gfp_t flags)
+{
+	return kmem_cache_alloc(cachep, flags);
+}
+#endif
+
 static inline void *kmalloc(size_t size, gfp_t flags)
 {
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -50,10 +63,17 @@ static inline void *kmalloc(size_t size, gfp_t flags)
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
-						flags);
+			ret = __kmem_cache_alloc(malloc_sizes[i].cs_dmacachep,
+						 flags);
+		else
 #endif
-		return kmem_cache_alloc(malloc_sizes[i].cs_cachep, flags);
+			ret = __kmem_cache_alloc(malloc_sizes[i].cs_cachep,
+						 flags);
+
+		kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+				     size, malloc_sizes[i].cs_size, flags);
+
+		return ret;
 	}
 	return __kmalloc(size, flags);
 }
@@ -62,8 +82,23 @@ found:
 extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
 extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc_node(struct kmem_cache *cachep,
+				     gfp_t flags,
+				     int nodeid);
+#else
+static inline void *__kmem_cache_alloc_node(struct kmem_cache *cachep,
+					    gfp_t flags,
+					    int nodeid)
+{
+	return kmem_cache_alloc_node(cachep, flags, nodeid);
+}
+#endif
+
 static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 {
+	void *ret;
+
 	if (__builtin_constant_p(size)) {
 		int i = 0;
 
@@ -84,11 +119,18 @@ static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 found:
 #ifdef CONFIG_ZONE_DMA
 		if (flags & GFP_DMA)
-			return kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep,
-						flags, node);
+			ret = __kmem_cache_alloc_node(malloc_sizes[i].cs_dmacachep,
+						      flags, node);
+		else
 #endif
-		return kmem_cache_alloc_node(malloc_sizes[i].cs_cachep,
-						flags, node);
+			ret =  __kmem_cache_alloc_node(malloc_sizes[i].cs_cachep,
+						       flags, node);
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL, _THIS_IP_,
+					  ret, size, malloc_sizes[i].cs_size,
+					  flags, node);
+
+		return ret;
 	}
 	return __kmalloc_node(size, flags, node);
 }
mm/slab.c +55 -6

120 lines not on this page · raw message

Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#17 lore raw

Re: [RESEND PATCH] kmemtrace: SLAB hooks.

Hi Eduard-Gabriel,

Quoted 8 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

include/linux/slab_def.h +0 -0
@@ -28,8 +29,20 @@ extern struct cache_sizes malloc_sizes[];
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 

include/linux/slab_def.h extern struct cache_sizes malloc_sizes[]; · line 41

Quoted 10 lines
include/linux/slab_def.h +10 -0
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
+#else
+static inline void *__kmem_cache_alloc(struct kmem_cache *cachep,
+				       gfp_t flags)
+{
+	return kmem_cache_alloc(cachep, flags);
+}
+#endif
+

I'm okay with this approach but then you need to do s/__kmem_cache_alloc/kmem_cache_alloc_trace/ or similar. In the kernel, it's always the *upper* level function that doesn't have the underscores.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#18 lore raw

Re: [RESEND PATCH] kmemtrace: SLAB hooks.

Quoted 11 lines · Pekka Enberg

Hi Eduard-Gabriel,

Quoted 8 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLAB allocator, to allow tracing with kmemtrace.

include/linux/slab_def.h +0 -0
@@ -28,8 +29,20 @@ extern struct cache_sizes malloc_sizes[];
 void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 void *__kmalloc(size_t size, gfp_t flags);
 
Quoted 15 lines

include/linux/slab_def.h extern struct cache_sizes malloc_sizes[]; · line 41

Quoted 10 lines
include/linux/slab_def.h +10 -0
+#ifdef CONFIG_KMEMTRACE
+extern void *__kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags);
+#else
+static inline void *__kmem_cache_alloc(struct kmem_cache *cachep,
+				       gfp_t flags)
+{
+	return kmem_cache_alloc(cachep, flags);
+}
+#endif
+

I'm okay with this approach but then you need to do s/__kmem_cache_alloc/kmem_cache_alloc_trace/ or similar. In the kernel, it's always the *upper* level function that doesn't have the underscores.

Hmm, doesn't really make sense:
1. This should be called kmem_cache_alloc_notrace, not *_trace. __kmem_cache_alloc() _disables_ tracing.
2. __kmem_cache_alloc is not really upper level now, since it's called only in kmalloc. So it's an internal function which is not supposed to be used by other kernel code.

Are you sure I should do this?

Eduard

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#19 lore raw

Re: [RESEND PATCH] kmemtrace: SLAB hooks.

Quoted 8 lines · On Mon, 2008-07-14 at 21:37 +0300, [email protected] wrote:
Quoted 4 lines

I'm okay with this approach but then you need to do s/__kmem_cache_alloc/kmem_cache_alloc_trace/ or similar. In the kernel, it's always the *upper* level function that doesn't have the underscores.

Hmm, doesn't really make sense:
1. This should be called kmem_cache_alloc_notrace, not *_trace. __kmem_cache_alloc() _disables_ tracing.

kmem_cache_alloc_notrace() sounds good to me.

Quoted 5 lines

2. __kmem_cache_alloc is not really upper level now, since it's called only in kmalloc. So it's an internal function which is not supposed to be used by other kernel code.

Are you sure I should do this?

Yes.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

A message that is not in the archive (sent off-list or not yet received): [email protected]

#21 lore raw

RFC PATCH 4/5 kmemtrace: SLUB hooks.

This adds hooks for the SLUB allocator, to allow tracing with kmemtrace.

---
 include/linux/slub_def.h |    9 +++++++-
 mm/slub.c                |   49 +++++++++++++++++++++++++++++++++++++++------
 2 files changed, 50 insertions(+), 8 deletions(-)
include/linux/slub_def.h +8 -1
index d117ea2..d60ab10 100644
@@ -10,6 +10,7 @@
 #include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
+#include <linux/kmemtrace.h>
 
 enum stat_item {
 	ALLOC_FASTPATH,		/* Allocation from cpu slab */
@@ -205,7 +206,13 @@ void *__kmalloc(size_t size, gfp_t flags);
 
 static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 {
-	return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size));
+	unsigned int order = get_order(size);
+	void *ret = (void *) __get_free_pages(flags, order);
+
+	kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+			     size, PAGE_SIZE << order, flags);
+
+	return ret;
 }
 
 static __always_inline void *kmalloc(size_t size, gfp_t flags)
mm/slub.c +42 -7

103 lines not on this page · raw message

Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Reviewed-by on v1 4/5
#22 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

Hi,

Christoph, can you please take a look at this?

Quoted 3 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLUB allocator, to allow tracing with kmemtrace.

Quoted 149 lines
---
 include/linux/slub_def.h |    9 +++++++-
 mm/slub.c                |   49 +++++++++++++++++++++++++++++++++++++++------
 2 files changed, 50 insertions(+), 8 deletions(-)
include/linux/slub_def.h +8 -1
index d117ea2..d60ab10 100644
@@ -10,6 +10,7 @@
 #include <linux/gfp.h>
 #include <linux/workqueue.h>
 #include <linux/kobject.h>
+#include <linux/kmemtrace.h>
 
 enum stat_item {
       ALLOC_FASTPATH,         /* Allocation from cpu slab */
@@ -205,7 +206,13 @@ void *__kmalloc(size_t size, gfp_t flags);
 
 static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 {
-       return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size));
+       unsigned int order = get_order(size);
+       void *ret = (void *) __get_free_pages(flags, order);
+
+       kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+                            size, PAGE_SIZE << order, flags);
+
+       return ret;
 }
 
 static __always_inline void *kmalloc(size_t size, gfp_t flags)
mm/slub.c +42 -8
index 1a427c0..6841dfa 100644
@@ -23,6 +23,7 @@
 #include <linux/kallsyms.h>
 #include <linux/memory.h>
 #include <linux/math64.h>
+#include <linux/kmemtrace.h>
 
 /*
 * Lock order:
@@ -1650,14 +1651,25 @@ static __always_inline void *slab_alloc(struct kmem_cache *s,
 
 void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags)
 {
-       return slab_alloc(s, gfpflags, -1, __builtin_return_address(0));
+       void *ret = slab_alloc(s, gfpflags, -1, __builtin_return_address(0));
+
+       kmemtrace_mark_alloc(KMEMTRACE_KIND_CACHE, _RET_IP_, ret,
+                            s->objsize, s->size, gfpflags);
+
+       return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc);
 
 #ifdef CONFIG_NUMA
 void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node)
 {
-       return slab_alloc(s, gfpflags, node, __builtin_return_address(0));
+       void *ret = slab_alloc(s, gfpflags, node,
+                              __builtin_return_address(0));
+
+       kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE, _RET_IP_, ret,
+                                 s->objsize, s->size, gfpflags, node);
+
+       return ret;
 }
 EXPORT_SYMBOL(kmem_cache_alloc_node);
 #endif
@@ -1769,6 +1781,8 @@ void kmem_cache_free(struct kmem_cache *s, void *x)
       page = virt_to_head_page(x);
 
       slab_free(s, page, x, __builtin_return_address(0));
+
+       kmemtrace_mark_free(KMEMTRACE_KIND_CACHE, _RET_IP_, x);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
@@ -2674,6 +2688,7 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
 void *__kmalloc(size_t size, gfp_t flags)
 {
       struct kmem_cache *s;
+       void *ret;
 
       if (unlikely(size > PAGE_SIZE))
               return kmalloc_large(size, flags);
@@ -2683,7 +2698,12 @@ void *__kmalloc(size_t size, gfp_t flags)
       if (unlikely(ZERO_OR_NULL_PTR(s)))
               return s;
 
-       return slab_alloc(s, flags, -1, __builtin_return_address(0));
+       ret = slab_alloc(s, flags, -1, __builtin_return_address(0));
+
+       kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _RET_IP_, ret,
+                            size, (size_t) s->size, (unsigned long) flags);
+
+       return ret;
 }
 EXPORT_SYMBOL(__kmalloc);
 
@@ -2702,16 +2722,29 @@ static void *kmalloc_large_node(size_t size, gfp_t flags, int node)
 void *__kmalloc_node(size_t size, gfp_t flags, int node)
 {
       struct kmem_cache *s;
-
-       if (unlikely(size > PAGE_SIZE))
-               return kmalloc_large_node(size, flags, node);
+       void *ret;
+
+       if (unlikely(size > PAGE_SIZE)) {
+               ret = kmalloc_large_node(size, flags, node);
+
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL, _RET_IP_, ret,
+                                         size, PAGE_SIZE << get_order(size),
+                                         (unsigned long) flags, node);
+
+               return ret;
+       }
 
       s = get_slab(size, flags);
 
       if (unlikely(ZERO_OR_NULL_PTR(s)))
               return s;
 
-       return slab_alloc(s, flags, node, __builtin_return_address(0));
+       ret = slab_alloc(s, flags, node, __builtin_return_address(0));
+
+       kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL, _RET_IP_, ret,
+                                 size, s->size, (unsigned long) flags, node);
+
+       return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 #endif
@@ -2769,6 +2802,8 @@ void kfree(const void *x)
               return;
       }
       slab_free(page->slab, page, object, __builtin_return_address(0));
+
+       kmemtrace_mark_free(KMEMTRACE_KIND_KERNEL, _RET_IP_, x);
 }
 EXPORT_SYMBOL(kfree);
 
--

1.5.6.1

Quoted 6 lines

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#24 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

Quoted 6 lines · On Fri, 11 Jul 2008 09:48:03 -0500 Christoph Lameter <[email protected]>…
Quoted 1 line · Pekka Enberg

Christoph, can you please take a look at this?

Yeah. I saw it. Is there some high level description as to how this is going to be used?

I'll soon post a link to a repo that holds the userspace tool.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#25 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

In reply to Christoph Lameter
Quoted 6 lines · On Fri, 11 Jul 2008 09:48:03 -0500 Christoph Lameter <[email protected]>…
Quoted 1 line · Pekka Enberg

Christoph, can you please take a look at this?

Yeah. I saw it. Is there some high level description as to how this is going to be used?

Here is the userspace application's git tree:
http://repo.or.cz/w/kmemtrace-user.git

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#26 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

Quoted 5 lines · On Sat, 12 Jul 2008 16:28:36 +0300 Eduard - Gabriel Munteanu…
Quoted 2 lines · On Fri, 11 Jul 2008 09:48:03 -0500 Christoph Lameter <[email protected]>…

Pekka Enberg wrote:

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

Christoph, can you please take a look at this?

Yeah. I saw it. Is there some high level description as to how this is going to be used?

Here is the userspace application's git tree:
http://repo.or.cz/w/kmemtrace-user.git

Basically, you go like this:
1. Boot the kernel, preferably into 'single' runlevel.
2. Mount debugfs and whatever other filesystems.
3. Run kmemtraced, wait a few seconds and stop it.
4*. Check /debug/kmemtrace/total_overruns (debugfs is mounted on /debug) to see if there were any buffer overruns.
5*. Run kmemtrace-check on all CPU cpu*.out to see if there are any erroneous events.
6. Run kmemtrace-report with no parameters to get a short summary of how the allocator performs.

* - you can optionally skip these steps.

To build the userspace app, launch './configure' when running on that particular kmemtrace-enabled kernel. It should correctly detect the headers directory. Otherwise, add KERNEL_SOURCES variable as an argument to configure. Then run 'make'.

BTW, that repo may change, so don't rely on those commits to be consistent for a long time. I could delete them all and restructure the project.

Eduard

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#27 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

In reply to Eduard - Gabriel Munteanu

Hi Eduard-Gabriel,

Quoted 5 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLUB allocator, to allow tracing with kmemtrace.

include/linux/slub_def.h void *__kmalloc(size_t size, gfp_t flags); · line 213

Quoted 9 lines
include/linux/slub_def.h +5 -1
@@ -205,7 +206,13 @@ void *__kmalloc(size_t size, gfp_t flags);
 
 static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 {
-       return (void *)__get_free_pages(flags | __GFP_COMP, get_order(size));
+       unsigned int order = get_order(size);
+       void *ret = (void *) __get_free_pages(flags, order);
+
+       kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+                            size, PAGE_SIZE << order, flags);

Oh, I missed this on the first review. Here we have, like in SLOB, page allocator pass-through, so wouldn't KIND_PAGES be more appropriate?

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#28 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

Quoted 12 lines · On Fri, 11 Jul 2008 11:45:59 +0300 "Pekka Enberg" <[email protected]>…

Hi Eduard-Gabriel,

Quoted 8 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLUB allocator, to allow tracing with kmemtrace.

Signed-off-by: Eduard - Gabriel Munteanu
<[email protected]>

(quoted diff) +0 -0
@@ -205,7 +206,13 @@ void *__kmalloc(size_t size, gfp_t flags);
 
Quoted 13 lines

include/linux/slub_def.h void *__kmalloc(size_t size, gfp_t flags); · line 213

Quoted 9 lines
include/linux/slub_def.h +5 -1
 static __always_inline void *kmalloc_large(size_t size, gfp_t
 flags) {
-       return (void *)__get_free_pages(flags | __GFP_COMP,
 get_order(size));
+       unsigned int order = get_order(size);
+       void *ret = (void *) __get_free_pages(flags, order);
+
+       kmemtrace_mark_alloc(KMEMTRACE_KIND_KERNEL, _THIS_IP_, ret,
+                            size, PAGE_SIZE << order, flags);

Oh, I missed this on the first review. Here we have, like in SLOB, page allocator pass-through, so wouldn't KIND_PAGES be more appropriate?

The rationale was to be able to trace how kmalloc()s perform, no matter what the allocator does behind the scenes. Presumably, the developer would know what kmalloc() really does with an allocation request.

Does this sound okay?

Eduard

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#29 lore raw

Re: [RFC PATCH 4/5] kmemtrace: SLUB hooks.

Hi Eduard-Gabriel,

On Fri, 11 Jul 2008 11:45:59 +0300

Quoted 3 lines
Quoted 3 lines

Oh, I missed this on the first review. Here we have, like in SLOB, page allocator pass-through, so wouldn't KIND_PAGES be more appropriate?

Quoted 5 lines · Eduard - Gabriel Munteanu

The rationale was to be able to trace how kmalloc()s perform, no matter what the allocator does behind the scenes. Presumably, the developer would know what kmalloc() really does with an allocation request.

Does this sound okay?

Fine with me.

Pekka

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

A message that is not in the archive (sent off-list or not yet received): [email protected]

#31 lore raw

RFC PATCH 5/5 kmemtrace: SLOB hooks.

This adds hooks for the SLOB allocator, to allow tracing with kmemtrace.

---
 mm/slob.c |   37 +++++++++++++++++++++++++++++++------
 1 files changed, 31 insertions(+), 6 deletions(-)
mm/slob.c +31 -6
index a3ad667..44f395a 100644
@@ -65,6 +65,7 @@
 #include <linux/module.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/kmemtrace.h>
 #include <asm/atomic.h>
 
 /*
@@ -463,27 +464,38 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
 {
 	unsigned int *m;
 	int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+	void *ret;
 
 	if (size < PAGE_SIZE - align) {
 		if (!size)
 			return ZERO_SIZE_PTR;
 
 		m = slob_alloc(size + align, gfp, align, node);
+		
 		if (!m)
 			return NULL;
 		*m = size;
-		return (void *)m + align;
+		ret = (void *)m + align;
+
+		kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL,
+					  _RET_IP_, ret,
+					  size, size + align, gfp, node);
 	} else {
-		void *ret;
+		unsigned int order = get_order(size);
 
-		ret = slob_new_page(gfp | __GFP_COMP, get_order(size), node);
+		ret = slob_new_page(gfp | __GFP_COMP, order, node);
 		if (ret) {
 			struct page *page;
 			page = virt_to_page(ret);
 			page->private = size;
 		}
-		return ret;
+		
+		kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL,
+					  _RET_IP_, ret,
+					  size, PAGE_SIZE << order, gfp, node);
 	}
+
+	return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 
@@ -501,6 +513,8 @@ void kfree(const void *block)
 		slob_free(m, *m + align);
 	} else
 		put_page(&sp->page);
+
+	kmemtrace_mark_free(KMEMTRACE_KIND_KERNEL, _RET_IP_, block);
 }
 EXPORT_SYMBOL(kfree);
 
@@ -569,10 +583,19 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
 {
 	void *b;
 
-	if (c->size < PAGE_SIZE)
+	if (c->size < PAGE_SIZE) {
 		b = slob_alloc(c->size, flags, c->align, node);
-	else
+		kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE,
+					  _RET_IP_, b, c->size,
+					  SLOB_UNITS(c->size) * SLOB_UNIT,
+					  flags, node);
+	} else {
 		b = slob_new_page(flags, get_order(c->size), node);
+		kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE,
+					  _RET_IP_, b, c->size, 
+					  PAGE_SIZE << get_order(c->size),
+					  flags, node);
+	}
 
 	if (c->ctor)
 		c->ctor(c, b);
@@ -608,6 +631,8 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
 	} else {
 		__kmem_cache_free(b, c->size);
 	}
+
+	kmemtrace_mark_free(KMEMTRACE_KIND_CACHE, _RET_IP_, b);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
Signature · 7 lines
1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#32 lore raw

Re: [RFC PATCH 5/5] kmemtrace: SLOB hooks.

Hi,

Matt, can you take a look at this? I know you don't want *debugging* code in SLOB but this is for instrumentation.

Quoted 44 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLOB allocator, to allow tracing with kmemtrace.

---
 mm/slob.c |   37 +++++++++++++++++++++++++++++++------
 1 files changed, 31 insertions(+), 6 deletions(-)
mm/slob.c +9 -2
index a3ad667..44f395a 100644
@@ -65,6 +65,7 @@
 #include <linux/module.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/kmemtrace.h>
 #include <asm/atomic.h>
 
 /*
@@ -463,27 +464,38 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
 {
       unsigned int *m;
       int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+       void *ret;
 
       if (size < PAGE_SIZE - align) {
               if (!size)
                       return ZERO_SIZE_PTR;
 
               m = slob_alloc(size + align, gfp, align, node);
+
               if (!m)
                       return NULL;
               *m = size;
-               return (void *)m + align;
+               ret = (void *)m + align;
+
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL,
+                                         _RET_IP_, ret,
+                                         size, size + align, gfp, node);
       } else {
-               void *ret;
+               unsigned int order = get_order(size);
 

mm/slob.c void *__kmalloc_node(size_t size, gfp_t gfp, int node) · line 493

Quoted 10 lines
mm/slob.c +3 -2
-               ret = slob_new_page(gfp | __GFP_COMP, get_order(size), node);
+               ret = slob_new_page(gfp | __GFP_COMP, order, node);
               if (ret) {
                       struct page *page;
                       page = virt_to_page(ret);
                       page->private = size;
               }
-               return ret;
+
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL,

The latter case is actually page allocator pass-through so I wonder if we want to use KIND_PAGES here instead?

Quoted 9 lines
mm/slob.c +4 -0
+                                         _RET_IP_, ret,
+                                         size, PAGE_SIZE << order, gfp, node);
       }
+
+       return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 

mm/slob.c void kfree(const void *block) · line 517

Quoted 5 lines
mm/slob.c +2 -0
@@ -501,6 +513,8 @@ void kfree(const void *block)
               slob_free(m, *m + align);
       } else
               put_page(&sp->page);
+
+       kmemtrace_mark_free(KMEMTRACE_KIND_KERNEL, _RET_IP_, block);

Same comment here.

Quoted 37 lines
mm/slob.c +13 -3
 }
 EXPORT_SYMBOL(kfree);
 
@@ -569,10 +583,19 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
 {
       void *b;
 
-       if (c->size < PAGE_SIZE)
+       if (c->size < PAGE_SIZE) {
               b = slob_alloc(c->size, flags, c->align, node);
-       else
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE,
+                                         _RET_IP_, b, c->size,
+                                         SLOB_UNITS(c->size) * SLOB_UNIT,
+                                         flags, node);
+       } else {
               b = slob_new_page(flags, get_order(c->size), node);
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE,
+                                         _RET_IP_, b, c->size,
+                                         PAGE_SIZE << get_order(c->size),
+                                         flags, node);
+       }
 
       if (c->ctor)
               c->ctor(c, b);
@@ -608,6 +631,8 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
       } else {
               __kmem_cache_free(b, c->size);
       }
+
+       kmemtrace_mark_free(KMEMTRACE_KIND_CACHE, _RET_IP_, b);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
--

1.5.6.1

Quoted 6 lines

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#33 lore raw

Re: [RFC PATCH 5/5] kmemtrace: SLOB hooks.

Quoted 4 lines · Pekka Enberg

Hi,

Matt, can you take a look at this? I know you don't want *debugging* code in SLOB but this is for instrumentation.

I presume this code all disappears in a default SLOB build?

Quoted 20 lines
Quoted 18 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLOB allocator, to allow tracing with kmemtrace.

---
 mm/slob.c |   37 +++++++++++++++++++++++++++++++------
 1 files changed, 31 insertions(+), 6 deletions(-)
mm/slob.c +1 -0
index a3ad667..44f395a 100644
@@ -65,6 +65,7 @@
 #include <linux/module.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/kmemtrace.h>
 #include <asm/atomic.h>
 
Quoted 6 lines

mm/slob.c void *__kmalloc_node(size_t size, gfp_t gfp, int node) · line 467

Quoted 6 lines
mm/slob.c +1 -0
 /*
@@ -463,27 +464,38 @@ void *__kmalloc_node(size_t size, gfp_t gfp, int node)
 {
       unsigned int *m;
       int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+       void *ret;

There's tons of tab damage in this patch. Or perhaps it's just been mangled by someone's mailer?

Quoted 93 lines
Quoted 19 lines
mm/slob.c +7 -2
       if (size < PAGE_SIZE - align) {
               if (!size)
                       return ZERO_SIZE_PTR;
 
               m = slob_alloc(size + align, gfp, align, node);
+
               if (!m)
                       return NULL;
               *m = size;
-               return (void *)m + align;
+               ret = (void *)m + align;
+
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL,
+                                         _RET_IP_, ret,
+                                         size, size + align, gfp, node);
       } else {
-               void *ret;
+               unsigned int order = get_order(size);
 

mm/slob.c void *__kmalloc_node(size_t size, gfp_t gfp, int node) · line 493

Quoted 10 lines
mm/slob.c +3 -2
-               ret = slob_new_page(gfp | __GFP_COMP, get_order(size), node);
+               ret = slob_new_page(gfp | __GFP_COMP, order, node);
               if (ret) {
                       struct page *page;
                       page = virt_to_page(ret);
                       page->private = size;
               }
-               return ret;
+
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_KERNEL,

The latter case is actually page allocator pass-through so I wonder if we want to use KIND_PAGES here instead?

Quoted 9 lines
mm/slob.c +4 -0
+                                         _RET_IP_, ret,
+                                         size, PAGE_SIZE << order, gfp, node);
       }
+
+       return ret;
 }
 EXPORT_SYMBOL(__kmalloc_node);
 

mm/slob.c void kfree(const void *block) · line 517

Quoted 5 lines
mm/slob.c +2 -0
@@ -501,6 +513,8 @@ void kfree(const void *block)
               slob_free(m, *m + align);
       } else
               put_page(&sp->page);
+
+       kmemtrace_mark_free(KMEMTRACE_KIND_KERNEL, _RET_IP_, block);

Same comment here.

Quoted 43 lines
mm/slob.c +13 -3
 }
 EXPORT_SYMBOL(kfree);
 
@@ -569,10 +583,19 @@ void *kmem_cache_alloc_node(struct kmem_cache *c, gfp_t flags, int node)
 {
       void *b;
 
-       if (c->size < PAGE_SIZE)
+       if (c->size < PAGE_SIZE) {
               b = slob_alloc(c->size, flags, c->align, node);
-       else
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE,
+                                         _RET_IP_, b, c->size,
+                                         SLOB_UNITS(c->size) * SLOB_UNIT,
+                                         flags, node);
+       } else {
               b = slob_new_page(flags, get_order(c->size), node);
+               kmemtrace_mark_alloc_node(KMEMTRACE_KIND_CACHE,
+                                         _RET_IP_, b, c->size,
+                                         PAGE_SIZE << get_order(c->size),
+                                         flags, node);
+       }
 
       if (c->ctor)
               c->ctor(c, b);
@@ -608,6 +631,8 @@ void kmem_cache_free(struct kmem_cache *c, void *b)
       } else {
               __kmem_cache_free(b, c->size);
       }
+
+       kmemtrace_mark_free(KMEMTRACE_KIND_CACHE, _RET_IP_, b);
 }
 EXPORT_SYMBOL(kmem_cache_free);
 
--

1.5.6.1

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

Signature · 7 lines
Mathematics is the supreme nostalgia of our time.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#34 lore raw

Re: [RFC PATCH 5/5] kmemtrace: SLOB hooks.

Quoted 8 lines · On Fri, 11 Jul 2008 10:36:37 -0500 Matt Mackall <[email protected]> wrote:
Quoted 4 lines · Pekka Enberg

Hi,

Matt, can you take a look at this? I know you don't want *debugging* code in SLOB but this is for instrumentation.

I presume this code all disappears in a default SLOB build?

Yes, of course. If CONFIG_KMEMTRACE is disabled, those calls go into empty static inlines.

Quoted 21 lines
Quoted 21 lines
Quoted 19 lines · Eduard - Gabriel Munteanu

This adds hooks for the SLOB allocator, to allow tracing with kmemtrace.

Signed-off-by: Eduard - Gabriel Munteanu
<[email protected]> ---

 mm/slob.c |   37 +++++++++++++++++++++++++++++++------
 1 files changed, 31 insertions(+), 6 deletions(-)
mm/slob.c +1 -0
index a3ad667..44f395a 100644
@@ -65,6 +65,7 @@
 #include <linux/module.h>
 #include <linux/rcupdate.h>
 #include <linux/list.h>
+#include <linux/kmemtrace.h>
 #include <asm/atomic.h>
 
Quoted 9 lines
Quoted 6 lines

mm/slob.c void *__kmalloc_node(size_t size, gfp_t · line 467

Quoted 6 lines
mm/slob.c +1 -0
 /*
@@ -463,27 +464,38 @@ void *__kmalloc_node(size_t size, gfp_t
 gfp, int node) {
       unsigned int *m;
       int align = max(ARCH_KMALLOC_MINALIGN, ARCH_SLAB_MINALIGN);
+       void *ret;

There's tons of tab damage in this patch. Or perhaps it's just been mangled by someone's mailer?

I know :-(. This was intended as a simple RFC, things will change on subsequent submissions.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>