* Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
[not found] <449125467.1554931259945048608.JavaMail.root@zmail02.collab.prod.int.phx2.redhat.com>
@ 2009-12-04 17:11 ` David Smith
2009-12-09 6:59 ` Rajasekhar Duddu
0 siblings, 1 reply; 5+ messages in thread
From: David Smith @ 2009-12-04 17:11 UTC (permalink / raw)
To: Rajasekhar Duddu; +Cc: systemtap
One really minor comment below.
> ----- Original Message -----
> From: "Rajasekhar Duddu" <rajduddu@linux.vnet.ibm.com>
> To: systemtap@sources.redhat.com
> Sent: Friday, December 4, 2009 6:08:19 AM GMT -06:00 US/Canada Central
> Subject: Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
>
>
> 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.
>
>
> +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. */
Typo here - 'kporbe' should be 'kprobe'.
--
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
2009-12-04 17:11 ` [PATCH V5] Tracepoint Tapset for Memory Subsystem David Smith
@ 2009-12-09 6:59 ` Rajasekhar Duddu
0 siblings, 0 replies; 5+ messages in thread
From: Rajasekhar Duddu @ 2009-12-09 6:59 UTC (permalink / raw)
To: David Smith; +Cc: systemtap
On Fri, Dec 04, 2009 at 12:11:33PM -0500, David Smith wrote:
> One really minor comment below.
>
> > ----- Original Message -----
> > From: "Rajasekhar Duddu" <rajduddu@linux.vnet.ibm.com>
> > To: systemtap@sources.redhat.com
> > Sent: Friday, December 4, 2009 6:08:19 AM GMT -06:00 US/Canada Central
> > Subject: Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem
> >
> >
> > 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.
> >
> >
> > +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. */
>
> Typo here - 'kporbe' should be 'kprobe'.
>
Thanks David,
I will correct it in my next patch.
--
Rajasekhar Duddu (rajduddu@linux.vnet.ibm.com),
Linux on System z - CSVT, IBM LTC, Bangalore.
^ permalink raw reply [flat|nested] 5+ messages in thread
* [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; 5+ 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] 5+ messages in thread
* Re: [PATCH V4] Tracepoint Tapset for Memory Subsystem
2009-11-25 9:31 [PATCH V4] " Rajasekhar Duddu
@ 2009-11-30 16:26 ` Frank Ch. Eigler
2009-12-04 12:09 ` [PATCH V5] " Rajasekhar Duddu
0 siblings, 1 reply; 5+ 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] 5+ 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; 5+ 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] 5+ 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; 5+ 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] 5+ 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
0 siblings, 0 replies; 5+ 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] 5+ messages in thread
end of thread, other threads:[~2009-12-09 6:59 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <449125467.1554931259945048608.JavaMail.root@zmail02.collab.prod.int.phx2.redhat.com>
2009-12-04 17:11 ` [PATCH V5] Tracepoint Tapset for Memory Subsystem David Smith
2009-12-09 6:59 ` Rajasekhar Duddu
2009-11-25 9:31 [PATCH V4] " 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
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).