public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* [PATCH V4] Tracepoint Tapset for Memory Subsystem
@ 2009-11-25  9:31 Rajasekhar Duddu
  2009-11-30 16:26 ` Frank Ch. Eigler
  0 siblings, 1 reply; 10+ messages in thread
From: Rajasekhar Duddu @ 2009-11-25  9:31 UTC (permalink / raw)
  To: systemtap

Hi all,
	here I am sending the updated patch along with the example
script. Please review it and let me know if it needs any more
improvements.


Changelog 1:
        Removed the Hardcoded constants in converting GFPFLAGS.
        Added a kprobe based fallback probe to kfree.

Changelog 2:
        Removed the unreliable code which was used in fetching the
call_site in kprobe based probe for
kfree.(__builtin_return_address(0))

Changelog 3:
        Defined two macros for converting the GFP_FLAGS into string
formats.
        Added k(ret)probe based fallback probes for all the
Functions.

Changelog 4:
	Added an example script and a corresponding meta file 
for kmem_cache_alloc probe point at 
testsuite/systemtap.examples/memory/vm.tracepoints.(stp/meta)


Sample O/P:

stap -v testsuite/systemtap.examples/memory/vm.tracepoints.stp 
Pass 1: parsed user script and 63 library script(s) in
170usr/10sys/189real ms.
Pass 2: analyzed script: 2 probe(s), 2 function(s), 5 embed(s), 1
global(s) in 20usr/0sys/24real ms.
Pass 3: using cached
/root/.systemtap/cache/97/stap_97935f61947942cab7e7143435bd6ee7_3084.c
Pass 4: using cached
/root/.systemtap/cache/97/stap_97935f61947942cab7e7143435bd6ee7_3084.ko
Pass 5: starting run.

Process:swapper
Slab_size:256   Count:3

Process:sendmail
Slab_size:4096  Count:4
Slab_size:256   Count:2
Slab_size:16    Count:2
Slab_size:192   Count:2
Slab_size:640   Count:2
Slab_size:72    Count:2
Slab_size:64    Count:2
Slab_size:32    Count:2
Slab_size:128   Count:2

Process:kjournald
Slab_size:104   Count:11
Slab_size:112   Count:11
Slab_size:256   Count:11
Slab_size:336   Count:2

-------------------------------------------------------


Process:sshd
Slab_size:512   Count:1
Slab_size:256   Count:1

Process:swapper
Slab_size:256   Count:1

Process:sendmail
Slab_size:4096  Count:4
Slab_size:256   Count:2
Slab_size:16    Count:2
Slab_size:192   Count:2
Slab_size:640   Count:2
Slab_size:72    Count:2
Slab_size:64    Count:2
Slab_size:32    Count:2
Slab_size:128   Count:2

Process:crond
Slab_size:4096  Count:2

-------------------------------------------------------

Patch:


Signed-off-by: Rajasekhar Duddu <rajduddu@linux.vnet.ibm.com>
diff -rupaN a/tapset/memory.stp b/tapset/memory.stp
--- a/tapset/memory.stp	2009-11-25 01:18:29.000000000 -0500
+++ b/tapset/memory.stp	2009-11-25 01:21:16.000000000 -0500
@@ -195,3 +195,269 @@ probe vm.brk = kernel.function("do_brk")
 probe vm.oom_kill = kernel.function("__oom_kill_task") {
     task = $p
 }
+/* Macro for GFP Bitmasks. */
+/* The resulted GFP_FLAGS may be either single or concatenation of the multiple bitmasks. */
+
+%{
+#define __GFP_BITMASKS(FLAG)  if(gfp_flag & FLAG) { if(THIS->__retvalue[0] != '\0') \
+		strlcat(THIS->__retvalue, " | "#FLAG, MAXSTRINGLEN); \
+		else strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); }
+%}
+
+
+/* Macro for Composite Flags. */
+/* Each Composite GFP_FLAG is the combination of multiple bitmasks. */
+
+%{
+#define __GFP_COMPOSITE_FLAG(FLAG)  if(gfp_flag == FLAG) { \
+		strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); return; }
+%}
+
+
+/* Function to convert the GFP_FLAGS into corresponding STRING formats. */
+
+function __gfp_flag_str:string(gfp_flag:long) %{
+	long gfp_flag = THIS->gfp_flag;
+	THIS->__retvalue[0] = '\0';
+
+
+/* Composite GFP FLAGS of the BitMasks. */
+
+	__GFP_COMPOSITE_FLAG(GFP_ZONEMASK)
+	__GFP_COMPOSITE_FLAG(GFP_ATOMIC)
+	__GFP_COMPOSITE_FLAG(GFP_NOIO)
+	__GFP_COMPOSITE_FLAG(GFP_NOFS)
+	__GFP_COMPOSITE_FLAG(GFP_KERNEL)
+	__GFP_COMPOSITE_FLAG(GFP_TEMPORARY)
+	__GFP_COMPOSITE_FLAG(GFP_USER)
+	__GFP_COMPOSITE_FLAG(GFP_HIGHUSER)
+	__GFP_COMPOSITE_FLAG(GFP_HIGHUSER_MOVABLE)
+	__GFP_COMPOSITE_FLAG(GFP_THISNODE)
+	__GFP_COMPOSITE_FLAG(GFP_DMA)
+	__GFP_COMPOSITE_FLAG(GFP_DMA32)
+
+/* GFP BitMasks */
+
+	__GFP_BITMASKS(__GFP_DMA)
+	__GFP_BITMASKS(__GFP_HIGHMEM)
+	__GFP_BITMASKS(__GFP_MOVABLE)
+	__GFP_BITMASKS(__GFP_WAIT)
+	__GFP_BITMASKS(__GFP_HIGH)
+	__GFP_BITMASKS(__GFP_IO)
+	__GFP_BITMASKS(__GFP_FS)
+	__GFP_BITMASKS(__GFP_COLD)
+	__GFP_BITMASKS(__GFP_NOWARN)
+	__GFP_BITMASKS(__GFP_REPEAT)
+	__GFP_BITMASKS(__GFP_NOFAIL)
+	__GFP_BITMASKS(__GFP_COMP)
+	__GFP_BITMASKS(__GFP_ZERO)
+	__GFP_BITMASKS(__GFP_NOMEMALLOC)
+	__GFP_BITMASKS(__GFP_HARDWALL)
+	__GFP_BITMASKS(__GFP_THISNODE)
+	__GFP_BITMASKS(__GFP_RECLAIMABLE)
+	__GFP_BITMASKS(__GFP_NOTRACK)
+
+%}
+
+/* The Formal Parameters will be displayed if available, otherwise \
+		 "0" or "unknown" will be displayed */
+
+probe __vm.kmalloc.tp = kernel.trace("kmalloc") {
+	name = "kmalloc"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+/* It is unsafe to invoke __builtin_return_address() \
+presently(to get call_site for kporbe based probes) \
+and that it can be improved later when fix for bugs bz#6961 and bz#6580 is available. */
+
+probe __vm.kmalloc.kp = kernel.function("kmalloc").return {
+	name = "kmalloc"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmalloc - Fires when kmalloc is requested.
+ * @call_site: Address of the kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: type of kmemory to allocate (in String format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc = __vm.kmalloc.tp !,
+			__vm.kmalloc.kp
+{}
+
+
+probe __vm.kmem_cache_alloc.tp = kernel.trace("kmem_cache_alloc") {
+	name = "kmem_cache_alloc"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmem_cache_alloc.kp = kernel.function("kmem_cache_alloc").return {
+	name = "kmem_cache_alloc"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmem_cache_alloc - Fires when \
+ *              kmem_cache_alloc is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+
+probe vm.kmem_cache_alloc = __vm.kmem_cache_alloc.tp !,
+				__vm.kmem_cache_alloc.kp
+{}
+
+probe __vm.kmalloc_node.tp = kernel.trace("kmalloc_node")? {
+	name = "kmalloc_node"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmalloc_node.kp = kernel.function("kmalloc_node").return? {
+	name = "kmalloc_node"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmalloc_node - Fires when kmalloc_node is requested.
+ * @call_site: Address of the function caling this  kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc_node = __vm.kmalloc_node.tp !,
+			__vm.kmalloc_node.kp
+{}
+
+probe __vm.kmem_cache_alloc_node.tp = kernel.trace("kmem_cache_alloc_node")? {
+	name = "kmem_cache_alloc_node"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmem_cache_alloc_node.kp = kernel.function("kmem_cache_alloc_node").return? {
+	name = "kmem_cache_alloc_node"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmem_cache_alloc_node - Fires when \
+ *              kmem_cache_alloc_node is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmem_cache_alloc_node = __vm.kmem_cache_alloc_node.tp !,
+				__vm.kmem_cache_alloc_node.kp
+{}
+
+
+probe __vm.kfree.tp = kernel.trace("kfree") {
+	name = "kfree"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+
+probe __vm.kfree.kp = kernel.function("kfree").return {
+	name = "kfree"
+	call_site = 0
+	caller_function = "unknown"
+	ptr = $return
+}
+
+/**
+ * probe vm.kfree - Fires when kfree is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @ptr: Pointer to the kmemory allocated which is returned by kmalloc
+ */
+probe vm.kfree = __vm.kfree.tp !,
+		__vm.kfree.kp
+{}
+
+probe __vm.kmem_cache_free.tp = kernel.trace("kmem_cache_free") {
+	name = "kmem_cache_free"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+probe __vm.kmem_cache_free.kp = kernel.function("kmem_cache_free").return {
+	name = "kmem_cache_free"
+	call_site = 0
+	caller_function = "unknown"
+	ptr = $return
+}
+/**
+ * probe vm.kmem_cache_free - Fires when \
+ *              kmem_cache_free is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @ptr: Pointer to the kmemory allocated which is returned by kmem_cache
+ */
+probe vm.kmem_cache_free = __vm.kmem_cache_free.tp !,
+				__vm.kmem_cache_free.kp
+{}
diff -rupaN a/testsuite/buildok/vm.tracepoints.stp b/testsuite/buildok/vm.tracepoints.stp
--- a/testsuite/buildok/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/buildok/vm.tracepoints.stp	2009-11-25 04:05:23.000000000 -0500
@@ -0,0 +1,31 @@
+#! stap -up4
+
+probe vm.kfree {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
+
+probe vm.kmalloc {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_alloc {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmalloc_node {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_alloc_node {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_free {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
diff -rupaN a/testsuite/systemtap.examples/memory/vm.tracepoints.meta b/testsuite/systemtap.examples/memory/vm.tracepoints.meta
--- a/testsuite/systemtap.examples/memory/vm.tracepoints.meta	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/systemtap.examples/memory/vm.tracepoints.meta	2009-11-25 03:58:25.000000000 -0500
@@ -0,0 +1,13 @@
+title: Collect slab allocation statistics
+name: vm.tracepoints.stp
+version: 1.0
+author: Rajasekhar
+keywords: memory slab allocator
+subsystem: memory
+status: production
+exit: user-controlled
+output: sorted-list
+scope: system-wide
+description: The script will probe all memory slab/slub allocations and collects information about the size of the object (bytes requested) and user-space process in execution. When run over a period of time, it helps to correlate kernel-space memory consumption owing to user-space processes.
+test_check: stap -p4 vm.tracepoints.stp
+test_installcheck: stap vm.tracepoints.stp -c "sleep 10"
diff -rupaN a/testsuite/systemtap.examples/memory/vm.tracepoints.stp b/testsuite/systemtap.examples/memory/vm.tracepoints.stp
--- a/testsuite/systemtap.examples/memory/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/systemtap.examples/memory/vm.tracepoints.stp	2009-11-25 04:06:21.000000000 -0500
@@ -0,0 +1,18 @@
+global slabs
+
+probe vm.kmem_cache_alloc {
+	slabs [execname(), bytes_req]++
+}
+
+probe timer.ms(10000)
+{
+	dummy = "";
+	foreach ([name, bytes] in slabs) {
+		if (dummy != name)
+			printf("\nProcess:%s\n", name);
+        	printf("Slab_size:%d\tCount:%d\n", bytes, slabs[name, bytes]);
+		dummy = name;
+	}
+	delete slabs
+	printf("\n-------------------------------------------------------\n\n")
+}


Thanks 
-- 
Rajasekhar Duddu (rajduddu@linux.vnet.ibm.com),
Linux on System z - CSVT, IBM LTC, Bangalore.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V4] Tracepoint Tapset for Memory Subsystem
  2009-11-25  9:31 [PATCH V4] Tracepoint Tapset for Memory Subsystem Rajasekhar Duddu
@ 2009-11-30 16:26 ` Frank Ch. Eigler
  2009-12-04 12:09   ` [PATCH V5] " Rajasekhar Duddu
  0 siblings, 1 reply; 10+ messages in thread
From: Frank Ch. Eigler @ 2009-11-30 16:26 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

Rajasekhar Duddu <rajduddu@linux.vnet.ibm.com> writes:

> [...]
> +%{
> +#define __GFP_BITMASKS(FLAG)  if(gfp_flag & FLAG) { if(THIS->__retvalue[0] != '\0') \
> +		strlcat(THIS->__retvalue, " | "#FLAG, MAXSTRINGLEN); \
> +		else strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); }
> +%}
> +%{
> +#define __GFP_COMPOSITE_FLAG(FLAG)  if(gfp_flag == FLAG) { \
> +		strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); return; }
> +%}

These should be defined within the embedded-c function block below,
and should be #undef'd there too, to avoid polluting the namespace.


>[...]
> --- a/testsuite/systemtap.examples/memory/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
> +++ b/testsuite/systemtap.examples/memory/vm.tracepoints.stp	2009-11-25 04:06:21.000000000 -0500
> @@ -0,0 +1,18 @@
> +global slabs
> +
> +probe vm.kmem_cache_alloc {
> +	slabs [execname(), bytes_req]++
> +}
> +
> +probe timer.ms(10000)
> +{
> +	dummy = "";
> +	foreach ([name, bytes] in slabs) {
> +		if (dummy != name)
> +			printf("\nProcess:%s\n", name);
> +        	printf("Slab_size:%d\tCount:%d\n", bytes, slabs[name, bytes]);
> +		dummy = name;
> +	}
> +	delete slabs
> +	printf("\n-------------------------------------------------------\n\n")
> +}

As a matter of style, this would be nearly equivalent to all of that,
except for reporting once at the end rather than every 10 seconds.

global slabs
probe vm.kmem_cache_alloc {
	slabs [execname(), bytes_req]<<<1
}

Please confirm that the tapset reference documentation template is
configured to extract the @@doc stuff from the tapset.

Please add a sentence to NEWS to describe the new tapset.  (Others
who recently added tapset extensions should do the same!)

Please commit with those changes.
  
- FChE

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
  2009-11-30 16:26 ` Frank Ch. Eigler
