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


Hi all,
	here I am sending the updated patch based on all the
previous comments. Please review it and let me know if it needs any
more improvemnts.

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.


Sample O/P:

stapio          0x0000000230168 0x0000000000230168 0x00000a1eed018
24              24              80              GFP_NOFS
kmem_cache_alloc
sendmail        0x0000000153ed8 0x0000000000153ed8 0x00000b28a8000
4096            4096            208             GFP_KERNEL
kmem_cache_alloc
sendmail        0x000000014740a 0x000000000014740a 0x00000b572ba00
256             256             32976           __GFP_WAIT |
__GFP_IO | __GFP_FS | __GFP_ZERO
kmem_cache_alloc
sendmail        0x0000000271de0 0x0000000000271de0 0x00000bca09af0
16              16              32976           __GFP_WAIT |
__GFP_IO | __GFP_FS | __GFP_ZERO
kmalloc
sendmail        0x0000000271d90 0x0000000000271d90 0x00000bca09af0
16              16              32976           __GFP_WAIT |
__GFP_IO | __GFP_FS | __GFP_ZERO
kmem_cache_alloc
sendmail        0x000000015ef38 0x000000000015ef38 0x00000ada220c0
192             192             208             GFP_KERNEL
kmem_cache_alloc
sendmail        0x00000001b35a6 0x00000000001b35a6 0x00000bbae6540
640             648             208             GFP_KERNEL
kmem_cache_alloc
sendmail        0x0000000277264 0x0000000000277264 0x00000b9c03e10
72              72              32848           __GFP_WAIT |
__GFP_IO | __GFP_ZERO
kmem_cache_alloc
sendmail        0x00000001b368c 0x00000000001b368c 0x00000b7e69dc0
64              64              208             GFP_KERNEL
kmalloc

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-09-30 06:14:29.000000000 -0400
+++ b/tapset/memory.stp	2009-10-16 07:06:54.000000000 -0400
@@ -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) %{
+	int gfp_flag = (int)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($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($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($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($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-10-16 01:19:26.000000000 -0400
@@ -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)
+}


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

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

* Re: [PATCH V3] Tracepoint Tapset for Memory Subsystem
  2009-11-09  7:10 [PATCH V3] Tracepoint Tapset for Memory Subsystem Rajasekhar Duddu
@ 2009-11-09 17:02 ` Frank Ch. Eigler
  0 siblings, 0 replies; 9+ messages in thread
From: Frank Ch. Eigler @ 2009-11-09 17:02 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

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

> Hi all,
> 	here I am sending the updated patch based on all the
> previous comments. Please review it and let me know if it needs any
> more improvemnts. [...]

I didn't see anything objectionable in a quick scan.  I would like to
see a demo script (systemtap.examples/*) that somehow goes beyond just
tracing individual calls (like the buildok test).

- FChE

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-10-09 17:38                       ` Frank Ch. Eigler
@ 2009-10-14  8:32                         ` Rajasekhar Duddu
  0 siblings, 0 replies; 9+ messages in thread
From: Rajasekhar Duddu @ 2009-10-14  8:32 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: systemtap

On Fri, Oct 09, 2009 at 01:38:06PM -0400, Frank Ch. Eigler wrote:
> Hi -
> 
> On Fri, Oct 09, 2009 at 10:38:05PM +0530, Rajasekhar Duddu wrote:
> > [...]
> > > > Fallback kprobe is not available for other memory functions because
> > > > the variables exported by them are will be modified.
> > > 
> > > Could you elaborate?  Do you mean that the same values may not be
> > > available from a kprobe context?
> 
> > 	 Yes, the same values may not be available from a kprobe
> > context, for example if we take "ret" variable as it is populated mid-way in
> > the  function and it is also the return value of a function which can
> > be captured only by a return probe. But by a return probe we cannot
> > capture the formal parameters of the memory function.
> 
> Actually, we often can.  $variables accessed in .function().return context 
> are exactly snapshots of the incoming actual arguments.
> 
> So for example the trace_kmalloc() case, we could have a
> k(ret)probes-based fallback based upon inspection of the sources,
> and unwinding through the "__always_inline" stuff:
> 
> probe __vm.kmalloc.kp = kernel.function("__kmalloc").return {
>     name = "kmalloc"
>     call_size = 0
>     caller_function = ""
>     bytes_req = $size
>     bytes_alloc = bytes_req # unavailable
>     gfp_flags = gfp_flag_str($flags)
>     ptr = $return
> }
> 
> Based on CONFIG_NUMA (which we can now express preprocessor
> conditionals on), there may be a _node variant, plus _track_caller
> variants.  All this can be expressed with some effort.
> 
> 
> - FChE

Hi Frank,
	sure , I will try to have the kprobe based probes with all
possible parameters exported in my next patch.

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

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-10-09 17:08                     ` Rajasekhar Duddu
@ 2009-10-09 17:38                       ` Frank Ch. Eigler
  2009-10-14  8:32                         ` Rajasekhar Duddu
  0 siblings, 1 reply; 9+ messages in thread
From: Frank Ch. Eigler @ 2009-10-09 17:38 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

Hi -

On Fri, Oct 09, 2009 at 10:38:05PM +0530, Rajasekhar Duddu wrote:
> [...]
> > > Fallback kprobe is not available for other memory functions because
> > > the variables exported by them are will be modified.
> > 
> > Could you elaborate?  Do you mean that the same values may not be
> > available from a kprobe context?

> 	 Yes, the same values may not be available from a kprobe
> context, for example if we take "ret" variable as it is populated mid-way in
> the  function and it is also the return value of a function which can
> be captured only by a return probe. But by a return probe we cannot
> capture the formal parameters of the memory function.

Actually, we often can.  $variables accessed in .function().return context 
are exactly snapshots of the incoming actual arguments.

So for example the trace_kmalloc() case, we could have a
k(ret)probes-based fallback based upon inspection of the sources,
and unwinding through the "__always_inline" stuff:

probe __vm.kmalloc.kp = kernel.function("__kmalloc").return {
    name = "kmalloc"
    call_size = 0
    caller_function = ""
    bytes_req = $size
    bytes_alloc = bytes_req # unavailable
    gfp_flags = gfp_flag_str($flags)
    ptr = $return
}

Based on CONFIG_NUMA (which we can now express preprocessor
conditionals on), there may be a _node variant, plus _track_caller
variants.  All this can be expressed with some effort.


- FChE

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-10-07 19:51                   ` Frank Ch. Eigler
@ 2009-10-09 17:08                     ` Rajasekhar Duddu
  2009-10-09 17:38                       ` Frank Ch. Eigler
  0 siblings, 1 reply; 9+ messages in thread
From: Rajasekhar Duddu @ 2009-10-09 17:08 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: systemtap

On Wed, Oct 07, 2009 at 03:51:07PM -0400, Frank Ch. Eigler wrote:
> Rajasekhar Duddu <rajduddu@linux.vnet.ibm.com> writes:
> 
> > [...]
> >> Nice.  I thought that the raison d'etre for these aliases was to
> >> abstract the presence or absence of tracepoints, so is there no
> >> fallback kprobe available?  Something like this:
> >> 
> > Fallback kprobe is not available for other memory functions because
> > the variables exported by them are will be modified.
> 
> Could you elaborate?  Do you mean that the same values may not be
> available from a kprobe context?
> 
>
Hi Frank,
	 Yes, the same values may not be available from a kprobe
context, for example if we take "ret" variable as it is populated mid-way in
the  function and it is also the return value of a function which can
be captured only by a return probe. But by a return probe we cannot
capture the formal parameters of the memory function.
 

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

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-10-07 13:07                 ` Rajasekhar Duddu
@ 2009-10-07 19:51                   ` Frank Ch. Eigler
  2009-10-09 17:08                     ` Rajasekhar Duddu
  0 siblings, 1 reply; 9+ messages in thread
From: Frank Ch. Eigler @ 2009-10-07 19:51 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

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

> [...]
>> Nice.  I thought that the raison d'etre for these aliases was to
>> abstract the presence or absence of tracepoints, so is there no
>> fallback kprobe available?  Something like this:
>> 
> Fallback kprobe is not available for other memory functions because
> the variables exported by them are will be modified.

Could you elaborate?  Do you mean that the same values may not be
available from a kprobe context?


- FChE

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-10-06 19:01               ` Frank Ch. Eigler
@ 2009-10-07 13:07                 ` Rajasekhar Duddu
  2009-10-07 19:51                   ` Frank Ch. Eigler
  0 siblings, 1 reply; 9+ messages in thread
From: Rajasekhar Duddu @ 2009-10-07 13:07 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: systemtap

Hi Frank, 
	thanks for your comments. I am answering for your
questions here and in my next patch I will apply all the possible
changes. 

On Tue, Oct 06, 2009 at 03:01:09PM -0400, Frank Ch. Eigler wrote:
> Rajasekhar Duddu <rajduddu@linux.vnet.ibm.com> writes:
> 
> > [...]
> > +/* Function to convert the GFP_FLAGS . */
> > +
> > +function gfp_flag_str:string (gfp_flag:long)
> > +%{
> > +int flags = (int)THIS->gfp_flag;
> > +THIS->__retvalue[0] = '\0';
> > +
> > +#ifdef __GFP_HIGH
> > +        if (flags & __GFP_HIGH)
> > +                strlcat (THIS->__retvalue, "GFP_HIGH",MAXSTRINGLEN);
> > +#endif
> > +
> > +#ifdef __GFP_WAIT
> > +        if (flags & __GFP_WAIT)
> > +                strlcat (THIS->__retvalue, "GFP_WAIT",MAXSTRINGLEN);
> > +#endif
> > +
> > +#ifdef __GFP_IO
> > +        if (flags & __GFP_IO)
> > +                strlcat (THIS->__retvalue, "|GFP_IO",MAXSTRINGLEN);
> > +#endif
> 
> Why no "|" before GFP_HIGH/GFP_WAIT?

All the other Flags (except GFP_WAIT/GFP_HIGH) are composition of 
one or the other Flags, and the composition starts with either
GFP_HIGH or GFP_WAIT, so there is no "|" before GFP_HIGH/GFP_WAIT.

> Also, why no "__" before the stringified version?
This I will apply in the next patch.
> 
> 
> > +#ifdef __GFP_FS
> > +        if (flags & __GFP_FS)
> > +                strlcat (THIS->__retvalue, "|GFP_FS",MAXSTRINGLEN);
> > +#endif
> 
> (How about a macro to generate all these near-identical branches?)
> 
> 
Sure I will have macro something like this:
%{

#define FLAG_TEST(TYPE)  if (flags & TYPE) { strlcat \
(THIS->__retvalue, #TYPE,MAXSTRINGLEN); }

%}

and I will use that in my gfp_flag_str as fallowing.

#ifdef __GFP_HIGH
        FLAG_TEST(__GFP_HIGH);
#endif

> > +%}
> 
> 
> > +/**
> > + * probe vm.kmalloc - Fires when <command>kmalloc</command> is requested.
> > + * @call_site: Address of the caller function.
> > + * @caller_function: Name of the caller function.
> > + * @bytes_req: Requested Bytes
> > + * @bytes_alloc: Allocated Bytes
> > + * @gfp_flags: type of kmemory to allocate
> > + * @ptr: Pointer to the kmemory allocated
> > + */
> > +
> > +probe vm.kmalloc = 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_flag_str($gfp_flags)
> > +	ptr = $ptr
> > +}
> 
> Nice.  I thought that the raison d'etre for these aliases was to
> abstract the presence or absence of tracepoints, so is there no
> fallback kprobe available?  Something like this:
> 
Fallback kprobe is not available for other memory functions because
the variables exported by them are will be modified.
> 
> > +probe __vm.kfree.kp = kernel.function("kfree") {
> > +	name = "kfree"
> > +	call_site = "0"
> 
> (Note though that this will fail type checking on a non-tracepoint
> kernel -- have you tried it? -- it should be just 0 instead of "0".)
> 
This also I will apply in my next patch.
> > +	caller_function = "unknown"
> > +	ptr = $x
> > +}
> > +
> > +probe __vm.kfree.tp = kernel.trace("kfree") {
> > +	name = "kfree"
> > +	call_site = $call_site
> > +	caller_function = symname(call_site)
> > +	ptr = $ptr
> > +}
> > +
> > +/**
> > + * probe vm.kfree - Fires when <command>kfree</comand> is requested.
> > + * @call_site: Address of the caller function (displayed if available)
> > + * @caller_function - Name of the caller function (displayed if available)
> > + * @ptr: Pointer to the kmemory allocated which is returned by kmalloc
> > + */
> > +probe vm.kfree = __vm.kfree.tp !,
> > +		   __vm.kfree.kp
> > +{}
> 
> Right.
> 
> 
> > +/**
> > + * probe vm.kmalloc_node - Fires when <command>kmalloc_node</command> is requested.
> > + * @call_site: Address of the caller function.
> > + * @caller_function: Name of the caller function.
> > + * @bytes_req: Requested Bytes
> > + * @bytes_alloc: Allocated Bytes
> > + * @gfp_flags: Type of kmemory to allocate
> > + * @ptr: Pointer to the kmemory allocated
> > + */
> 
> Please, no "<command>" markup in there, it is not valid.
> 
This I will cange in my next patch.
> 
> > +probe vm.kmalloc_node = kernel.trace("kmalloc_node")? {
> > [...]
> 
> Why is this marked with "?"?

Kmalloc_node will be called when "CONFIG_NUMA" is defined, so I have
used "?" to make it an optional.
> 
> 
> > --- a/testsuite/buildok/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
> > +++ b/testsuite/buildok/vm.tracepoints.stp	2009-10-02 10:59:20.000000000 -0400
> > @@ -0,0 +1,32 @@
> > +#!/usr/bin/stp -up4
> 
> Other similar test cases just use
> 
> #! stap -up4
> 
This also I will change in my next patch.
> 

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

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-10-02 15:14             ` [PATCH v3] " Rajasekhar Duddu
@ 2009-10-06 19:01               ` Frank Ch. Eigler
  2009-10-07 13:07                 ` Rajasekhar Duddu
  0 siblings, 1 reply; 9+ messages in thread
From: Frank Ch. Eigler @ 2009-10-06 19:01 UTC (permalink / raw)
  To: Rajasekhar Duddu; +Cc: systemtap

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

> [...]
> +/* Function to convert the GFP_FLAGS . */
> +
> +function gfp_flag_str:string (gfp_flag:long)
> +%{
> +int flags = (int)THIS->gfp_flag;
> +THIS->__retvalue[0] = '\0';
> +
> +#ifdef __GFP_HIGH
> +        if (flags & __GFP_HIGH)
> +                strlcat (THIS->__retvalue, "GFP_HIGH",MAXSTRINGLEN);
> +#endif
> +
> +#ifdef __GFP_WAIT
> +        if (flags & __GFP_WAIT)
> +                strlcat (THIS->__retvalue, "GFP_WAIT",MAXSTRINGLEN);
> +#endif
> +
> +#ifdef __GFP_IO
> +        if (flags & __GFP_IO)
> +                strlcat (THIS->__retvalue, "|GFP_IO",MAXSTRINGLEN);
> +#endif

Why no "|" before GFP_HIGH/GFP_WAIT?
Also, why no "__" before the stringified version?


> +#ifdef __GFP_FS
> +        if (flags & __GFP_FS)
> +                strlcat (THIS->__retvalue, "|GFP_FS",MAXSTRINGLEN);
> +#endif

(How about a macro to generate all these near-identical branches?)


> +%}


> +/**
> + * probe vm.kmalloc - Fires when <command>kmalloc</command> is requested.
> + * @call_site: Address of the caller function.
> + * @caller_function: Name of the caller function.
> + * @bytes_req: Requested Bytes
> + * @bytes_alloc: Allocated Bytes
> + * @gfp_flags: type of kmemory to allocate
> + * @ptr: Pointer to the kmemory allocated
> + */
> +
> +probe vm.kmalloc = 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_flag_str($gfp_flags)
> +	ptr = $ptr
> +}

Nice.  I thought that the raison d'etre for these aliases was to
abstract the presence or absence of tracepoints, so is there no
fallback kprobe available?  Something like this:


> +probe __vm.kfree.kp = kernel.function("kfree") {
> +	name = "kfree"
> +	call_site = "0"

(Note though that this will fail type checking on a non-tracepoint
kernel -- have you tried it? -- it should be just 0 instead of "0".)

> +	caller_function = "unknown"
> +	ptr = $x
> +}
> +
> +probe __vm.kfree.tp = kernel.trace("kfree") {
> +	name = "kfree"
> +	call_site = $call_site
> +	caller_function = symname(call_site)
> +	ptr = $ptr
> +}
> +
> +/**
> + * probe vm.kfree - Fires when <command>kfree</comand> is requested.
> + * @call_site: Address of the caller function (displayed if available)
> + * @caller_function - Name of the caller function (displayed if available)
> + * @ptr: Pointer to the kmemory allocated which is returned by kmalloc
> + */
> +probe vm.kfree = __vm.kfree.tp !,
> +		   __vm.kfree.kp
> +{}

Right.


> +/**
> + * probe vm.kmalloc_node - Fires when <command>kmalloc_node</command> is requested.
> + * @call_site: Address of the caller function.
> + * @caller_function: Name of the caller function.
> + * @bytes_req: Requested Bytes
> + * @bytes_alloc: Allocated Bytes
> + * @gfp_flags: Type of kmemory to allocate
> + * @ptr: Pointer to the kmemory allocated
> + */

Please, no "<command>" markup in there, it is not valid.


> +probe vm.kmalloc_node = kernel.trace("kmalloc_node")? {
> [...]

Why is this marked with "?"?


> --- a/testsuite/buildok/vm.tracepoints.stp	1969-12-31 19:00:00.000000000 -0500
> +++ b/testsuite/buildok/vm.tracepoints.stp	2009-10-02 10:59:20.000000000 -0400
> @@ -0,0 +1,32 @@
> +#!/usr/bin/stp -up4

Other similar test cases just use

#! stap -up4



- FChE

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

* Re: [PATCH v3] Tracepoint Tapset for Memory Subsystem
  2009-09-30 10:12           ` Rajasekhar Duddu
@ 2009-10-02 15:14             ` Rajasekhar Duddu
  2009-10-06 19:01               ` Frank Ch. Eigler
  0 siblings, 1 reply; 9+ messages in thread
From: Rajasekhar Duddu @ 2009-10-02 15:14 UTC (permalink / raw)
  To: systemtap


Hi, 
	Thanks for all those who had sent their comments.
I have modified the patch according to the comments passed.


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-09-30 06:14:29.000000000 -0400
+++ b/tapset/memory.stp	2009-10-02 11:05:10.000000000 -0400
@@ -195,3 +195,209 @@ probe vm.brk = kernel.function("do_brk")
 probe vm.oom_kill = kernel.function("__oom_kill_task") {
     task = $p
 }
+/* Function to convert the GFP_FLAGS . */
+
+function gfp_flag_str:string (gfp_flag:long)
+%{
+int flags = (int)THIS->gfp_flag;
+THIS->__retvalue[0] = '\0';
+
+#ifdef __GFP_HIGH
+        if (flags & __GFP_HIGH)
+                strlcat (THIS->__retvalue, "GFP_HIGH",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_WAIT
+        if (flags & __GFP_WAIT)
+                strlcat (THIS->__retvalue, "GFP_WAIT",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_IO
+        if (flags & __GFP_IO)
+                strlcat (THIS->__retvalue, "|GFP_IO",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_FS
+        if (flags & __GFP_FS)
+                strlcat (THIS->__retvalue, "|GFP_FS",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_COLD
+        if (flags & __GFP_COLD)
+                strlcat (THIS->__retvalue, "|GFP_COLD",MAXSTRINGLEN);
+#endif
+#ifdef __GFP_NOWARN
+        if (flags & __GFP_NOWARN)
+                strlcat (THIS->__retvalue, "|GFP_NOWARN",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_REPEAT
+        if (flags & __GFP_REPEAT)
+                strlcat (THIS->__retvalue, "|GFP_REPEAT",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_NOFAIL
+        if (flags & __GFP_NOFAIL)
+                strlcat (THIS->__retvalue, "|GFP_NOFAIL",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_NORETRY
+        if (flags & __GFP_NORETRY)
+                strlcat (THIS->__retvalue, "|GFP_NORETRY",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_COMP
+        if (flags & __GFP_COMP)
+                strlcat (THIS->__retvalue, "|GFP_COMP",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_ZERO
+        if (flags & __GFP_ZERO)
+                strlcat (THIS->__retvalue, "|GFP_ZERO",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_NOMEMALLOC
+        if (flags & __GFP_NOMEMALLOC)
+                strlcat (THIS->__retvalue, "|GFP_NOMEMALLOC",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_HARDWALL
+        if (flags & __GFP_HARDWALL)
+                strlcat (THIS->__retvalue, "|GFP_HARDWALL",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_THISNODE
+        if (flags & __GFP_THISNODE)
+                strlcat (THIS->__retvalue, "|GFP_THISNODE",MAXSTRINGLEN);
+#endif
+
+#ifdef __GFP_RECLAIMABLE
+        if (flags & __GFP_RECLAIMABLE)
+                strlcat (THIS->__retvalue, "|GFP_RECLAIMABLE",MAXSTRINGLEN);
+#endif
+
+
+#ifdef __GFP_NOTRACK
+        if (flags & __GFP_NOTRACK)
+                strlcat (THIS->__retvalue, "|GFP_NOTRACK",MAXSTRINGLEN);
+#endif
+%}
+
+
+/**
+ * probe vm.kmalloc - Fires when <command>kmalloc</command> is requested.
+ * @call_site: Address of the caller function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: type of kmemory to allocate
+ * @ptr: Pointer to the kmemory allocated
+ */
+
+probe vm.kmalloc = 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_flag_str($gfp_flags)
+	ptr = $ptr
+}
+
+/**
+ * probe vm.kmem_cache_alloc - Fires when \
+ *		<command>kmem_cache_alloc</command> is requested.
+ * @call_site: Address of the caller function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: Type of kmemory to allocate
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmem_cache_alloc = 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_flag_str($gfp_flags)
+        ptr = $ptr
+}
+
+
+/**
+ * probe vm.kmalloc_node - Fires when <command>kmalloc_node</command> is requested.
+ * @call_site: Address of the caller function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: Type of kmemory to allocate
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmalloc_node = 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_flag_str($gfp_flags)
+        ptr = $ptr
+}
+
+/**
+ * probe vm.kmem_cache_alloc_node - Fires when \
+ *		<command>kmem_cache_alloc_node</command> is requested.
+ * @call_site: Address of the caller function.
+ * @caller_function: Name of the caller function.
+ * @bytes_req: Requested Bytes
+ * @bytes_alloc: Allocated Bytes
+ * @gfp_flags: Type of kmemory to allocate
+ * @ptr: Pointer to the kmemory allocated
+ */
+probe vm.kmem_cache_alloc_node = 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_flag_str($gfp_flags)
+        ptr = $ptr
+}
+
+probe __vm.kfree.kp = kernel.function("kfree") {
+	name = "kfree"
+	call_site = "0"
+	caller_function = "unknown"
+	ptr = $x
+}
+
+probe __vm.kfree.tp = kernel.trace("kfree") {
+	name = "kfree"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
+
+/**
+ * probe vm.kfree - Fires when <command>kfree</comand> is requested.
+ * @call_site: Address of the caller function (displayed if available)
+ * @caller_function - Name of the caller function (displayed if available)
+ * @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 - Fires when \
+ *		<command>kmem_cache_free</command> is requested.
+ * @call_site: Address of the caller 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 = kernel.trace("kmem_cache_free") {
+	name = "kmem_cache_free"
+	call_site = $call_site
+	caller_function = symname(call_site)
+	ptr = $ptr
+}
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-10-02 10:59:20.000000000 -0400
@@ -0,0 +1,32 @@
+#!/usr/bin/stp -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 %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags)
+}
+
+probe vm.kmem_cache_alloc {
+                println (name)
+                printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags)
+}
+probe vm.kmalloc_node {
+                println (name)
+                printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags)
+}
+
+probe vm.kmem_cache_alloc_node {
+                println (name)
+                printf("%-15s %-15p %-15s %-15p %-15d %-15d %-15s \n", execname(), call_site, caller_function, ptr, bytes_req, bytes_alloc, gfp_flags)
+}
+
+probe vm.kmem_cache_free {
+                println (name)
+                printf("%-15s %-15p %-15s %-15p \n", execname(), call_site, caller_function, ptr)
+}
+
+

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

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

end of thread, other threads:[~2009-11-09 17:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-09  7:10 [PATCH V3] Tracepoint Tapset for Memory Subsystem Rajasekhar Duddu
2009-11-09 17:02 ` Frank Ch. Eigler
  -- strict thread matches above, loose matches on Subject: below --
2009-09-19  5:01 [PATCH] " Rajasekhar Duddu
2009-09-22 17:39 ` David Smith
2009-09-22 21:23   ` Frank Ch. Eigler
2009-09-22 22:05     ` David Smith
2009-09-24 18:08       ` [PATCH v2] " Rajasekhar Duddu
2009-09-25 21:50         ` Josh Stone
2009-09-30 10:12           ` Rajasekhar Duddu
2009-10-02 15:14             ` [PATCH v3] " Rajasekhar Duddu
2009-10-06 19:01               ` Frank Ch. Eigler
2009-10-07 13:07                 ` Rajasekhar Duddu
2009-10-07 19:51                   ` Frank Ch. Eigler
2009-10-09 17:08                     ` Rajasekhar Duddu
2009-10-09 17:38                       ` Frank Ch. Eigler
2009-10-14  8:32                         ` 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).