From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30474 invoked by alias); 4 Dec 2009 12:09:56 -0000 Received: (qmail 30464 invoked by uid 22791); 4 Dec 2009 12:09:53 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from e23smtp01.au.ibm.com (HELO e23smtp01.au.ibm.com) (202.81.31.143) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 04 Dec 2009 12:08:28 +0000 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [202.81.31.246]) by e23smtp01.au.ibm.com (8.14.3/8.13.1) with ESMTP id nB4C6j2c020684 for ; Fri, 4 Dec 2009 23:06:45 +1100 Received: from d23av01.au.ibm.com (d23av01.au.ibm.com [9.190.234.96]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id nB4C4iXe1470494 for ; Fri, 4 Dec 2009 23:04:46 +1100 Received: from d23av01.au.ibm.com (loopback [127.0.0.1]) by d23av01.au.ibm.com (8.14.3/8.13.1/NCO v10.0 AVout) with ESMTP id nB4C8M6Z028229 for ; Fri, 4 Dec 2009 23:08:22 +1100 Received: from localhost ([9.124.33.100]) by d23av01.au.ibm.com (8.14.3/8.13.1/NCO v10.0 AVin) with ESMTP id nB4C8LIj028146 for ; Fri, 4 Dec 2009 23:08:21 +1100 Date: Fri, 04 Dec 2009 12:09:00 -0000 From: Rajasekhar Duddu To: systemtap@sources.redhat.com Subject: Re: [PATCH V5] Tracepoint Tapset for Memory Subsystem Message-ID: <20091204120819.GA14359@rajduddu> References: <20091125093051.GA13363@rajduddu> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.18 (2008-05-17) X-IsSubscribed: yes Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org X-SW-Source: 2009-q4/txt/msg00802.txt.bz2 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 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.