@ 2009-12-04 12:09   ` Rajasekhar Duddu
  2009-12-07  2:52     ` Wenji Huang
  0 siblings, 1 reply; 10+ messages in thread
From: Rajasekhar Duddu @ 2009-12-04 12:09 UTC (permalink / raw)
  To: systemtap


Hi all,
	I have update the patch according to Franks previous
comments.
Please review it and if it is fine, please somebody commit this
version of patch on behalf of me..thanks in advance.

Changelog 1:
        Removed the Hardcoded constants in converting GFPFLAGS.
        Added a kprobe based fallback probe to kfree.

Changelog 2:
        Removed the unreliable code which was used in fetching the
call_site in kprobe based probe for
kfree.(__builtin_return_address(0))

Changelog 3:
        Defined two macros for converting the GFP_FLAGS into string
formats.
        Added k(ret)probe based fallback probes for all the
Functions.

Changelog 4:
        Added an example script and a corresponding meta file
for kmem_cache_alloc probe point at
testsuite/systemtap.examples/memory/vm.tracepoints.(stp/meta)

Changelog 5:
	Updated the example script.
	Added description of the tapset in NEWS.
	Confirmed that the tapset reference documentation
template is configured to extract the @@doc stuff from the tapset .


Sample O/P:

stap -v testsuite/systemtap.examples/memory/vm.tracepoints.stp
Pass 1: parsed user script and 63 library script(s) in
170usr/10sys/189real ms.
Pass 2: analyzed script: 2 probe(s), 2 function(s), 3 embed(s), 1
global(s) in 11480usr/3730sys/14373real ms.
Pass 3: translated to C into
"/tmp/stapxnPdcI/stap_2436291999f620c5f051efe7320a1268_3415.c" in
0usr/0sys/1real ms.
Pass 4: compiled C into
"stap_2436291999f620c5f051efe7320a1268_3415.ko" in
3600usr/610sys/4176real ms.
Pass 5: starting run.

