* [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).