Process:kjournald
Slab_size:256   Count:109
Slab_size:112   Count:109
Slab_size:104   Count:109
Slab_size:336   Count:2

Process:swapper
Slab_size:256   Count:1

Process:sendmail
Slab_size:192   Count:2
Slab_size:64    Count:2
Slab_size:640   Count:2
Slab_size:16    Count:2
Slab_size:32    Count:2
Slab_size:256   Count:2
Slab_size:128   Count:2
Slab_size:72    Count:2
Slab_size:4096  Count:4

-------------------------------------------------------


Process:sshd
Slab_size:256   Count:1

Process:pdflush
Slab_size:256   Count:729

Process:sshd
Slab_size:512   Count:1


Patch:


Signed-off-by: Rajasekhar Duddu <rajduddu@linux.vnet.ibm.com>
diff -rupaN a/NEWS b/NEWS
--- a/NEWS	2009-11-25 01:18:29.000000000 -0500
+++ b/NEWS	2009-12-04 06:24:33.000000000 -0500
@@ -1,3 +1,5 @@
+New tapset for Memory subsystem based on Kernel Tracepoints.
+
 * What's new in verson 1.0
 
 - process().mark() probes now use an enabling semaphore to reduce the
diff -rupaN a/tapset/memory.stp b/tapset/memory.stp
--- a/tapset/memory.stp	2009-11-25 01:18:29.000000000 -0500
+++ b/tapset/memory.stp	2009-12-04 06:42:12.000000000 -0500
@@ -195,3 +195,269 @@ probe vm.brk = kernel.function("do_brk")
 probe vm.oom_kill = kernel.function("__oom_kill_task") {
     task = $p
 }
+
+function __gfp_flag_str:string(gfp_flag:long) %{
+	long gfp_flag = THIS->gfp_flag;
+	THIS->__retvalue[0] = '\0';
+
+
+/* Macro for GFP Bitmasks. */
+/* The resulted GFP_FLAGS may be either single or concatenation of the multiple bitmasks. */
+
+
+#define __GFP_BITMASKS(FLAG)  if(gfp_flag & FLAG) { if(THIS->__retvalue[0] != '\0') \
+                strlcat(THIS->__retvalue, " | "#FLAG, MAXSTRINGLEN); \
+                else strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); }
+
+
+/* Macro for Composite Flags. */
+/* Each Composite GFP_FLAG is the combination of multiple bitmasks. */
+
+
+#define __GFP_COMPOSITE_FLAG(FLAG)  if(gfp_flag == FLAG) { \
+                strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); return; }
+
+
+/* Composite GFP FLAGS of the BitMasks. */
+
+	__GFP_COMPOSITE_FLAG(GFP_ZONEMASK)
+	__GFP_COMPOSITE_FLAG(GFP_ATOMIC)
+	__GFP_COMPOSITE_FLAG(GFP_NOIO)
+	__GFP_COMPOSITE_FLAG(GFP_NOFS)
+	__GFP_COMPOSITE_FLAG(GFP_KERNEL)
+	__GFP_COMPOSITE_FLAG(GFP_TEMPORARY)
+	__GFP_COMPOSITE_FLAG(GFP_USER)
+	__GFP_COMPOSITE_FLAG(GFP_HIGHUSER)
+	__GFP_COMPOSITE_FLAG(GFP_HIGHUSER_MOVABLE)
+	__GFP_COMPOSITE_FLAG(GFP_THISNODE)
+	__GFP_COMPOSITE_FLAG(GFP_DMA)
+	__GFP_COMPOSITE_FLAG(GFP_DMA32)
+
+/* GFP BitMasks */
+
+	__GFP_BITMASKS(__GFP_DMA)
+	__GFP_BITMASKS(__GFP_HIGHMEM)
+	__GFP_BITMASKS(__GFP_MOVABLE)
+	__GFP_BITMASKS(__GFP_WAIT)
+	__GFP_BITMASKS(__GFP_HIGH)
+	__GFP_BITMASKS(__GFP_IO)
+	__GFP_BITMASKS(__GFP_FS)
+	__GFP_BITMASKS(__GFP_COLD)
+	__GFP_BITMASKS(__GFP_NOWARN)
+	__GFP_BITMASKS(__GFP_REPEAT)
+	__GFP_BITMASKS(__GFP_NOFAIL)
+	__GFP_BITMASKS(__GFP_COMP)
+	__GFP_BITMASKS(__GFP_ZERO)
+	__GFP_BITMASKS(__GFP_NOMEMALLOC)
+	__GFP_BITMASKS(__GFP_HARDWALL)
+	__GFP_BITMASKS(__GFP_THISNODE)
+	__GFP_BITMASKS(__GFP_RECLAIMABLE)
+	__GFP_BITMASKS(__GFP_NOTRACK)
+
+
+#undef __GFP_BITMASKS
+#undef __GFP_COMPOSITE_FLAG
+%}
+
+/* The Formal Parameters will be displayed if available, otherwise \
+		 "0" or "unknown" will be displayed */
+
+probe __vm.kmalloc.tp = kernel.trace("kmalloc") {
+	name = "kmalloc"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+/* It is unsafe to invoke __builtin_return_address() \
+presently(to get call_site for kporbe based probes) \
+and that it can be improved later when fix for bugs bz#6961 and bz#6580 is available. */
+
+probe __vm.kmalloc.kp = kernel.function("kmalloc").return {
+	name = "kmalloc"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmalloc - Fires when kmalloc is requested.
+ * @call_site: Address of the kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: type of kmemory to allocate (in String format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc = __vm.kmalloc.tp !,
+			__vm.kmalloc.kp
+{}
+
+
+probe __vm.kmem_cache_alloc.tp = kernel.trace("kmem_cache_alloc") {
+	name = "kmem_cache_alloc"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmem_cache_alloc.kp = kernel.function("kmem_cache_alloc").return {
+	name = "kmem_cache_alloc"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmem_cache_alloc - Fires when \
+ *              kmem_cache_alloc is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+
+probe vm.kmem_cache_alloc = __vm.kmem_cache_alloc.tp !,
+				__vm.kmem_cache_alloc.kp
+{}
+
+probe __vm.kmalloc_node.tp = kernel.trace("kmalloc_node")? {
+	name = "kmalloc_node"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmalloc_node.kp = kernel.function("kmalloc_node").return? {
+	name = "kmalloc_node"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmalloc_node - Fires when kmalloc_node is requested.
+ * @call_site: Address of the function caling this  kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc_node = __vm.kmalloc_node.tp !,
+			__vm.kmalloc_node.kp
+{}
+
+probe __vm.kmem_cache_alloc_node.tp = kernel.trace("kmem_cache_alloc_node")? {
+	name = "kmem_cache_alloc_node"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmem_cache_alloc_node.kp = kernel.function("kmem_cache_alloc_node").return? {
+	name = "kmem_cache_alloc_node"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmem_cache_alloc_node - Fires when \
+ *              kmem_cache_alloc_node is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmem_cache_alloc_node = __vm.kmem_cache_alloc_node.tp !,
+				__vm.kmem_cache_alloc_node.kp
+{}
+
+
+probe __vm.kfree.tp = kernel.trace("kfree") {
+	name = "kfree"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+
+probe __vm.kfree.kp = kernel.function("kfree").return {
+	name = "kfree"
+	call_site = 0
+	caller_function = "unknown"
+	ptr = $return
+}
+
+/**
+ * probe vm.kfree - Fires when kfree is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @ptr: Pointer to the kmemory allocated which is returned by kmalloc
+ */
+probe vm.kfree = __vm.kfree.tp !,
+		__vm.kfree.kp
+{}
+
+probe __vm.kmem_cache_free.tp = kernel.trace("kmem_cache_free") {
+	name = "kmem_cache_free"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+probe __vm.kmem_cache_free.kp = kernel.function("kmem_cache_free").return {
+	name = "kmem_cache_free"
+	call_site = 0
+	caller_function = "unknown"
+	ptr = $return
+}
+/**
+ * probe vm.kmem_cache_free - Fires when \
+ *              kmem_cache_free is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @ptr: Pointer to the kmemory allocated which is returned by kmem_cache
+ */
+probe vm.kmem_cache_free = __vm.kmem_cache_free.tp !,
+				__vm.kmem_cache_free.kp
+{}
diff -rupaN a/testsuite/buildok/vm.tracepoints.stp b/testsuite/buildok/vm.tracepoints.stp
--- a/testsuite/buildok/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/buildok/vm.tracepoints.stp	2009-12-04 06:20:12.000000000 -0500
@@ -0,0 +1,31 @@
+#! stap -up4
+
+probe vm.kfree {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
+
+probe vm.kmalloc {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_alloc {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmalloc_node {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_alloc_node {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_free {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
diff -rupaN a/testsuite/systemtap.examples/memory/vm.tracepoints.meta b/testsuite/systemtap.examples/memory/vm.tracepoints.meta
--- a/testsuite/systemtap.examples/memory/vm.tracepoints.meta	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/systemtap.examples/memory/vm.tracepoints.meta	2009-12-04 06:22:05.000000000 -0500
@@ -0,0 +1,13 @@
+title: Collect slab allocation statistics
+name: vm.tracepoints.stp
+version: 1.0
+author: Rajasekhar
+keywords: memory slab allocator
+subsystem: memory
+status: production
+exit: user-controlled
+output: sorted-list
+scope: system-wide
+description: The script will probe all memory slab/slub allocations and collects information about the size of the object (bytes requested) and user-space process in execution. When run over a period of time, it helps to correlate kernel-space memory consumption owing to user-space processes.
+test_check: stap -p4 vm.tracepoints.stp
+test_installcheck: stap vm.tracepoints.stp -c "sleep 10"
diff -rupaN a/testsuite/systemtap.examples/memory/vm.tracepoints.stp b/testsuite/systemtap.examples/memory/vm.tracepoints.stp
--- a/testsuite/systemtap.examples/memory/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/systemtap.examples/memory/vm.tracepoints.stp	2009-12-04 06:21:38.000000000 -0500
@@ -0,0 +1,18 @@
+global slabs
+
+probe vm.kmem_cache_alloc {
+	slabs [execname(), bytes_req]<<<1
+}
+
+probe timer.ms(10000)
+{
+	dummy = "";
+	foreach ([name, bytes] in slabs) {
+		if (dummy != name)
+			printf("\nProcess:%s\n", name);
+        	printf("Slab_size:%d\tCount:%d\n", bytes, @count(slabs[name, bytes]));
+		dummy = name;
+	}
+	delete slabs
+	printf("\n-------------------------------------------------------\n\n")
+}

Thanks
-- 
Rajasekhar Duddu (rajduddu@linux.vnet.ibm.com),
Linux on System z - CSVT, IBM LTC, Bangalore.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
  2009-12-04 12:09   ` [PATCH V5] " Rajasekhar Duddu
@ 2009-12-07  2:52     ` Wenji Huang
  2009-12-09  6:57       ` Rajasekhar Duddu
  0 siblings, 1 reply; 10+ messages in thread
From: Wenji Huang @ 2009-12-07  2:52 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

Hi,

Rajasekhar Duddu wrote:
> +/* The Formal Parameters will be displayed if available, otherwise \
> +		 "0" or "unknown" will be displayed */
> +
> +probe __vm.kmalloc.tp = kernel.trace("kmalloc") {
> +	name = "kmalloc"
> +	call_site = $call_site
> +	caller_function = symname(call_site)
> +	bytes_req = $bytes_req
> +	bytes_alloc = $bytes_alloc
> +	gfp_flags = $gfp_flags
> +	gfp_flag_name = __gfp_flag_str($gfp_flags)
> +	ptr = $ptr
> +}
> +
> +/* It is unsafe to invoke __builtin_return_address() \
> +presently(to get call_site for kporbe based probes) \
> +and that it can be improved later when fix for bugs bz#6961 and bz#6580 is available. */
> +
> +probe __vm.kmalloc.kp = kernel.function("kmalloc").return {
> +	name = "kmalloc"
> +	call_site = 0
> +	caller_function = "unknown"
> +	bytes_req = $size
> +	bytes_alloc = "unknown"
why let bytes_alloc be "unknown", not 0 ?
The type is not consistent with the above one.

Same issue exists in the following part.


Regards,
Wenji


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
  2009-12-07  2:52     ` Wenji Huang
@ 2009-12-09  6:57       ` Rajasekhar Duddu
  2009-12-11 18:36         ` [PATCH V6] " Rajasekhar Duddu
  0 siblings, 1 reply; 10+ messages in thread
From: Rajasekhar Duddu @ 2009-12-09  6:57 UTC (permalink / raw)
  To: Wenji Huang; +Cc: systemtap

On Mon, Dec 07, 2009 at 10:49:59AM +0800, Wenji Huang wrote:
> Hi,
>
> Rajasekhar Duddu wrote:
>> +/* The Formal Parameters will be displayed if available, otherwise \
>> +		 "0" or "unknown" will be displayed */
>> +
>> +probe __vm.kmalloc.tp = kernel.trace("kmalloc") {
>> +	name = "kmalloc"
>> +	call_site = $call_site
>> +	caller_function = symname(call_site)
>> +	bytes_req = $bytes_req
>> +	bytes_alloc = $bytes_alloc
>> +	gfp_flags = $gfp_flags
>> +	gfp_flag_name = __gfp_flag_str($gfp_flags)
>> +	ptr = $ptr
>> +}
>> +
>> +/* It is unsafe to invoke __builtin_return_address() \
>> +presently(to get call_site for kporbe based probes) \
>> +and that it can be improved later when fix for bugs bz#6961 and bz#6580 is available. */
>> +
>> +probe __vm.kmalloc.kp = kernel.function("kmalloc").return {
>> +	name = "kmalloc"
>> +	call_site = 0
>> +	caller_function = "unknown"
>> +	bytes_req = $size
>> +	bytes_alloc = "unknown"
> why let bytes_alloc be "unknown", not 0 ?
> The type is not consistent with the above one.
>
> Same issue exists in the following part.
>
Hi Wenji,
	I do agree with you that type is not consistent here, but if
bytes_alloc is assigined "0" , it may indicate a failure.
When Memory allacation is successful then bytes_alloc would be
non-zero which we are not able to fetch here, so I feel its not
good to assign it with zero.

Thanks

-- 
Rajasekhar Duddu (rajduddu@linux.vnet.ibm.com),
Linux on System z - CSVT, IBM LTC, Bangalore.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V6] Tracepoint Tapset for Memory Subsystem
  2009-12-09  6:57       ` Rajasekhar Duddu
@ 2009-12-11 18:36         ` Rajasekhar Duddu
  2009-12-21 11:46           ` Prerna Saxena
  2009-12-29 21:36           ` Mark Wielaard
  0 siblings, 2 replies; 10+ messages in thread
From: Rajasekhar Duddu @ 2009-12-11 18:36 UTC (permalink / raw)
  To: systemtap

Hi, 
	I have corrected the typo error in this patch.
If it is fine, please some body commit this pathc on behalf of me.
Thanks in advance.

Changelog 1:
        Removed the Hardcoded constants in converting GFPFLAGS.
        Added a kprobe based fallback probe to kfree.

Changelog 2:
        Removed the unreliable code which was used in fetching the
call_site in kprobe based probe for
kfree.(__builtin_return_address(0))

Changelog 3:
        Defined two macros for converting the GFP_FLAGS into string
formats.
        Added k(ret)probe based fallback probes for all the
Functions.

Changelog 4:
        Added an example script and a corresponding meta file
for kmem_cache_alloc probe point at
testsuite/systemtap.examples/memory/vm.tracepoints.(stp/meta)

Changelog 5:
        Updated the example script.
        Added description of the tapset in NEWS.
        Confirmed that the tapset reference documentation
template is configured to extract the @@doc stuff from the tapset .


Sample O/P:

stap -v testsuite/systemtap.examples/memory/vm.tracepoints.stp
Pass 1: parsed user script and 63 library script(s) in
170usr/10sys/189real ms.
Pass 2: analyzed script: 2 probe(s), 2 function(s), 3 embed(s), 1
global(s) in 11480usr/3730sys/14373real ms.
Pass 3: translated to C into
"/tmp/stapxnPdcI/stap_2436291999f620c5f051efe7320a1268_3415.c" in
0usr/0sys/1real ms.
Pass 4: compiled C into
"stap_2436291999f620c5f051efe7320a1268_3415.ko" in
3600usr/610sys/4176real ms.
Pass 5: starting run.

Process:kjournald
Slab_size:256   Count:109
Slab_size:112   Count:109
Slab_size:104   Count:109
Slab_size:336   Count:2

Process:swapper
Slab_size:256   Count:1

Pactch:


Signed-off-by: Rajasekhar Duddu <rajduddu@linux.vnet.ibm.com>
diff -rupaN a/NEWS b/NEWS
--- a/NEWS	2009-11-25 01:18:29.000000000 -0500
+++ b/NEWS	2009-12-04 06:24:33.000000000 -0500
@@ -1,3 +1,5 @@
+New tapset for Memory subsystem based on Kernel Tracepoints.
+
 * What's new in verson 1.0
 
 - process().mark() probes now use an enabling semaphore to reduce the
diff -rupaN a/tapset/memory.stp b/tapset/memory.stp
--- a/tapset/memory.stp	2009-11-25 01:18:29.000000000 -0500
+++ b/tapset/memory.stp	2009-12-11 13:13:40.000000000 -0500
@@ -195,3 +195,269 @@ probe vm.brk = kernel.function("do_brk")
 probe vm.oom_kill = kernel.function("__oom_kill_task") {
     task = $p
 }
+
+function __gfp_flag_str:string(gfp_flag:long) %{
+	long gfp_flag = THIS->gfp_flag;
+	THIS->__retvalue[0] = '\0';
+
+
+/* Macro for GFP Bitmasks. */
+/* The resulted GFP_FLAGS may be either single or concatenation of the multiple bitmasks. */
+
+
+#define __GFP_BITMASKS(FLAG)  if(gfp_flag & FLAG) { if(THIS->__retvalue[0] != '\0') \
+                strlcat(THIS->__retvalue, " | "#FLAG, MAXSTRINGLEN); \
+                else strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); }
+
+
+/* Macro for Composite Flags. */
+/* Each Composite GFP_FLAG is the combination of multiple bitmasks. */
+
+
+#define __GFP_COMPOSITE_FLAG(FLAG)  if(gfp_flag == FLAG) { \
+                strlcat(THIS->__retvalue, #FLAG, MAXSTRINGLEN); return; }
+
+
+/* Composite GFP FLAGS of the BitMasks. */
+
+	__GFP_COMPOSITE_FLAG(GFP_ZONEMASK)
+	__GFP_COMPOSITE_FLAG(GFP_ATOMIC)
+	__GFP_COMPOSITE_FLAG(GFP_NOIO)
+	__GFP_COMPOSITE_FLAG(GFP_NOFS)
+	__GFP_COMPOSITE_FLAG(GFP_KERNEL)
+	__GFP_COMPOSITE_FLAG(GFP_TEMPORARY)
+	__GFP_COMPOSITE_FLAG(GFP_USER)
+	__GFP_COMPOSITE_FLAG(GFP_HIGHUSER)
+	__GFP_COMPOSITE_FLAG(GFP_HIGHUSER_MOVABLE)
+	__GFP_COMPOSITE_FLAG(GFP_THISNODE)
+	__GFP_COMPOSITE_FLAG(GFP_DMA)
+	__GFP_COMPOSITE_FLAG(GFP_DMA32)
+
+/* GFP BitMasks */
+
+	__GFP_BITMASKS(__GFP_DMA)
+	__GFP_BITMASKS(__GFP_HIGHMEM)
+	__GFP_BITMASKS(__GFP_MOVABLE)
+	__GFP_BITMASKS(__GFP_WAIT)
+	__GFP_BITMASKS(__GFP_HIGH)
+	__GFP_BITMASKS(__GFP_IO)
+	__GFP_BITMASKS(__GFP_FS)
+	__GFP_BITMASKS(__GFP_COLD)
+	__GFP_BITMASKS(__GFP_NOWARN)
+	__GFP_BITMASKS(__GFP_REPEAT)
+	__GFP_BITMASKS(__GFP_NOFAIL)
+	__GFP_BITMASKS(__GFP_COMP)
+	__GFP_BITMASKS(__GFP_ZERO)
+	__GFP_BITMASKS(__GFP_NOMEMALLOC)
+	__GFP_BITMASKS(__GFP_HARDWALL)
+	__GFP_BITMASKS(__GFP_THISNODE)
+	__GFP_BITMASKS(__GFP_RECLAIMABLE)
+	__GFP_BITMASKS(__GFP_NOTRACK)
+
+
+#undef __GFP_BITMASKS
+#undef __GFP_COMPOSITE_FLAG
+%}
+
+/* The Formal Parameters will be displayed if available, otherwise \
+		 "0" or "unknown" will be displayed */
+
+probe __vm.kmalloc.tp = kernel.trace("kmalloc") {
+	name = "kmalloc"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+/* It is unsafe to invoke __builtin_return_address() \
+presently(to get call_site for kprobe based probes) \
+and that it can be improved later when fix for bugs bz#6961 and bz#6580 is available. */
+
+probe __vm.kmalloc.kp = kernel.function("kmalloc").return {
+	name = "kmalloc"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmalloc - Fires when kmalloc is requested.
+ * @call_site: Address of the kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: type of kmemory to allocate (in String format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc = __vm.kmalloc.tp !,
+			__vm.kmalloc.kp
+{}
+
+
+probe __vm.kmem_cache_alloc.tp = kernel.trace("kmem_cache_alloc") {
+	name = "kmem_cache_alloc"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmem_cache_alloc.kp = kernel.function("kmem_cache_alloc").return {
+	name = "kmem_cache_alloc"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmem_cache_alloc - Fires when \
+ *              kmem_cache_alloc is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+
+probe vm.kmem_cache_alloc = __vm.kmem_cache_alloc.tp !,
+				__vm.kmem_cache_alloc.kp
+{}
+
+probe __vm.kmalloc_node.tp = kernel.trace("kmalloc_node")? {
+	name = "kmalloc_node"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmalloc_node.kp = kernel.function("kmalloc_node").return? {
+	name = "kmalloc_node"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmalloc_node - Fires when kmalloc_node is requested.
+ * @call_site: Address of the function caling this  kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc_node = __vm.kmalloc_node.tp !,
+			__vm.kmalloc_node.kp
+{}
+
+probe __vm.kmem_cache_alloc_node.tp = kernel.trace("kmem_cache_alloc_node")? {
+	name = "kmem_cache_alloc_node"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	bytes_req = $bytes_req
+	bytes_alloc = $bytes_alloc
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+probe __vm.kmem_cache_alloc_node.kp = kernel.function("kmem_cache_alloc_node").return? {
+	name = "kmem_cache_alloc_node"
+	call_site = 0
+	caller_function = "unknown"
+	bytes_req = $size
+	bytes_alloc = "unknown"
+	gfp_flags = $gfp_flags
+	gfp_flag_name = __gfp_flag_str($gfp_flags)
+	ptr = $return
+}
+
+/**
+ * probe vm.kmem_cache_alloc_node - Fires when \
+ *              kmem_cache_alloc_node is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @gfp_flag_name: Type of kmemory to allocate(in string format)
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmem_cache_alloc_node = __vm.kmem_cache_alloc_node.tp !,
+				__vm.kmem_cache_alloc_node.kp
+{}
+
+
+probe __vm.kfree.tp = kernel.trace("kfree") {
+	name = "kfree"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+
+probe __vm.kfree.kp = kernel.function("kfree").return {
+	name = "kfree"
+	call_site = 0
+	caller_function = "unknown"
+	ptr = $return
+}
+
+/**
+ * probe vm.kfree - Fires when kfree is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @ptr: Pointer to the kmemory allocated which is returned by kmalloc
+ */
+probe vm.kfree = __vm.kfree.tp !,
+		__vm.kfree.kp
+{}
+
+probe __vm.kmem_cache_free.tp = kernel.trace("kmem_cache_free") {
+	name = "kmem_cache_free"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+probe __vm.kmem_cache_free.kp = kernel.function("kmem_cache_free").return {
+	name = "kmem_cache_free"
+	call_site = 0
+	caller_function = "unknown"
+	ptr = $return
+}
+/**
+ * probe vm.kmem_cache_free - Fires when \
+ *              kmem_cache_free is requested.
+ * @call_site: Address of the function calling this kmemory function.
+ * @caller_function: Name of the caller function.
+ * @ptr: Pointer to the kmemory allocated which is returned by kmem_cache
+ */
+probe vm.kmem_cache_free = __vm.kmem_cache_free.tp !,
+				__vm.kmem_cache_free.kp
+{}
diff -rupaN a/testsuite/buildok/vm.tracepoints.stp b/testsuite/buildok/vm.tracepoints.stp
--- a/testsuite/buildok/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/buildok/vm.tracepoints.stp	2009-12-04 06:20:12.000000000 -0500
@@ -0,0 +1,31 @@
+#! stap -up4
+
+probe vm.kfree {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
+
+probe vm.kmalloc {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_alloc {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmalloc_node {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_alloc_node {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags, gfp_flag_name)
+}
+
+probe vm.kmem_cache_free {
+        println(name)
+        printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
diff -rupaN a/testsuite/systemtap.examples/memory/vm.tracepoints.meta b/testsuite/systemtap.examples/memory/vm.tracepoints.meta
--- a/testsuite/systemtap.examples/memory/vm.tracepoints.meta	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/systemtap.examples/memory/vm.tracepoints.meta	2009-12-04 06:22:05.000000000 -0500
@@ -0,0 +1,13 @@
+title: Collect slab allocation statistics
+name: vm.tracepoints.stp
+version: 1.0
+author: Rajasekhar
+keywords: memory slab allocator
+subsystem: memory
+status: production
+exit: user-controlled
+output: sorted-list
+scope: system-wide
+description: The script will probe all memory slab/slub allocations and collects information about the size of the object (bytes requested) and user-space process in execution. When run over a period of time, it helps to correlate kernel-space memory consumption owing to user-space processes.
+test_check: stap -p4 vm.tracepoints.stp
+test_installcheck: stap vm.tracepoints.stp -c "sleep 10"
diff -rupaN a/testsuite/systemtap.examples/memory/vm.tracepoints.stp b/testsuite/systemtap.examples/memory/vm.tracepoints.stp
--- a/testsuite/systemtap.examples/memory/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
+++ b/testsuite/systemtap.examples/memory/vm.tracepoints.stp	2009-12-04 06:21:38.000000000 -0500
@@ -0,0 +1,18 @@
+global slabs
+
+probe vm.kmem_cache_alloc {
+	slabs [execname(), bytes_req]<<<1
+}
+
+probe timer.ms(10000)
+{
+	dummy = "";
+	foreach ([name, bytes] in slabs) {
+		if (dummy != name)
+			printf("\nProcess:%s\n", name);
+        	printf("Slab_size:%d\tCount:%d\n", bytes, @count(slabs[name, bytes]));
+		dummy = name;
+	}
+	delete slabs
+	printf("\n-------------------------------------------------------\n\n")
+}

Thanks
-- 
Rajasekhar Duddu (rajduddu@linux.vnet.ibm.com),
Linux on System z - CSVT, IBM LTC, Bangalore.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V6] Tracepoint Tapset for Memory Subsystem
  2009-12-11 18:36         ` [PATCH V6] " Rajasekhar Duddu
@ 2009-12-21 11:46           ` Prerna Saxena
  2009-12-21 21:49             ` Mark Wielaard
  2009-12-29 21:36           ` Mark Wielaard
  1 sibling, 1 reply; 10+ messages in thread
From: Prerna Saxena @ 2009-12-21 11:46 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

Hi Rajasekhar,

On 12/12/2009 12:05 AM, Rajasekhar Duddu wrote:
> Hi,
> 	I have corrected the typo error in this patch.
> If it is fine, please some body commit this pathc on behalf of me.
> Thanks in advance.
>

Committed to git (commit : 0c487e433fd6343e49b1e9dbc6492f38cfe26143)

Regards,
-- 
Prerna Saxena

Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V6] Tracepoint Tapset for Memory Subsystem
  2009-12-21 11:46           ` Prerna Saxena
@ 2009-12-21 21:49             ` Mark Wielaard
  2009-12-22 17:02               ` Prerna Saxena
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Wielaard @ 2009-12-21 21:49 UTC (permalink / raw)
  To: Prerna Saxena; +Cc: Rajasekhar Duddu, systemtap

On Mon, 2009-12-21 at 17:16 +0530, Prerna Saxena wrote:
> On 12/12/2009 12:05 AM, Rajasekhar Duddu wrote:
> > 	I have corrected the typo error in this patch.
> > If it is fine, please some body commit this pathc on behalf of me.
> > Thanks in advance.
> >
> 
> Committed to git (commit : 0c487e433fd6343e49b1e9dbc6492f38cfe26143)

This commit only added the new examples and tests, but omitted the
changes to the existing files NEWS and tapset/memory.stp. Could these
also be added?

Thanks,

Mark

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V6] Tracepoint Tapset for Memory Subsystem
  2009-12-21 21:49             ` Mark Wielaard
@ 2009-12-22 17:02               ` Prerna Saxena
  0 siblings, 0 replies; 10+ messages in thread
From: Prerna Saxena @ 2009-12-22 17:02 UTC (permalink / raw)
  To: Mark Wielaard; +Cc: Rajasekhar Duddu, systemtap

On 12/22/2009 03:19 AM, Mark Wielaard wrote:
> On Mon, 2009-12-21 at 17:16 +0530, Prerna Saxena wrote:
>> On 12/12/2009 12:05 AM, Rajasekhar Duddu wrote:
>>> 	I have corrected the typo error in this patch.
>>> If it is fine, please some body commit this pathc on behalf of me.
>>> Thanks in advance.
>>>
>>
>> Committed to git (commit : 0c487e433fd6343e49b1e9dbc6492f38cfe26143)
>
> This commit only added the new examples and tests, but omitted the
> changes to the existing files NEWS and tapset/memory.stp. Could these
> also be added?
>
> Thanks,
>
> Mark
>
Thanks mark, this has been fixed in commit 
d5d6f6f18b4ed3e2cd02b6a6a0740938582df89b

-- 
Prerna Saxena

Linux Technology Centre,
IBM Systems and Technology Lab,
Bangalore, India

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V6] Tracepoint Tapset for Memory Subsystem
  2009-12-11 18:36         ` [PATCH V6] " Rajasekhar Duddu
  2009-12-21 11:46           ` Prerna Saxena
@ 2009-12-29 21:36           ` Mark Wielaard
  1 sibling, 0 replies; 10+ messages in thread
From: Mark Wielaard @ 2009-12-29 21:36 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

Hi Rajasekhar,

On Sat, 2009-12-12 at 00:05 +0530, Rajasekhar Duddu wrote:
> Changelog 3:
>         Defined two macros for converting the GFP_FLAGS into string
> formats.
>         Added k(ret)probe based fallback probes for all the
> Functions.

Sorry for the late feedback. I finally tested on an old 2.6.18 kernel
which didn't have the tracepoints defined. I made a couple of changes to
the fallback probes to make them work (a bit). I agree with Wenji that
having bytes_alloc be sometimes a long and sometimes a string is not
very helpful. So I made it a long always by setting it to the same value
as bytes_req. That isn't ideal, but better than having the type
mismatch. I couldn't find a good solution for the vm.kmalloc fallback,
since the function is always inlined, the return probe won't really work
(I pulled that test out of the other buildok/vm.tracepoints.stp to show
the rest does build now). Maybe someone knows a trick to get this
fallback to also work. But maybe we should just encourage people to
upgrade their kernel to one that has the tracepoints defined.

Cheers,

Mark

commit 11c015d84facc299ebcb12771ccda1975333a6bc
Author: Mark Wielaard <mjw@redhat.com>
Date:   Tue Dec 29 21:05:55 2009 +0100

  Fixup some memory tapset vm kernel function probe fallbacks.
    
  Older kernels don't have all GFP constants defined, and the fallback
  kernel function probe fallbacks don't have the same dwarf variable
  names as the kernel trace point probes. So replace them with variables
  that are available. bytes_alloc was sometimes a long and sometimes a
  string, this caused scripts to fail depending on which alternative was
  chosen for a particular kernel. So make it a long always.
  This isn't a full solution since kmalloc is always inlined which makes
  the kernel.function("kmalloc").return probe fail.
  
  * tapset/memory.stp: Define __GFP_THISNODE, __GFP_RECLAIMABLE,
    GFP_TEMPORARY, GFP_HIGHUSER_MOVABLE and GFP_THISNODE when not yet
    defined.
    (__vm.kmalloc.kp): Use $flags, not $gfp_flags. Set bytes_alloc equal
    to bytes_req.
    (__vm.kmem_cache_alloc.kp): Likewise. And use $cachep->buffer_size
    for bytes_req.
    (__vm.kmalloc_node.kp): Likewise.
    (__vm.kmem_cache_alloc_node.kp): Likewise.
    (__vm.kfree.kp): Use $ibjp for ptr, not $return.
    (__vm.kmem_cache_free.kp): Likewise.
  * testsuite/buildok/vm.tracepoints.stp: Move vm.kmalloc test to...
  * testsuite/buildok/vm.tracepoints.kmalloc.stp: ... here.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-12-29 21:36 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-25  9:31 [PATCH V4] Tracepoint Tapset for Memory Subsystem Rajasekhar Duddu
2009-11-30 16:26 ` Frank Ch. Eigler
2009-12-04 12:09   ` [PATCH V5] " Rajasekhar Duddu
2009-12-07  2:52     ` Wenji Huang
2009-12-09  6:57       ` Rajasekhar Duddu
2009-12-11 18:36         ` [PATCH V6] " Rajasekhar Duddu
2009-12-21 11:46           ` Prerna Saxena
2009-12-21 21:49             ` Mark Wielaard
2009-12-22 17:02               ` Prerna Saxena
2009-12-29 21:36           ` Mark Wielaard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).