Re: [RFC/PATCHSET 00/15] perf report: Add support to accumulate hist periods

2012-10-30 Thread Namhyung Kim
Hi Arun and Peter,

On Mon, 29 Oct 2012 14:36:01 -0700, Arun Sharma wrote:
 On 10/29/12 12:08 PM, Peter Zijlstra wrote:

 Right, so I tried this and I would expect the callchains to be inverted
 too, so that when I expand say 'c' I would see that 'c' calls 'b' for
 100% which calls 'a' for 100%.

 Instead I get the regular callchains, expanding 'c' gives me main calls
 it for 100%.

 Adding -G (invert callchains) doesn't make it better, in that case, when
 I expand 'c' we start at '__libc_start_main' instead of 'c'.

 Is there anything I'm missing?


 Sounds like a reasonable expectation.

 I tested mainly:

 perf report --cumulate  -g graph,100,callee

 to find the functions with a large amount of CPU time underneath. Then
 examined the callgraph without --cumulate. But yeah - it'd be nice to
 be able to do both in a single invocation.

Yes, the callchain part needs to be improved.  Peter's idea indeed looks
good to me too.

But before doing that, I'd like to get an agreement on how to
design/implement this feature.

Sorry to Frederic (and Stephane), I'm bothering you multiple times with
this but I didn't get what you want exactly.  IIUC you don't want to
have --cumulate option but to share branch sampling code to implement
it, right?

But the branch sampling output looks not fit to --cumulate usage IMHO.
Could you give me an advice?


 Also, when callgraphs are displayed, the percentages are off (
 100%). Namhyung probably needs to use he-stat_acc-period in a few
 places as the denominator instead of he-period.

I will look into it later.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/9] perf python: add ui stubs file

2012-10-30 Thread Namhyung Kim
Hi David,

On Mon, 29 Oct 2012 10:31:41 -0600, David Ahern wrote:
 stdio based implementations of ui_ based functions for the python
 library. Needed for patch 3 - consolidating open counters method.

How about adding ui/util.c to the python-ext-sources?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/9] perf top: make use of perf_record_opts

2012-10-30 Thread Namhyung Kim
On Mon, 29 Oct 2012 10:31:42 -0600, David Ahern wrote:
 Changes top code to use the perf_record_opts struct. Stepping stone to
 consolidating the open counters code.

Maybe time to rename perf_record_opts to perf_open_opts or just perf_opts?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [BUG] perf report: different reports when run on terminal as opposed to script

2012-10-30 Thread Namhyung Kim
Hi Dhaval,

On Mon, 29 Oct 2012 12:45:53 -0400, Dhaval Giani wrote:
 On Mon, Oct 29, 2012 at 12:01 PM, Dhaval Giani dhaval.gi...@gmail.com wrote:
 Hi,

 As part of a class assignment I have to collect some performance
 statistics. In order to do so I run

 perf record -g the program I have to profile

 And in another window, I start 200 threads of the load generator
 (which is not recorded by perf)

 This generates me statistics that I expect to see, and I am happy. As
 this is academia and a class assignment, I need to collect information
 and analyze it across different setups. Which of course meant I script
 this whole thing, which basically is

 for i in all possibilities
 do
 perf record -g the program I have to profile 
 WAITPID=$!
 for j in NR_THREADS
 do
 start load generator 
 KILLPID=$!
 done
 wait $PID

You meant $WAITPID, right?


 kill $KILLPID

Doesn't it kill the last load generator only?


 mv perf.data results/perf.data.$i
 done

 (This is basic pseudo script of what I am doing), which results me
 having my profile being topped by _vscanf() and the function which I
 was seeing dominating in the older report dropping down to something
 like 5% (as opposed to 16-17%)

 Have I misunderstood how perf works? Something deeper? I am currently
 on 3.6.3. I can update to the latest upstream and report back. Any
 debug code is very welcome. I can also make my toy program and the
 scripts available for you to try out.

 I just updated to 6b0cb4eef7bdaa27b8021ea81813fba330a2d94d and I still
 see this happen.

 Thanks!
 Dhaval
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Patch v1 04/10] perf/x86: add memory profiling via PEBS Load Latency

2012-10-30 Thread Namhyung Kim
Hi Stephane,

On Mon, 29 Oct 2012 16:15:46 +0100, Stephane Eranian wrote:
 + /*
 +  * use the mapping table for bit 0-15
 +  */
 + val = pebs_data_source[dse.ld_dse];

I guess you meant bit 0-3, right?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Patch v1 06/10] perf/x86: add support for PEBS Precise Store

2012-10-30 Thread Namhyung Kim
On Mon, 29 Oct 2012 16:15:48 +0100, Stephane Eranian wrote:
 This patch adds support for PEBS Precise Store
 which is available on Intel Sandy Bridge and
 Ivy Bridge processors.

 To use Precise store, the proper PEBS event
 must be used: mem_trans_retired:precise_stores.
 For the perf tool, the generic mem-stores event
 exported via sysfs can be used directly.

Just trivial nitpicks..


 Signed-off-by: Stephane Eranian eran...@google.com
 ---
[snip]
 @@ -486,6 +524,7 @@ struct event_constraint 
 intel_snb_pebs_event_constraints[] = {
   INTEL_EVENT_CONSTRAINT(0xc4, 0xf),/* BR_INST_RETIRED.* */
   INTEL_EVENT_CONSTRAINT(0xc5, 0xf),/* BR_MISP_RETIRED.* */
   INTEL_PLD_CONSTRAINT(0x01cd, 0x8),/* 
 MEM_TRANS_RETIRED.LAT_ABOVE_THR */
 + INTEL_PST_CONSTRAINT(0x02cd, 0x8),/* 
 MEM_TRANS_RETIRED.PRECISE_STORES */
   INTEL_EVENT_CONSTRAINT(0xd0, 0xf),/* MEM_UOP_RETIRED.* */
   INTEL_EVENT_CONSTRAINT(0xd1, 0xf),/* MEM_LOAD_UOPS_RETIRED.* */
   INTEL_EVENT_CONSTRAINT(0xd2, 0xf),/* 
 MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
 @@ -500,6 +539,7 @@ struct event_constraint 
 intel_ivb_pebs_event_constraints[] = {
  INTEL_EVENT_CONSTRAINT(0xc4, 0xf),/* BR_INST_RETIRED.* */
  INTEL_EVENT_CONSTRAINT(0xc5, 0xf),/* BR_MISP_RETIRED.* */
  INTEL_PLD_CONSTRAINT(0x01cd, 0x8),/* 
 MEM_TRANS_RETIRED.LAT_ABOVE_THR */
 + INTEL_PST_CONSTRAINT(0x02cd, 0x8),/* 
 MEM_TRANS_RETIRED.PRECISE_STORES */

White-space damaged?  Oh, it seems already broken with spaces.


  INTEL_EVENT_CONSTRAINT(0xd0, 0xf),/* MEM_UOP_RETIRED.* */
  INTEL_EVENT_CONSTRAINT(0xd1, 0xf),/* MEM_LOAD_UOPS_RETIRED.* */
  INTEL_EVENT_CONSTRAINT(0xd2, 0xf),/* 
 MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */
[snip]
 @@ -672,7 +715,7 @@ static void __intel_pmu_pebs_event(struct perf_event 
 *event,
   /*
* if PEBS-LL or PreciseStore
*/
 - if (fll) {
 + if (fll || fst) {
   if (sample_type  PERF_SAMPLE_ADDR)
   data.addr = pebs-dla;
  
 @@ -688,6 +731,8 @@ static void __intel_pmu_pebs_event(struct perf_event 
 *event,
   if (sample_type  PERF_SAMPLE_DSRC) {
   if (fll)
   data.dsrc.val = load_latency_data(pebs-dse);
 + else if (fst)

Looks like it can be converted to a plain 'else'.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Patch v1 07/10] perf tools: add mem access sampling core support

2012-10-30 Thread Namhyung Kim
On Mon, 29 Oct 2012 16:15:49 +0100, Stephane Eranian wrote:
 This patch adds the sorting and histogram support
 functions to enable profiling of memory accesses.

 The following sorting orders are added:
  - symbol_daddr: data address symbol (or raw address)
  - dso_daddr: data address shared object
  - cost: access cost
  - locked: access uses locked transaction
  - tlb : TLB access
  - mem : memory level of the access (L1, L2, L3, RAM, ...)
  - snoop: access snoop mode

 Signed-off-by: Stephane Eranian eran...@google.com
 ---
[snip]
 +/* --sort daddr_sym */
 +static int64_t
 +sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
 +{
 + struct addr_map_symbol *l = left-mem_info-daddr;
 + struct addr_map_symbol *r = right-mem_info-daddr;
 +
 + return (int64_t)(r-addr - l-addr);
 +}

Doesn't it need to compare symbol (start address) if any, before doing
it with raw addresses?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Patch v1 08/10] perf report: add support for mem access profiling

2012-10-31 Thread Namhyung Kim
On Mon, 29 Oct 2012 16:15:50 +0100, Stephane Eranian wrote:
 This patch adds the --mem-mode option to perf report.

 This mode requires a perf.data file created with memory
 access samples.

 Signed-off-by: Stephane Eranian eran...@google.com
 ---
[snip]
 + cost = mi-cost;
 + if (!cost)
 + cost = 1;
 +
 + /*
 +  * The report shows the percentage of total branches captured
 +  * and not events sampled. Thus we use a pseudo period of 1.

But cost won't be 1 anymore if PERF_SAMPLE_COST set, right?


 +  * Only in the newt browser we are doing integrated annotation,
 +  * so we don't allocated the extra space needed because the stdio
 +  * code will not use it.

Yes, and gtk too.


 +  */
 + he = __hists__add_mem_entry(evsel-hists, al, parent, mi,
 + cost);
 + if (!he)
 + return -ENOMEM;
 +
 + if (sort__has_sym  he-ms.sym  use_browser  0) {

So I'd rather write 'use_browser == 1' instead of ' 0'.


 + struct annotation *notes = symbol__annotation(he-ms.sym);
 +
 + assert(evsel != NULL);
 +
 + if (notes-src == NULL  symbol__alloc_hist(he-ms.sym)  0)
 + goto out;
 +
 + err = hist_entry__inc_addr_samples(he, evsel-idx, al-addr);
 + if (err)
 + goto out;
 + }
 +
 + if (sort__has_sym  he-mem_info-daddr.sym  use_browser  0) {

Ditto.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [Patch v1 10/10] perf tools: add new mem command for memory access profiling

2012-10-31 Thread Namhyung Kim
On Mon, 29 Oct 2012 16:15:52 +0100, Stephane Eranian wrote:
 This new command is a wrapper on top of perf record and
 perf report to make it easier to configure for memory
 access profiling.

So this new command will be run only on speicific (PEBS  2?) Intel
machines, right?  Is there anything we can do for others?  Or at least
it might emit a warning message..


 To record loads:
 $ perf mem -t load rec .

 To record stores:
 $ perf mem -t store rec .

 To get the report:
 $ perf mem -t load rep

 Signed-off-by: Stephane Eranian eran...@google.com
 ---
[snip]
 +perf-mem(1)
 +===
 +
 +NAME
 +
 +perf-mem - Profile memory accesses
 +
 +SYNOPSIS
 +
 +[verse]
 +'perf mem' -t load record command
 +'perf mem' -t store record command
 +'perf mem' -t load report
 +'perf mem' -t store report

Is '-t' option mandatory?  AFAISC it seems optional and defaults to load.

And is command for record also mandatory?  Doesn't 'perf record' make
it optional?

If so, the above can be written like you did in 'mem_usage':

'perf mem' [options] (record [command] | report)


 +
 +DESCRIPTION
 +---
 +perf mem -t TYPE record runs a command and gathers memory operation data
 +from it, into perf.data. Perf record options are accepted and are passed 
 through.
 +
 +perf mem -t TYPE report displays the result. It invokes perf report with 
 the
 +right set of options to display a memory access profile.
 +
 +OPTIONS
 +---
 +command...::
 + Any command you can specify in a shell.
 +
 +-t::
 +--type=::
 + Select the memory operation type: load or store

It'd better saying it defaults to load.

 +
 +-R::
 +--dump-raw-samples=::
 + Dump the raw decoded samples on the screen in a format that is easy to 
 parse with
 + one sample per line.

Didn't we usually use -D switch for this?

 +
 +-x::
 +--field-separator::
 + Specify the field separator used when dump raw samples (-R option). By 
 default,
 + The separator is the space character.

And using -t for this will make it consistent with perf report IMHO.

 +
 +-C::
 +--cpu-list::
 + Restrict dump of raw samples to those provided via this option. Note 
 that the same
 + option can be passed in record mode. It will be interpreted the same 
 way as perf
 + record.
 +
 +SEE ALSO
 +
 +linkperf:perf-record[1], linkperf:perf-report[1]
[snip]
 +#define MEM_OPERATION_LOAD   load
 +#define MEM_OPERATION_STORE  store
 +
 +static char const*input_name = perf.data;

We have a global 'input_name' as of commit 70cb4e963f77 (perf tools:
Add a global variable 'const char *input_name').


 +static const char*mem_operation  = MEM_OPERATION_LOAD;
 +static const char*csv_sep= NULL;

Why not use symbol_conf.field_sep?

 +
 +struct perf_mem {
 + struct perf_tooltool;
 + char const  *input_name;
 + symbol_filter_t annotate_init;
 + boolhide_unresolved;
 + booldump_raw;
 + const char  *cpu_list;
 + DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 +};
 +
 +static const char * const mem_usage[] = {
 + perf mem [options] {record command |report},
 + NULL
 +};
[snip]
 +static int report_raw_events(struct perf_mem *mem)
 +{
 + int err = -EINVAL;
 + int ret;
 + struct perf_session *session = perf_session__new(input_name, O_RDONLY,
 +  0, false, mem-tool);
 +
 + if (mem-cpu_list) {
 + ret = perf_session__cpu_bitmap(session, mem-cpu_list,
 +mem-cpu_bitmap);
 + if (ret)
 + goto out_delete;
 + }
 +
 + if (symbol__init()  0)
 + return -1;
 +
 + if (session == NULL)
 + return -ENOMEM;

This check should be moved before perf_session__cpu_bitmap() calls.

Thanks,
Namhyung

 +
 + printf(# PID, TID, IP, ADDR, COST, DSRC, SYMBOL\n);
 +
 + err = perf_session__process_events(session, mem-tool);
 + if (err)
 + return err;
 +
 + return 0;
 +
 +out_delete:
 + perf_session__delete(session);
 + return err;
 +}
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [BUG] perf report: different reports when run on terminal as opposed to script

2012-10-31 Thread Namhyung Kim
On Tue, 30 Oct 2012 08:05:45 -0400, Dhaval Giani wrote:
 On Tue, Oct 30, 2012 at 3:42 AM, Namhyung Kim namhy...@kernel.org wrote:
 Hi Dhaval,

 On Mon, 29 Oct 2012 12:45:53 -0400, Dhaval Giani wrote:
 On Mon, Oct 29, 2012 at 12:01 PM, Dhaval Giani dhaval.gi...@gmail.com 
 wrote:
 Hi,

 As part of a class assignment I have to collect some performance
 statistics. In order to do so I run

 perf record -g the program I have to profile

 And in another window, I start 200 threads of the load generator
 (which is not recorded by perf)

 This generates me statistics that I expect to see, and I am happy. As
 this is academia and a class assignment, I need to collect information
 and analyze it across different setups. Which of course meant I script
 this whole thing, which basically is

 for i in all possibilities
 do
 perf record -g the program I have to profile 
 WAITPID=$!
 for j in NR_THREADS
 do
 start load generator 
 KILLPID=$!
 done
 wait $PID

 You meant $WAITPID, right?


 yes. grrr. I changed the name here to WAITPID for it to be clear and
 that was a fail. (I blame the cold)


 kill $KILLPID

 Doesn't it kill the last load generator only?



 Well, this was a bug in me typing the pseudo code. the actual script
 does $KILLPID $!

Okay, so I suspect that it might be affected by the autogroup scheduling
feature since you said running load generators in another window - I
guess it's a terminal.  How about running them with setsid?

Thanks,
Namhyung

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/9] perf python: add ui stubs file

2012-10-31 Thread Namhyung Kim
On Tue, 30 Oct 2012 08:53:38 -0700, Arnaldo Carvalho de Melo wrote:
 Em Tue, Oct 30, 2012 at 08:45:28AM -0600, David Ahern escreveu:
 On 10/30/12 1:24 AM, Namhyung Kim wrote:
 On Mon, 29 Oct 2012 10:31:41 -0600, David Ahern wrote:
 stdio based implementations of ui_ based functions for the python
 library. Needed for patch 3 - consolidating open counters method.

 How about adding ui/util.c to the python-ext-sources?

 Handles some of the ui_ functions, but still missing some
 symbols -- verbose, eprintf, ui__error_paranoid. The point of the
 python_stubs.c was a short term solution for the ui handlers.
 Arnaldo had some ideas on what is really needed.

 Yes, and that is something like what Namhyung did for perf_target, i.e.
 don't call ui__ stuff from the evsel/evlist classes but use a
 perf_evlist__strerror, merge perf_evlist__open_counters() with
 perf_evlist__open(), use just perf_evlist__open() everywhere, so that
 all tools get the fallbacks for features not present in older kernels,
 etc.

Yeah, it'd be better definitely.  But the problem is we might emit
warnings even in the internal fallback loop.  Not sure how to handle it
with this approach.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC/PATCHSET 00/15] perf report: Add support to accumulate hist periods

2012-10-31 Thread Namhyung Kim
On Tue, 30 Oct 2012 10:01:10 +0100, Ingo Molnar wrote:
 * Peter Zijlstra a.p.zijls...@chello.nl wrote:

 On Tue, 2012-10-30 at 15:59 +0900, Namhyung Kim wrote:

  Yes, the callchain part needs to be improved.  Peter's idea 
  indeed looks good to me too.
 
 FWIW, I think this is exactly what sysprof does, except that 
 tool isn't usable for other reasons.. You might want to look 
 at it though.

 I always found the fundamental sysprof system-wide call graph 
 profiling output/view superior - and so do many Xorg developers 
 who are using SysProf that I talked to - so I'd strongly 
 encourage to use that ordering and grouping for the default perf 
 call-graph profiling output/view.

Okay, I'll look at the sysprof.

Anyway, do you have any other comments for the general --cumulate
approach in this series (esp. with --branch-stack)?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: why is perf-report asking for objdump path?

2012-11-01 Thread Namhyung Kim
Hi David,

On Thu, 01 Nov 2012 15:09:46 -0600, David Ahern wrote:
 $ /tmp/pbuild/perf report -i perf.data --kallsyms kallsyms
 Error:
 Please install objdump for i686.
 You can add it to PATH, set CROSS_COMPILE or override the default
 using --objdump.

 And worse it refuses to run without it. If I was running the annotate
 command I could understand the request -- but this is the report path.

Agreed.  It should not affect when no annotation was used.


 Furthermore objdump exists:

 $ which objdump
 /usr/bin/objdump

 yes, the file was created on an i686 target, but I should be able to
 use the x86_64 host objdump if I were doing an annotate.

Could you test the below patch?  It'd great if you can do it in a
reverse situation - using x86_64 target on i686 host.


From f0a9d6303f83452c8b6f81081abae8fdf9c81778 Mon Sep 17 00:00:00 2001
From: Namhyung Kim namhyung@lge.com
Date: Fri, 2 Nov 2012 09:48:17 +0900
Subject: [PATCH] perf tools: Use normalized arch name for searching objdump
 path

David reported that perf report for i686 target data on x86_64 host
failed to work because it tried to find out cross-compiled objdump.

However objdump for x86_64 is compatible to i686 so that it doesn't
need to do it at all.  To prevent similar artifacts, normalize arch
name when comparing host and file architectures.

Reported-by: David Ahern dsah...@gmail.com
Cc: Irina Tirdea irina.tir...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/arch/common.c | 40 +---
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index 2367b253f039..5683529135b1 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -93,16 +93,46 @@ static int lookup_triplets(const char *const *triplets, 
const char *name)
return -1;
 }
 
+/*
+ * Return architecture name in a normalized form.
+ * The conversion logic comes from the Makefile.
+ */
+static const char *normalize_arch(char *arch)
+{
+   if (!strcmp(arch, x86_64))
+   return x86;
+   if (arch[0] == 'i'  arch[2] == '8'  arch[3] == '6')
+   return x86;
+   if (!strcmp(arch, sun4u) || !strncmp(arch, sparc, 5))
+   return sparc;
+   if (!strncmp(arch, arm, 3) || !strcmp(arch, sa110))
+   return arm;
+   if (!strncmp(arch, s390, 4))
+   return s390;
+   if (!strncmp(arch, parisc, 6))
+   return parisc;
+   if (!strncmp(arch, powerpc, 7) || !strncmp(arch, ppc, 3))
+   return powerpc;
+   if (!strncmp(arch, mips, 4))
+   return mips;
+   if (!strncmp(arch, sh, 2)  isdigit(arch[2]))
+   return sh;
+
+   return arch;
+}
+
 static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
  const char *name,
  const char **path)
 {
int idx;
-   char *arch, *cross_env;
+   const char *arch, *cross_env;
struct utsname uts;
const char *const *path_list;
char *buf = NULL;
 
+   arch = normalize_arch(env-arch);
+
if (uname(uts)  0)
goto out;
 
@@ -110,7 +140,7 @@ static int perf_session_env__lookup_binutils_path(struct 
perf_session_env *env,
 * We don't need to try to find objdump path for native system.
 * Just use default binutils path (e.g.: objdump).
 */
-   if (!strcmp(uts.machine, env-arch))
+   if (!strcmp(normalize_arch(uts.machine), arch))
goto out;
 
cross_env = getenv(CROSS_COMPILE);
@@ -127,8 +157,6 @@ static int perf_session_env__lookup_binutils_path(struct 
perf_session_env *env,
free(buf);
}
 
-   arch = env-arch;
-
if (!strcmp(arch, arm))
path_list = arm_triplets;
else if (!strcmp(arch, powerpc))
@@ -139,9 +167,7 @@ static int perf_session_env__lookup_binutils_path(struct 
perf_session_env *env,
path_list = s390_triplets;
else if (!strcmp(arch, sparc))
path_list = sparc_triplets;
-   else if (!strcmp(arch, x86) || !strcmp(arch, i386) ||
-!strcmp(arch, i486) || !strcmp(arch, i586) ||
-!strcmp(arch, i686))
+   else if (!strcmp(arch, x86))
path_list = x86_triplets;
else if (!strcmp(arch, mips))
path_list = mips_triplets;
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 00/25] perf test: Add perf_event_attr tests

2012-11-01 Thread Namhyung Kim
Hi,

On Fri, 2 Nov 2012 00:20:56 +0100, Jiri Olsa wrote:
 On Thu, Nov 01, 2012 at 05:38:01PM -0300, Arnaldo Carvalho de Melo wrote:
 Ah, I just pushed perf/core with this patchset, thanks!

 thanks,
 jirka

When using current acme/perf/core, I got this:

namhyung@sejong:perf$ ./perf test -v perf_event_attr
13: struct perf_event_attr setup   :
--- start ---
running './tests/attr/test-record-count'
running './tests/attr/test-stat-group1'
Traceback (most recent call last):
  File ./tests/attr.py, line 313, in module
main()
  File ./tests/attr.py, line 304, in main
run_tests(options)
  File ./tests/attr.py, line 247, in run_tests
Test(f, options).run()
  File ./tests/attr.py, line 126, in __init__
self.load_events(path, self.expect)
  File ./tests/attr.py, line 147, in load_events
base_items = parser_base.items('event')
  File /usr/lib64/python2.7/ConfigParser.py, line 642, in items
raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'event'
 end 
struct perf_event_attr setup: FAILED!

namhyung@sejong:perf$ cat tests/attr/test-stat-group1 
[config]
command = stat
args= -e '{cycles,instructions}' kill /dev/null 21
ret = 1

[event-1:base-stat]
fd=1
group_fd=-1

[event-2:base-stat]
fd=2
group_fd=1
config=1
# TODO both disabled and enable_on_exec are disabled for --group option,
#  enabled otherwise, check why..
disabled=1
enable_on_exec=1


Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 02/25] perf tests: Move test objects into 'tests' directory

2012-11-01 Thread Namhyung Kim
Hi Jiri,

Despite its way to acme's tree, I'd like to leave a few comments. :)


On Tue, 30 Oct 2012 23:01:43 +0100, Jiri Olsa wrote:
 Separating test objects into 'tests' directory.

 Signed-off-by: Jiri Olsa jo...@redhat.com
 Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
 Cc: Peter Zijlstra a.p.zijls...@chello.nl
 Cc: Ingo Molnar mi...@elte.hu
 Cc: Paul Mackerras pau...@samba.org
 Cc: Corey Ashford cjash...@linux.vnet.ibm.com
 Cc: Frederic Weisbecker fweis...@gmail.com
 ---
  tools/perf/Makefile |9 +-
  tools/perf/builtin-test.c   | 1559 
 ---
  tools/perf/tests/builtin-test.c | 1559 
 +++
  tools/perf/tests/dso-data.c |  153 
  tools/perf/tests/parse-events.c | 1116 +
  tools/perf/util/dso-test-data.c |  153 
  tools/perf/util/parse-events-test.c | 1116 -

Looks like it should be considered as renames.  Isn't 'git format-patch
-M' working?


  7 files changed, 2833 insertions(+), 2832 deletions(-)
  delete mode 100644 tools/perf/builtin-test.c
  create mode 100644 tools/perf/tests/builtin-test.c
  create mode 100644 tools/perf/tests/dso-data.c
  create mode 100644 tools/perf/tests/parse-events.c
  delete mode 100644 tools/perf/util/dso-test-data.c
  delete mode 100644 tools/perf/util/parse-events-test.c

 diff --git a/tools/perf/Makefile b/tools/perf/Makefile
 index 3e807d7..2d3427f 100644
 --- a/tools/perf/Makefile
 +++ b/tools/perf/Makefile
 @@ -169,7 +169,7 @@ endif
  
  ### --- END CONFIGURATION SECTION ---
  
 -BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util 
 -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 
 -D_GNU_SOURCE
 +BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -Iutil 
 -I. -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 
 -D_GNU_SOURCE

Hmm..  Do you really want this?  AFAIK there're lots of places that
include header files under the util directory and they used relative
path.  I don't know how it affects them but at least they can be changed
to use simpler path with this change.


  BASIC_LDFLAGS =
  
  ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
 @@ -371,7 +371,6 @@ LIB_OBJS += $(OUTPUT)util/help.o
  LIB_OBJS += $(OUTPUT)util/levenshtein.o
  LIB_OBJS += $(OUTPUT)util/parse-options.o
  LIB_OBJS += $(OUTPUT)util/parse-events.o
 -LIB_OBJS += $(OUTPUT)util/parse-events-test.o
  LIB_OBJS += $(OUTPUT)util/path.o
  LIB_OBJS += $(OUTPUT)util/rbtree.o
  LIB_OBJS += $(OUTPUT)util/bitmap.o
 @@ -389,7 +388,6 @@ LIB_OBJS += $(OUTPUT)util/sigchain.o
  LIB_OBJS += $(OUTPUT)util/dso.o
  LIB_OBJS += $(OUTPUT)util/symbol.o
  LIB_OBJS += $(OUTPUT)util/symbol-elf.o
 -LIB_OBJS += $(OUTPUT)util/dso-test-data.o
  LIB_OBJS += $(OUTPUT)util/color.o
  LIB_OBJS += $(OUTPUT)util/pager.o
  LIB_OBJS += $(OUTPUT)util/header.o
 @@ -430,6 +428,9 @@ LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
  
  LIB_OBJS += $(OUTPUT)arch/common.o
  
 +LIB_OBJS += $(OUTPUT)tests/parse-events.o
 +LIB_OBJS += $(OUTPUT)tests/dso-data.o
 +

Maybe TEST_OBJS?  I guess they don't need to be included in libperf?


  BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
  BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
  # Benchmark modules
 @@ -459,8 +460,8 @@ BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
  BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
  BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
  BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
 -BUILTIN_OBJS += $(OUTPUT)builtin-test.o
  BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
 +BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o

Placing builtin command in a different directory looks little bit odd.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCHv2 03/25] perf tests: Add framework for automated perf_event_attr tests

2012-11-01 Thread Namhyung Kim
On Wed, 31 Oct 2012 15:52:47 +0100, Jiri Olsa wrote:
 Adding automated test to check event's perf_event_attr values.

 The idea is run perf session with kidnapping sys_perf_event_open
 function. For each sys_perf_event_open call we store the
 perf_event_attr data to the file to be checked later against what
 we expect.

 You can run this by:
   $ python ./tests/attr.py -d ./tests/attr/ -p ./perf -v

 v2 changes:
   - preserve errno value in the hook

 Signed-off-by: Jiri Olsa jo...@redhat.com
 Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
 Cc: Peter Zijlstra a.p.zijls...@chello.nl
 Cc: Ingo Molnar mi...@elte.hu
 Cc: Paul Mackerras pau...@samba.org
 Cc: Corey Ashford cjash...@linux.vnet.ibm.com
 Cc: Frederic Weisbecker fweis...@gmail.com
 ---
  tools/perf/Makefile  |   1 +
  tools/perf/perf.c|   2 +
  tools/perf/perf.h|  16 ++-
  tools/perf/tests/attr.c  | 140 +
  tools/perf/tests/attr.py | 313 
 +++
  5 files changed, 470 insertions(+), 2 deletions(-)
  create mode 100644 tools/perf/tests/attr.c
  create mode 100644 tools/perf/tests/attr.py

 diff --git a/tools/perf/Makefile b/tools/perf/Makefile
 index 2d3427f..1da87a3 100644
 --- a/tools/perf/Makefile
 +++ b/tools/perf/Makefile
 @@ -430,6 +430,7 @@ LIB_OBJS += $(OUTPUT)arch/common.o
  
  LIB_OBJS += $(OUTPUT)tests/parse-events.o
  LIB_OBJS += $(OUTPUT)tests/dso-data.o
 +LIB_OBJS += $(OUTPUT)tests/attr.o

It'd better if it has more specific name like 'event-attr' but it'd not
a big deal so no strong objection. :)

  
  BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
  BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
[snip]
 +#define WRITE_ASS(str, fmt, data)\
 +do { \
 + char buf[BUFSIZE];  \
 + size_t size;\
 + \
 + size = snprintf(buf, BUFSIZE, #str =%fmt \n, data); \
 + if (1 != fwrite(buf, size, 1, file)) {  \
 + perror(test attr - failed to write event file);   \
 + fclose(file);   \
 + return -1;  \
 + }   \
 + \
 +} while (0)

What is ASS?

 +
 +static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu,
 +int fd, int group_fd, unsigned long flags)
 +{
 + FILE *file;
 + char path[PATH_MAX];
 +
 + snprintf(path, PATH_MAX, %s/event-%d-%llu-%d, dir,
 +  attr-type, attr-config, fd);
 +
 + file = fopen(path, w+);
 + if (!file) {
 + perror(test attr - failed to open event file);
 + return -1;
 + }
 +
 + if (fprintf(file, [event-%d-%llu-%d]\n,
 + attr-type, attr-config, fd)  0) {
 + perror(test attr - failed to write event file);
 + fclose(file);
 + return -1;
 + }
 +
 + /* syscall arguments */
 + WRITE_ASS(fd,   d, fd);
 + WRITE_ASS(group_fd, d, group_fd);
 + WRITE_ASS(cpu,  d, cpu);
 + WRITE_ASS(pid,  d, pid);
 + WRITE_ASS(flags,   lu, flags);
 +
 + /* struct perf_event_attr */
 + WRITE_ASS(type,   PRIu32,  attr-type);
 + WRITE_ASS(size,   PRIu32,  attr-size);
 + WRITE_ASS(config,  llu,  attr-config);
 + WRITE_ASS(sample_period, llu, attr-sample_period);
 + WRITE_ASS(sample_type,   llu, attr-sample_type);
 + WRITE_ASS(read_format,   llu, attr-read_format);
 + WRITE_ASS(disabled,   d, attr-disabled);
 + WRITE_ASS(inherit,d, attr-inherit);
 + WRITE_ASS(pinned, d, attr-pinned);
 + WRITE_ASS(exclusive,  d, attr-exclusive);
 + WRITE_ASS(exclude_user,   d, attr-exclude_user);
 + WRITE_ASS(exclude_kernel, d, attr-exclude_kernel);
 + WRITE_ASS(exclude_hv, d, attr-exclude_hv);
 + WRITE_ASS(exclude_idle,   d, attr-exclude_idle);
 + WRITE_ASS(mmap,   d, attr-mmap);
 + WRITE_ASS(comm,   d, attr-comm);
 + WRITE_ASS(freq,   d, attr-freq);
 + WRITE_ASS(inherit_stat,   d, attr-inherit_stat);
 + WRITE_ASS(enable_on_exec, d, attr-enable_on_exec);
 + WRITE_ASS(task,   d, attr-task);
 + WRITE_ASS(watermask,  d, attr-watermark);
 + WRITE_ASS(precise_ip, d, attr-precise_ip);
 + WRITE_ASS(mmap_data,  d, attr-mmap_data);
 + WRITE_ASS(sample_id_all,  d, attr-sample_id_all);
 + WRITE_ASS(exclude_host,   d, attr-exclude_host);
 + WRITE_ASS(exclude_guest,  d, attr-exclude_guest);
 + WRITE_ASS(exclude_callchain_kernel, d,
 +   attr-exclude_callchain_kernel);
 + 

Re: [PATCH 00/25] perf test: Add perf_event_attr tests

2012-11-01 Thread Namhyung Kim
On Fri, 02 Nov 2012 10:25:18 +0900, Namhyung Kim wrote:
 namhyung@sejong:perf$ cat tests/attr/test-stat-group1 
 [config]
 command = stat
 args= -e '{cycles,instructions}' kill /dev/null 21
 ret = 1

 [event-1:base-stat]
 fd=1
 group_fd=-1

 [event-2:base-stat]
 fd=2
 group_fd=1
 config=1
 # TODO both disabled and enable_on_exec are disabled for --group option,
 #  enabled otherwise, check why..
 disabled=1
 enable_on_exec=1

Oh I realize that I don't have the base-stat file.

  namhyung@sejong:perf$ cat tests/attr/base-stat
  cat: tests/attr/base-stat: No such file or directory

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] perf report: Enable the runtime switching of perf data file

2012-11-01 Thread Namhyung Kim
Hi Feng,

On Thu,  1 Nov 2012 00:00:57 +0800, Feng Tang wrote:
 This is for tui browser only. This patch will check the returned
 key of tui hists browser, if it's K_SWITH_INPUT_DATA, then recreate
 a session for the new selected data file.

You may want to add my previous patch [1] to your patch set as it can
call perf_session__delete() multiple times.

Thanks,
Namhyung

[1] https://lkml.org/lkml/2012/9/24/693
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RESEND 1/3] perf tools: Use normalized arch name for searching objdump path

2012-11-01 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

David reported that perf report for i686 target data on x86_64 host
failed to work because it tried to find out cross-compiled objdump.

However objdump for x86_64 is compatible to i686 so that it doesn't
need to do it at all.  To prevent similar artifacts, normalize arch
name when comparing host and file architectures.

Reported-by: David Ahern dsah...@gmail.com
Cc: David Ahern dsah...@gmail.com
Cc: Irina Tirdea irina.tir...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/arch/common.c | 40 +---
 1 file changed, 33 insertions(+), 7 deletions(-)

diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
index 2367b253f039..5683529135b1 100644
--- a/tools/perf/arch/common.c
+++ b/tools/perf/arch/common.c
@@ -93,16 +93,46 @@ static int lookup_triplets(const char *const *triplets, 
const char *name)
return -1;
 }
 
+/*
+ * Return architecture name in a normalized form.
+ * The conversion logic comes from the Makefile.
+ */
+static const char *normalize_arch(char *arch)
+{
+   if (!strcmp(arch, x86_64))
+   return x86;
+   if (arch[0] == 'i'  arch[2] == '8'  arch[3] == '6')
+   return x86;
+   if (!strcmp(arch, sun4u) || !strncmp(arch, sparc, 5))
+   return sparc;
+   if (!strncmp(arch, arm, 3) || !strcmp(arch, sa110))
+   return arm;
+   if (!strncmp(arch, s390, 4))
+   return s390;
+   if (!strncmp(arch, parisc, 6))
+   return parisc;
+   if (!strncmp(arch, powerpc, 7) || !strncmp(arch, ppc, 3))
+   return powerpc;
+   if (!strncmp(arch, mips, 4))
+   return mips;
+   if (!strncmp(arch, sh, 2)  isdigit(arch[2]))
+   return sh;
+
+   return arch;
+}
+
 static int perf_session_env__lookup_binutils_path(struct perf_session_env *env,
  const char *name,
  const char **path)
 {
int idx;
-   char *arch, *cross_env;
+   const char *arch, *cross_env;
struct utsname uts;
const char *const *path_list;
char *buf = NULL;
 
+   arch = normalize_arch(env-arch);
+
if (uname(uts)  0)
goto out;
 
@@ -110,7 +140,7 @@ static int perf_session_env__lookup_binutils_path(struct 
perf_session_env *env,
 * We don't need to try to find objdump path for native system.
 * Just use default binutils path (e.g.: objdump).
 */
-   if (!strcmp(uts.machine, env-arch))
+   if (!strcmp(normalize_arch(uts.machine), arch))
goto out;
 
cross_env = getenv(CROSS_COMPILE);
@@ -127,8 +157,6 @@ static int perf_session_env__lookup_binutils_path(struct 
perf_session_env *env,
free(buf);
}
 
-   arch = env-arch;
-
if (!strcmp(arch, arm))
path_list = arm_triplets;
else if (!strcmp(arch, powerpc))
@@ -139,9 +167,7 @@ static int perf_session_env__lookup_binutils_path(struct 
perf_session_env *env,
path_list = s390_triplets;
else if (!strcmp(arch, sparc))
path_list = sparc_triplets;
-   else if (!strcmp(arch, x86) || !strcmp(arch, i386) ||
-!strcmp(arch, i486) || !strcmp(arch, i586) ||
-!strcmp(arch, i686))
+   else if (!strcmp(arch, x86))
path_list = x86_triplets;
else if (!strcmp(arch, mips))
path_list = mips_triplets;
-- 
1.7.11.7

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] perf report: Postpone objdump check until annotation requested

2012-11-01 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

David reported that current perf report refused to run on a data file
captured from a different machine because of objdump.  Since the
objdump tools won't be used unless annotation was requested, checking
its presence at init time doens't make sense.

Reported-by: David Ahern dsah...@gmail.com
Cc: Irina Tirdea irina.tir...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c|  9 ++---
 tools/perf/builtin-top.c   |  3 ++-
 tools/perf/ui/browsers/hists.c | 22 --
 tools/perf/util/hist.h |  7 +--
 4 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 234f34d466e3..fc251005dd3d 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -428,7 +428,8 @@ static int __cmd_report(struct perf_report *rep)
if (use_browser  0) {
if (use_browser == 1) {
perf_evlist__tui_browse_hists(session-evlist, help,
- NULL);
+ NULL,
+ session-header.env);
} else if (use_browser == 2) {
perf_evlist__gtk_browse_hists(session-evlist, help,
  NULL);
@@ -672,12 +673,6 @@ int cmd_report(int argc, const char **argv, const char 
*prefix __maybe_unused)
has_br_stack = perf_header__has_feat(session-header,
 HEADER_BRANCH_STACK);
 
-   if (!objdump_path) {
-   ret = perf_session_env__lookup_objdump(session-header.env);
-   if (ret)
-   goto error;
-   }
-
if (sort__branch_mode == -1  has_br_stack)
sort__branch_mode = 1;
 
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 102b43c9905d..c9ff3950cd4b 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -598,7 +598,8 @@ static void *display_thread_tui(void *arg)
list_for_each_entry(pos, top-evlist-entries, node)
pos-hists.uid_filter_str = top-target.uid_str;
 
-   perf_evlist__tui_browse_hists(top-evlist, help, hbt);
+   perf_evlist__tui_browse_hists(top-evlist, help, hbt,
+ top-session-header.env);
 
exit_browser(0);
exit(0);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index c7d32edb8057..ccc4bd161420 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -11,6 +11,7 @@
 #include ../../util/pstack.h
 #include ../../util/sort.h
 #include ../../util/util.h
+#include ../../arch/common.h
 
 #include ../browser.h
 #include ../helpline.h
@@ -1137,7 +1138,8 @@ static inline bool is_report_browser(void *timer)
 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
const char *helpline, const char *ev_name,
bool left_exits,
-   struct hist_browser_timer *hbt)
+   struct hist_browser_timer *hbt,
+   struct perf_session_env *env)
 {
struct hists *hists = evsel-hists;
struct hist_browser *browser = hist_browser__new(hists);
@@ -1367,6 +1369,9 @@ retry_popup_menu:
struct hist_entry *he;
int err;
 do_annotate:
+   if (!objdump_path  
perf_session_env__lookup_objdump(env))
+   continue;
+
he = hist_browser__selected_entry(browser);
if (he == NULL)
continue;
@@ -1470,6 +1475,7 @@ struct perf_evsel_menu {
struct ui_browser b;
struct perf_evsel *selection;
bool lost_events, lost_events_warned;
+   struct perf_session_env *env;
 };
 
 static void perf_evsel_menu__write(struct ui_browser *browser,
@@ -1551,7 +1557,8 @@ browse_hists:
hbt-timer(hbt-arg);
ev_name = perf_evsel__name(pos);
key = perf_evsel__hists_browse(pos, nr_events, help,
-  ev_name, true, hbt);
+  ev_name, true, hbt,
+  menu-env);
ui_browser__show_title(menu-b, title);
switch (key) {
case K_TAB:
@@ -1599,7 +1606,8 @@ out:
 
 static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
   const char *help,
-  struct hist_browser_timer *hbt

[PATCH 2/3] perf tools: Introduce struct hist_browser_timer

2012-11-01 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Currently various hist browser functions receive 3 arguments for
refreshing histogram but only used from a few places.  Also it's only
for perf top command so that it can be NULL for other (and probably
most) cases.  Pack them into a struct in order to reduce number of
those unused arguments.

This is a mechanical change and does not intend a functional change.

Cc: David Ahern dsah...@gmail.com
Cc: Irina Tirdea irina.tir...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-annotate.c |  2 +-
 tools/perf/builtin-report.c   |  4 ++--
 tools/perf/builtin-top.c  |  9 +---
 tools/perf/ui/browsers/annotate.c | 27 +++-
 tools/perf/ui/browsers/hists.c| 43 +--
 tools/perf/ui/gtk/browser.c   |  4 +---
 tools/perf/util/annotate.h|  8 
 tools/perf/util/hist.h| 28 -
 8 files changed, 58 insertions(+), 67 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index cb234765ce3d..dc870cf31b79 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -139,7 +139,7 @@ find_next:
}
 
if (use_browser  0) {
-   key = hist_entry__tui_annotate(he, evidx, NULL, NULL, 
0);
+   key = hist_entry__tui_annotate(he, evidx, NULL);
switch (key) {
case K_RIGHT:
next = rb_next(nd);
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index f07eae73e692..234f34d466e3 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -428,10 +428,10 @@ static int __cmd_report(struct perf_report *rep)
if (use_browser  0) {
if (use_browser == 1) {
perf_evlist__tui_browse_hists(session-evlist, help,
- NULL, NULL, 0);
+ NULL);
} else if (use_browser == 2) {
perf_evlist__gtk_browse_hists(session-evlist, help,
- NULL, NULL, 0);
+ NULL);
}
} else
perf_evlist__tty_browse_hists(session-evlist, rep, help);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f2ecd498c72d..102b43c9905d 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -582,6 +582,11 @@ static void *display_thread_tui(void *arg)
struct perf_evsel *pos;
struct perf_top *top = arg;
const char *help = For a higher level overview, try: perf top --sort 
comm,dso;
+   struct hist_browser_timer hbt = {
+   .timer  = perf_top__sort_new_samples,
+   .arg= top,
+   .refresh= top-delay_secs,
+   };
 
perf_top__sort_new_samples(top);
 
@@ -593,9 +598,7 @@ static void *display_thread_tui(void *arg)
list_for_each_entry(pos, top-evlist-entries, node)
pos-hists.uid_filter_str = top-target.uid_str;
 
-   perf_evlist__tui_browse_hists(top-evlist, help,
- perf_top__sort_new_samples,
- top, top-delay_secs);
+   perf_evlist__tui_browse_hists(top-evlist, help, hbt);
 
exit_browser(0);
exit(0);
diff --git a/tools/perf/ui/browsers/annotate.c 
b/tools/perf/ui/browsers/annotate.c
index 28f8aab73aee..3eff17f703f3 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -386,9 +386,8 @@ static void annotate_browser__init_asm_mode(struct 
annotate_browser *browser)
browser-b.nr_entries = browser-nr_asm_entries;
 }
 
-static bool annotate_browser__callq(struct annotate_browser *browser,
-   int evidx, void (*timer)(void *arg),
-   void *arg, int delay_secs)
+static bool annotate_browser__callq(struct annotate_browser *browser, int 
evidx,
+   struct hist_browser_timer *hbt)
 {
struct map_symbol *ms = browser-b.priv;
struct disasm_line *dl = browser-selection;
@@ -418,7 +417,7 @@ static bool annotate_browser__callq(struct annotate_browser 
*browser,
}
 
pthread_mutex_unlock(notes-lock);
-   symbol__tui_annotate(target, ms-map, evidx, timer, arg, delay_secs);
+   symbol__tui_annotate(target, ms-map, evidx, hbt);
ui_browser__show_title(browser-b, sym-name);
return true;
 }
@@ -602,13 +601,13 @@ static void annotate_browser__update_addr_width(struct 
annotate_browser *browser
 }
 
 static int annotate_browser__run(struct annotate_browser *browser, int evidx,
-void

[PATCH 0/6] perf header: Save and reuse feature information in header (v5)

2012-09-24 Thread Namhyung Kim
Hi,

Currently the perf header information is used only at initial setup
time and discarded.  If it's saved we could reuse the information for
various purpose - for instance, perf kvm stat needs to know cpuid so
it had to invent an accessor.

Thanks,
Namhyung


v4 - v5:
 * Use saved cpuid info for perf kvm (David)

v3 - v4:
 * rename perf_header_info to perf_session_env (Arnaldo)

v2 - v3:
 * patch 1-3 in v2 merged into tip
 * rebased on current acme/perf/core

v1 - v2:
 * not touch EVENT_DESC feature handling
 * split out struct perf_header_info
 * simplify multi-string handling
 * add some cleanup patches

Namhyung Kim (6):
  perf header: Add struct perf_session_env
  perf header: Add -process callbacks to most of features
  perf header: Use pre-processed session env when printing
  perf header: Remove unused @feat arg from -process callback
  perf kvm: Use perf_session_env for reading cpuid
  perf header: Remove perf_header__read_feature

 tools/perf/builtin-kvm.c |  10 +-
 tools/perf/util/header.c | 598 ++-
 tools/perf/util/header.h |  25 +-
 3 files changed, 406 insertions(+), 227 deletions(-)

-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/6] perf header: Use pre-processed session env when printing

2012-09-24 Thread Namhyung Kim
From now on each feature information is processed and saved in perf
header so that it can be used for printing.  The event desc and branch
stack features are not touched since they're not saved.

Cc: Stephane Eranian eran...@google.com
Cc: Robert Richter robert.rich...@amd.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/header.c | 207 +++
 1 file changed, 66 insertions(+), 141 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index d74b58d4105d..b2929d7a3d4e 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1103,118 +1103,80 @@ static int write_branch_stack(int fd __maybe_unused,
return 0;
 }
 
-static void print_hostname(struct perf_header *ph, int fd, FILE *fp)
+static void print_hostname(struct perf_header *ph, int fd __maybe_unused,
+  FILE *fp)
 {
-   char *str = do_read_string(fd, ph);
-   fprintf(fp, # hostname : %s\n, str);
-   free(str);
+   fprintf(fp, # hostname : %s\n, ph-env.hostname);
 }
 
-static void print_osrelease(struct perf_header *ph, int fd, FILE *fp)
+static void print_osrelease(struct perf_header *ph, int fd __maybe_unused,
+   FILE *fp)
 {
-   char *str = do_read_string(fd, ph);
-   fprintf(fp, # os release : %s\n, str);
-   free(str);
+   fprintf(fp, # os release : %s\n, ph-env.os_release);
 }
 
-static void print_arch(struct perf_header *ph, int fd, FILE *fp)
+static void print_arch(struct perf_header *ph, int fd __maybe_unused, FILE *fp)
 {
-   char *str = do_read_string(fd, ph);
-   fprintf(fp, # arch : %s\n, str);
-   free(str);
+   fprintf(fp, # arch : %s\n, ph-env.arch);
 }
 
-static void print_cpudesc(struct perf_header *ph, int fd, FILE *fp)
+static void print_cpudesc(struct perf_header *ph, int fd __maybe_unused,
+ FILE *fp)
 {
-   char *str = do_read_string(fd, ph);
-   fprintf(fp, # cpudesc : %s\n, str);
-   free(str);
+   fprintf(fp, # cpudesc : %s\n, ph-env.cpu_desc);
 }
 
-static void print_nrcpus(struct perf_header *ph, int fd, FILE *fp)
+static void print_nrcpus(struct perf_header *ph, int fd __maybe_unused,
+FILE *fp)
 {
-   ssize_t ret;
-   u32 nr;
-
-   ret = read(fd, nr, sizeof(nr));
-   if (ret != (ssize_t)sizeof(nr))
-   nr = -1; /* interpreted as error */
-
-   if (ph-needs_swap)
-   nr = bswap_32(nr);
-
-   fprintf(fp, # nrcpus online : %u\n, nr);
-
-   ret = read(fd, nr, sizeof(nr));
-   if (ret != (ssize_t)sizeof(nr))
-   nr = -1; /* interpreted as error */
-
-   if (ph-needs_swap)
-   nr = bswap_32(nr);
-
-   fprintf(fp, # nrcpus avail : %u\n, nr);
+   fprintf(fp, # nrcpus online : %u\n, ph-env.nr_cpus_online);
+   fprintf(fp, # nrcpus avail : %u\n, ph-env.nr_cpus_avail);
 }
 
-static void print_version(struct perf_header *ph, int fd, FILE *fp)
+static void print_version(struct perf_header *ph, int fd __maybe_unused,
+ FILE *fp)
 {
-   char *str = do_read_string(fd, ph);
-   fprintf(fp, # perf version : %s\n, str);
-   free(str);
+   fprintf(fp, # perf version : %s\n, ph-env.version);
 }
 
-static void print_cmdline(struct perf_header *ph, int fd, FILE *fp)
+static void print_cmdline(struct perf_header *ph, int fd __maybe_unused,
+ FILE *fp)
 {
-   ssize_t ret;
+   int nr, i;
char *str;
-   u32 nr, i;
-
-   ret = read(fd, nr, sizeof(nr));
-   if (ret != (ssize_t)sizeof(nr))
-   return;
 
-   if (ph-needs_swap)
-   nr = bswap_32(nr);
+   nr = ph-env.nr_cmdline;
+   str = ph-env.cmdline;
 
fprintf(fp, # cmdline : );
 
for (i = 0; i  nr; i++) {
-   str = do_read_string(fd, ph);
fprintf(fp, %s , str);
-   free(str);
+   str += strlen(str) + 1;
}
fputc('\n', fp);
 }
 
-static void print_cpu_topology(struct perf_header *ph, int fd, FILE *fp)
+static void print_cpu_topology(struct perf_header *ph, int fd __maybe_unused,
+  FILE *fp)
 {
-   ssize_t ret;
-   u32 nr, i;
+   int nr, i;
char *str;
 
-   ret = read(fd, nr, sizeof(nr));
-   if (ret != (ssize_t)sizeof(nr))
-   return;
-
-   if (ph-needs_swap)
-   nr = bswap_32(nr);
+   nr = ph-env.nr_sibling_cores;
+   str = ph-env.sibling_cores;
 
for (i = 0; i  nr; i++) {
-   str = do_read_string(fd, ph);
fprintf(fp, # sibling cores   : %s\n, str);
-   free(str);
+   str += strlen(str) + 1;
}
 
-   ret = read(fd, nr, sizeof(nr));
-   if (ret != (ssize_t)sizeof(nr))
-   return;
-
-   if (ph-needs_swap)
-   nr = bswap_32(nr);
+   nr

[PATCH 1/6] perf header: Add struct perf_session_env

2012-09-24 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

The struct perf_session_env will preserve environment information at
the time of perf record.  It can be accessed anytime after parsing a
perf.data file if needed.

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/header.h | 24 
 1 file changed, 24 insertions(+)

diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 58de08b21bce..5867c7d74f97 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -58,6 +58,29 @@ struct perf_header;
 int perf_file_header__read(struct perf_file_header *header,
   struct perf_header *ph, int fd);
 
+struct perf_session_env {
+   char*hostname;
+   char*os_release;
+   char*version;
+   char*arch;
+   int nr_cpus_online;
+   int nr_cpus_avail;
+   char*cpu_desc;
+   char*cpuid;
+   unsigned long long  total_mem;
+
+   int nr_cmdline;
+   char*cmdline;
+   int nr_sibling_cores;
+   char*sibling_cores;
+   int nr_sibling_threads;
+   char*sibling_threads;
+   int nr_numa_nodes;
+   char*numa_nodes;
+   int nr_pmu_mappings;
+   char*pmu_mappings;
+};
+
 struct perf_header {
int frozen;
boolneeds_swap;
@@ -67,6 +90,7 @@ struct perf_header {
u64 event_offset;
u64 event_size;
DECLARE_BITMAP(adds_features, HEADER_FEAT_BITS);
+   struct perf_session_env env;
 };
 
 struct perf_evlist;
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 4/6] perf header: Remove unused @feat arg from -process callback

2012-09-24 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

As the @feat arg is not used anywhere, get rid of it from the signature.

Cc: Stephane Eranian eran...@google.com
Cc: Robert Richter robert.rich...@amd.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/header.c | 70 
 1 file changed, 35 insertions(+), 35 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index b2929d7a3d4e..4b028df83a40 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1580,18 +1580,16 @@ out:
return err;
 }
 
-static int process_tracing_data(struct perf_file_section *section
-   __maybe_unused,
- struct perf_header *ph __maybe_unused,
- int feat __maybe_unused, int fd, void *data)
+static int process_tracing_data(struct perf_file_section *section 
__maybe_unused,
+   struct perf_header *ph __maybe_unused,
+   int fd, void *data)
 {
trace_report(fd, data, false);
return 0;
 }
 
 static int process_build_id(struct perf_file_section *section,
-   struct perf_header *ph,
-   int feat __maybe_unused, int fd,
+   struct perf_header *ph, int fd,
void *data __maybe_unused)
 {
if (perf_header__read_build_ids(ph, fd, section-offset, section-size))
@@ -1600,40 +1598,40 @@ static int process_build_id(struct perf_file_section 
*section,
 }
 
 static int process_hostname(struct perf_file_section *section __maybe_unused,
-   struct perf_header *ph, int feat __maybe_unused,
-   int fd, void *data __maybe_unused)
+   struct perf_header *ph, int fd,
+   void *data __maybe_unused)
 {
ph-env.hostname = do_read_string(fd, ph);
return ph-env.hostname ? 0 : -ENOMEM;
 }
 
 static int process_osrelease(struct perf_file_section *section __maybe_unused,
-struct perf_header *ph, int feat __maybe_unused,
-int fd, void *data __maybe_unused)
+struct perf_header *ph, int fd,
+void *data __maybe_unused)
 {
ph-env.os_release = do_read_string(fd, ph);
return ph-env.os_release ? 0 : -ENOMEM;
 }
 
 static int process_version(struct perf_file_section *section __maybe_unused,
-  struct perf_header *ph, int feat __maybe_unused,
-  int fd, void *data __maybe_unused)
+  struct perf_header *ph, int fd,
+  void *data __maybe_unused)
 {
ph-env.version = do_read_string(fd, ph);
return ph-env.version ? 0 : -ENOMEM;
 }
 
 static int process_arch(struct perf_file_section *section __maybe_unused,
-   struct perf_header *ph, int feat __maybe_unused,
-   int fd, void *data __maybe_unused)
+   struct perf_header *ph, int fd,
+   void *data __maybe_unused)
 {
ph-env.arch = do_read_string(fd, ph);
return ph-env.arch ? 0 : -ENOMEM;
 }
 
 static int process_nrcpus(struct perf_file_section *section __maybe_unused,
- struct perf_header *ph, int feat __maybe_unused,
- int fd, void *data __maybe_unused)
+ struct perf_header *ph, int fd,
+ void *data __maybe_unused)
 {
size_t ret;
u32 nr;
@@ -1659,24 +1657,24 @@ static int process_nrcpus(struct perf_file_section 
*section __maybe_unused,
 }
 
 static int process_cpudesc(struct perf_file_section *section __maybe_unused,
-  struct perf_header *ph, int feat __maybe_unused,
-  int fd, void *data __maybe_unused)
+  struct perf_header *ph, int fd,
+  void *data __maybe_unused)
 {
ph-env.cpu_desc = do_read_string(fd, ph);
return ph-env.cpu_desc ? 0 : -ENOMEM;
 }
 
 static int process_cpuid(struct perf_file_section *section __maybe_unused,
-struct perf_header *ph, int feat __maybe_unused,
-int fd, void *data __maybe_unused)
+struct perf_header *ph,  int fd,
+void *data __maybe_unused)
 {
ph-env.cpuid = do_read_string(fd, ph);
return ph-env.cpuid ? 0 : -ENOMEM;
 }
 
 static int process_total_mem(struct perf_file_section *section __maybe_unused,
-struct perf_header *ph, int feat __maybe_unused,
-int fd, void *data __maybe_unused)
+struct perf_header *ph, int fd,
+void *data __maybe_unused

[PATCH 2/6] perf header: Add -process callbacks to most of features

2012-09-24 Thread Namhyung Kim
From now on each feature information is processed and saved in perf
header so that it can be used wherever needed.  The BRANCH_STACK
feature is an exception since it needs nothing to be done.

Cc: Stephane Eranian eran...@google.com
Cc: Robert Richter robert.rich...@amd.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/header.c | 319 +--
 1 file changed, 308 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ad72b2814ba8..d74b58d4105d 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -22,6 +22,7 @@
 #include cpumap.h
 #include pmu.h
 #include vdso.h
+#include strbuf.h
 
 static bool no_buildid_cache = false;
 
@@ -1673,6 +1674,99 @@ static int process_build_id(struct perf_file_section 
*section,
return 0;
 }
 
+static int process_hostname(struct perf_file_section *section __maybe_unused,
+   struct perf_header *ph, int feat __maybe_unused,
+   int fd, void *data __maybe_unused)
+{
+   ph-env.hostname = do_read_string(fd, ph);
+   return ph-env.hostname ? 0 : -ENOMEM;
+}
+
+static int process_osrelease(struct perf_file_section *section __maybe_unused,
+struct perf_header *ph, int feat __maybe_unused,
+int fd, void *data __maybe_unused)
+{
+   ph-env.os_release = do_read_string(fd, ph);
+   return ph-env.os_release ? 0 : -ENOMEM;
+}
+
+static int process_version(struct perf_file_section *section __maybe_unused,
+  struct perf_header *ph, int feat __maybe_unused,
+  int fd, void *data __maybe_unused)
+{
+   ph-env.version = do_read_string(fd, ph);
+   return ph-env.version ? 0 : -ENOMEM;
+}
+
+static int process_arch(struct perf_file_section *section __maybe_unused,
+   struct perf_header *ph, int feat __maybe_unused,
+   int fd, void *data __maybe_unused)
+{
+   ph-env.arch = do_read_string(fd, ph);
+   return ph-env.arch ? 0 : -ENOMEM;
+}
+
+static int process_nrcpus(struct perf_file_section *section __maybe_unused,
+ struct perf_header *ph, int feat __maybe_unused,
+ int fd, void *data __maybe_unused)
+{
+   size_t ret;
+   u32 nr;
+
+   ret = read(fd, nr, sizeof(nr));
+   if (ret != sizeof(nr))
+   return -1;
+
+   if (ph-needs_swap)
+   nr = bswap_32(nr);
+
+   ph-env.nr_cpus_online = nr;
+
+   ret = read(fd, nr, sizeof(nr));
+   if (ret != sizeof(nr))
+   return -1;
+
+   if (ph-needs_swap)
+   nr = bswap_32(nr);
+
+   ph-env.nr_cpus_avail = nr;
+   return 0;
+}
+
+static int process_cpudesc(struct perf_file_section *section __maybe_unused,
+  struct perf_header *ph, int feat __maybe_unused,
+  int fd, void *data __maybe_unused)
+{
+   ph-env.cpu_desc = do_read_string(fd, ph);
+   return ph-env.cpu_desc ? 0 : -ENOMEM;
+}
+
+static int process_cpuid(struct perf_file_section *section __maybe_unused,
+struct perf_header *ph, int feat __maybe_unused,
+int fd, void *data __maybe_unused)
+{
+   ph-env.cpuid = do_read_string(fd, ph);
+   return ph-env.cpuid ? 0 : -ENOMEM;
+}
+
+static int process_total_mem(struct perf_file_section *section __maybe_unused,
+struct perf_header *ph, int feat __maybe_unused,
+int fd, void *data __maybe_unused)
+{
+   uint64_t mem;
+   size_t ret;
+
+   ret = read(fd, mem, sizeof(mem));
+   if (ret != sizeof(mem))
+   return -1;
+
+   if (ph-needs_swap)
+   mem = bswap_64(mem);
+
+   ph-env.total_mem = mem;
+   return 0;
+}
+
 static char *read_cpuid(struct perf_header *ph, int fd)
 {
return do_read_string(fd, ph);
@@ -1728,6 +1822,208 @@ process_event_desc(struct perf_file_section *section 
__maybe_unused,
return 0;
 }
 
+static int process_cmdline(struct perf_file_section *section __maybe_unused,
+  struct perf_header *ph, int feat __maybe_unused,
+  int fd, void *data __maybe_unused)
+{
+   size_t ret;
+   char *str;
+   u32 nr, i;
+   struct strbuf sb;
+
+   ret = read(fd, nr, sizeof(nr));
+   if (ret != sizeof(nr))
+   return -1;
+
+   if (ph-needs_swap)
+   nr = bswap_32(nr);
+
+   ph-env.nr_cmdline = nr;
+   strbuf_init(sb, 128);
+
+   for (i = 0; i  nr; i++) {
+   str = do_read_string(fd, ph);
+   if (!str)
+   goto error;
+
+   /* include a NULL character at the end */
+   strbuf_add(sb, str, strlen(str) + 1);
+   free(str);
+   }
+   ph

[PATCH 6/6] perf header: Remove perf_header__read_feature

2012-09-24 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Because its only user builtin-kvm::get_cpu_isa() has gone, It can be
removed safely.  In general, we have the feature information in
perf_session_env already, no need to read it again.

Cc: David Ahern dsah...@gmail.com
Cc: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Cc: Dong Hao haod...@linux.vnet.ibm.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/header.c | 60 +---
 tools/perf/util/header.h |  1 -
 2 files changed, 1 insertion(+), 60 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 4b028df83a40..6aae3290358e 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1690,11 +1690,6 @@ static int process_total_mem(struct perf_file_section 
*section __maybe_unused,
return 0;
 }
 
-static char *read_cpuid(struct perf_header *ph, int fd)
-{
-   return do_read_string(fd, ph);
-}
-
 static struct perf_evsel *
 perf_evlist__find_by_index(struct perf_evlist *evlist, int idx)
 {
@@ -1952,7 +1947,6 @@ error:
 struct feature_ops {
int (*write)(int fd, struct perf_header *h, struct perf_evlist *evlist);
void (*print)(struct perf_header *h, int fd, FILE *fp);
-   char *(*read)(struct perf_header *h, int fd);
int (*process)(struct perf_file_section *section,
   struct perf_header *h, int fd, void *data);
const char *name;
@@ -1967,10 +1961,6 @@ struct feature_ops {
 #define FEAT_OPF(n, func) \
[n] = { .name = #n, .write = write_##func, .print = print_##func, \
.process = process_##func, .full_only = true }
-#define FEAT_OPA_R(n, func) \
-   [n] = { .name = #n, .write = write_##func, .print = print_##func, \
-   .read  = read_##func, .process = process_##func, \
-   .full_only = true }
 
 /* feature_ops not implemented: */
 #define print_tracing_data NULL
@@ -1985,7 +1975,7 @@ static const struct feature_ops 
feat_ops[HEADER_LAST_FEATURE] = {
FEAT_OPP(HEADER_ARCH,   arch),
FEAT_OPP(HEADER_NRCPUS, nrcpus),
FEAT_OPP(HEADER_CPUDESC,cpudesc),
-   FEAT_OPA_R(HEADER_CPUID,cpuid),
+   FEAT_OPP(HEADER_CPUID,  cpuid),
FEAT_OPP(HEADER_TOTAL_MEM,  total_mem),
FEAT_OPP(HEADER_EVENT_DESC, event_desc),
FEAT_OPP(HEADER_CMDLINE,cmdline),
@@ -2040,54 +2030,6 @@ int perf_header__fprintf_info(struct perf_session 
*session, FILE *fp, bool full)
return 0;
 }
 
-struct header_read_data {
-   int feat;
-   char *result;
-};
-
-static int perf_file_section__read_feature(struct perf_file_section *section,
-   struct perf_header *ph,
-   int feat, int fd, void *data)
-{
-   struct header_read_data *hd = data;
-
-   if (feat != hd-feat)
-   return 0;
-
-   if (lseek(fd, section-offset, SEEK_SET) == (off_t)-1) {
-   pr_debug(Failed to lseek to % PRIu64  offset for feature 
-   %d, continuing...\n, section-offset, feat);
-   return 0;
-   }
-
-   if (feat = HEADER_LAST_FEATURE) {
-   pr_warning(unknown feature %d\n, feat);
-   return 0;
-   }
-
-   if (!feat_ops[feat].read) {
-   pr_warning(read is not supported for feature %d\n, feat);
-   return 0;
-   }
-
-   hd-result = feat_ops[feat].read(ph, fd);
-   return 0;
-}
-
-char *perf_header__read_feature(struct perf_session *session, int feat)
-{
-   struct perf_header *header = session-header;
-   struct header_read_data hd;
-   int fd = session-fd;
-
-   hd.feat = feat;
-   hd.result = NULL;
-
-   perf_header__process_sections(header, fd, hd,
-   perf_file_section__read_feature);
-   return hd.result;
-}
-
 static int do_write_feat(int fd, struct perf_header *h, int type,
 struct perf_file_section **p,
 struct perf_evlist *evlist)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 5867c7d74f97..99bdd3abce59 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -118,7 +118,6 @@ int perf_header__process_sections(struct perf_header 
*header, int fd,
  int feat, int fd, void *data));
 
 int perf_header__fprintf_info(struct perf_session *s, FILE *fp, bool full);
-char *perf_header__read_feature(struct perf_session *session, int feat);
 
 int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
  const char *name, bool is_kallsyms, bool is_vdso);
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http

[PATCH 5/6] perf kvm: Use perf_session_env for reading cpuid

2012-09-24 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

We have processed and saved cpuid information to perf_session_env
so reuse it for get_cpu_isa().

Cc: David Ahern dsah...@gmail.com
Cc: Xiao Guangrong xiaoguangr...@linux.vnet.ibm.com
Cc: Dong Hao haod...@linux.vnet.ibm.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-kvm.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 819af25a9a11..b76b3aa14ffd 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -664,16 +664,9 @@ static struct perf_tool eops = {
 
 static int get_cpu_isa(struct perf_session *session)
 {
-   char *cpuid;
+   char *cpuid = session-header.env.cpuid;
int isa;
 
-   cpuid = perf_header__read_feature(session, HEADER_CPUID);
-
-   if (!cpuid) {
-   pr_err(read HEADER_CPUID failed.\n);
-   return -ENOTSUP;
-   }
-
if (strstr(cpuid, Intel))
isa = 1;
else if (strstr(cpuid, AMD))
@@ -683,7 +676,6 @@ static int get_cpu_isa(struct perf_session *session)
isa = -ENOTSUP;
}
 
-   free(cpuid);
return isa;
 }
 
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] block: makes bio_split support bio without data

2012-09-24 Thread Namhyung Kim
Hi,

On Mon, 24 Sep 2012 14:56:39 +1000, NeilBrown wrote:
 Hi Jens,
  this patch has been sitting in my -next tree for a little while and I was
  hoping for it to go in for the next merge window.
  It simply allows bio_split() to be used on bios without a payload, such as
  'discard'.
  Are you happy with it going in though my 'md' tree, or would you rather take
  it though your 'block' tree?

 Thanks,
 NeilBrown


 From: Shaohua Li s...@fusionio.com
 Date: Thu, 20 Sep 2012 09:36:03 +1000
 Subject: [PATCH] block: makes bio_split support bio without data

 discard bio hasn't data attached. We hit a BUG_ON with such bio. This makes
 bio_split works for such bio.

 Signed-off-by: Shaohua Li s...@fusionio.com
 Signed-off-by: NeilBrown ne...@suse.de

 diff --git a/fs/bio.c b/fs/bio.c
 index 71072ab..dbb7a6c 100644
 --- a/fs/bio.c
 +++ b/fs/bio.c
 @@ -1501,7 +1501,7 @@ struct bio_pair *bio_split(struct bio *bi, int 
 first_sectors)
   trace_block_split(bdev_get_queue(bi-bi_bdev), bi,
   bi-bi_sector + first_sectors);
  
 - BUG_ON(bi-bi_vcnt != 1);
 + BUG_ON(bi-bi_vcnt != 1  bi-bi_vcnt != 0);

Why not
BUG_ON(bi-bi_vcnt  1);
?

Thanks,
Namhyung


   BUG_ON(bi-bi_idx != 0);
   atomic_set(bp-cnt, 3);
   bp-error = 0;
 @@ -1511,17 +1511,19 @@ struct bio_pair *bio_split(struct bio *bi, int 
 first_sectors)
   bp-bio2.bi_size -= first_sectors  9;
   bp-bio1.bi_size = first_sectors  9;
  
 - bp-bv1 = bi-bi_io_vec[0];
 - bp-bv2 = bi-bi_io_vec[0];
 - bp-bv2.bv_offset += first_sectors  9;
 - bp-bv2.bv_len -= first_sectors  9;
 - bp-bv1.bv_len = first_sectors  9;
 + if (bi-bi_vcnt != 0) {
 + bp-bv1 = bi-bi_io_vec[0];
 + bp-bv2 = bi-bi_io_vec[0];
 + bp-bv2.bv_offset += first_sectors  9;
 + bp-bv2.bv_len -= first_sectors  9;
 + bp-bv1.bv_len = first_sectors  9;
  
 - bp-bio1.bi_io_vec = bp-bv1;
 - bp-bio2.bi_io_vec = bp-bv2;
 + bp-bio1.bi_io_vec = bp-bv1;
 + bp-bio2.bi_io_vec = bp-bv2;
  
 - bp-bio1.bi_max_vecs = 1;
 - bp-bio2.bi_max_vecs = 1;
 + bp-bio1.bi_max_vecs = 1;
 + bp-bio2.bi_max_vecs = 1;
 + }
  
   bp-bio1.bi_end_io = bio_pair_end_1;
   bp-bio2.bi_end_io = bio_pair_end_2;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 1/9] perf hists: Move hists_init() from util/evsel.c to util/hist.c

2012-09-24 Thread Namhyung Kim
On Mon, 24 Sep 2012 13:02:39 -0300, Arnaldo Carvalho de Melo wrote:
 Em Mon, Sep 24, 2012 at 11:24:03PM +0800, Feng Tang escreveu:
 Which looks more natural

 It is there to avoid dragging the hist code into the python binding :-\

Hmm... it's so hairy.  Can't we do better?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/9] perf script: Add more filter to find_scripts()

2012-09-24 Thread Namhyung Kim
Hi Feng,

On Mon, 24 Sep 2012 23:24:05 +0800, Feng Tang wrote:
 As suggested by Arnaldo, many scripts have their own usages and need
 capture specific events or tracepoints, so only those scripts whose
 targe events match the events in current perf data file should be
 listed in the script browser menu.

 This patch will add the event match checking.

 Signed-off-by: Feng Tang feng.t...@intel.com
 ---
  tools/perf/builtin-script.c |   76 
 +--
  1 files changed, 73 insertions(+), 3 deletions(-)

 diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
 index 4e2f10f..37a0df8 100644
 --- a/tools/perf/builtin-script.c
 +++ b/tools/perf/builtin-script.c
 @@ -1031,6 +1031,63 @@ static int list_available_scripts(const struct option 
 *opt __maybe_unused,
  }
  
  /*
 + * Some scripts specify the required events in their xxx-record file,
 + * this function will check if the events in perf.data match those
 + * mentioned in the xxx-record.
 + */
 +static int check_ev_match(char *dir_name, char *scriptname,
 + struct perf_session *session)
 +{
 + char filename[MAXPATHLEN], evname[128];
 + char line[BUFSIZ], *p, *temp;
 + struct perf_evsel *pos;
 + int match;
 + FILE *fp;
 +
 + sprintf(filename, %s/bin/%s-record, dir_name, scriptname);
 +
 + fp = fopen(filename, r);
 + if (!fp)
 + return -1;
 +
 + while (fgets(line, sizeof(line), fp)) {
 + p = ltrim(line);
 + if (strlen(p) == 0 ||*p == '#')
 + continue;
 +
 + while (strlen(p)) {
 + temp = strstr(p, -e);
 + if (!temp)
 + break;
 +
 + p = temp + 3;
 + temp = strchr(p, ' ');
 + snprintf(evname, (temp - p) + 1, %s, p);

It can't recognize extra spaces, multiple events connected by commas,
event groups and probably more..  So I think it'd better if we can use
parse_events() here - but w/o an evlist.  Jiri, what do you think?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 7/9] perf header: Add check_perf_magic() func

2012-09-24 Thread Namhyung Kim
On Mon, 24 Sep 2012 23:24:09 +0800, Feng Tang wrote:
[snip]
 +/* Return 0 if matched */
 +int check_perf_magic(u64 magic)
 +{
 + if (!memcmp(magic, __perf_magic1, sizeof(magic))
 + || magic == __perf_magic2
 + || magic == __perf_magic2_sw)
 + return 0;
 +
 + return -1;
 +}

Just an idea.  How about returning version number instead of 0 so that
it can be used elsewhere those check is needed and possibly wants to
know the version number also?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 8/9] perf hists browser: Add option for runtime switching perf data file

2012-09-24 Thread Namhyung Kim
On Mon, 24 Sep 2012 23:24:10 +0800, Feng Tang wrote:
[snip]
 + if (!check_perf_magic(magic)) {
 + options[nr_options] = strdup(name);
 + abs_path[nr_options++] = strdup(path);

Need to check return values.


 + }
 + fclose(file);
 + }
 + closedir(pwd_dir);
 +
 + if (nr_options) {
 + choice = ui__popup_menu(nr_options, options);
 + if (choice  nr_options  choice = 0) {
 + input_name = strdup(abs_path[choice]);

Ditto.  Plus it might leak previous input_name.

Thanks,
Namhyung


 + ret = 0;
 + }
 + }
 +
 + free_popup_options(options, nr_options);
 + free_popup_options(abs_path, nr_options);
 + return ret;
 +}
 +
 +
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] perf test: Fix build failure

2012-09-24 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

The commit 6a6cd11d4e57 (perf test: Add test for the sched tracepoint
format fields) added following build error:

  CC builtin-test.o
builtin-test.c: In function ‘perf_evsel__test_field’:
builtin-test.c:1216:6: error: variable ‘ret’ set but not used 
[-Werror=unused-but-set-variable]
builtin-test.c: In function ‘perf_evsel__tp_sched_test’:
builtin-test.c:1242:6: error: variable ‘ret’ set but not used 
[-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors
make: *** [builtin-test.o] Error 1

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-test.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 32caf13cfe01..78b47a75a7c9 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -1233,7 +1233,7 @@ static int perf_evsel__test_field(struct perf_evsel 
*evsel, const char *name,
ret = -1;
}
 
-   return 0;
+   return ret;
 }
 
 static int perf_evsel__tp_sched_test(void)
@@ -1286,7 +1286,7 @@ static int perf_evsel__tp_sched_test(void)
if (perf_evsel__test_field(evsel, target_cpu, 4, true))
ret = -1;
 
-   return 0;
+   return ret;
 }
 
 static struct test {
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] perf session: Add perf_session__delete_env

2012-09-24 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

The perf session environment information was saved (so allocated)
during perf_session__open, but was not freed.  As free(3) handles NULL
pointer input properly it won't cause a issue for writing modes -
e.g. perf record.

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/session.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 3049b0ae7003..568037750d12 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -204,11 +204,30 @@ static void perf_session__delete_threads(struct 
perf_session *session)
machine__delete_threads(session-host_machine);
 }
 
+static void perf_session__delete_env(struct perf_session *self)
+{
+   struct perf_session_env *env = self-header.env;
+
+   free(env-hostname);
+   free(env-os_release);
+   free(env-version);
+   free(env-arch);
+   free(env-cpu_desc);
+   free(env-cpuid);
+
+   free(env-cmdline);
+   free(env-sibling_cores);
+   free(env-sibling_threads);
+   free(env-numa_nodes);
+   free(env-pmu_mappings);
+}
+
 void perf_session__delete(struct perf_session *self)
 {
perf_session__destroy_kernel_maps(self);
perf_session__delete_dead_threads(self);
perf_session__delete_threads(self);
+   perf_session__delete_env(self);
machine__exit(self-host_machine);
close(self-fd);
free(self);
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 27/30] tools lib traceevent: Carve out events format parsing routine

2012-09-24 Thread Namhyung Kim
On Mon, 24 Sep 2012 12:59:41 -0300, Arnaldo Carvalho de Melo wrote:
 From: Arnaldo Carvalho de Melo a...@redhat.com

 The pevent_parse_event() routine will parse a events/sys/tp/format file
 and add an event_format instance to the pevent struct.

 This patch introduces a pevent_parse_format() routine with just the bits
 needed to parse the event/sys/tp/format file and just return the
 event_format instance, useful for when all we want is to parse the
 format file, without requiring the pevent struct.
[snip]
 +enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf,
 +  unsigned long size, const char *sys)
 +{
 + struct event_format *event = NULL;
 + int ret = __pevent_parse_format(event, pevent, buf, size, sys);
 +
 + if (event == NULL)
 + return ret;
 +
 + /* Add pevent to event so that it can be referenced */
 + event-pevent = pevent;
 +
 + if (add_event(pevent, event))
 + goto event_add_failed;

It seems we should set the 'ret' to a proper pevent_errno -
PEVENT_ERRNO__MEM_ALLOC_FAILED.


 +
 +#define PRINT_ARGS 0
 + if (PRINT_ARGS  event-print_fmt.args)
 + print_args(event-print_fmt.args);
 +
 + return 0;
 +
 +event_add_failed:
 + free(event-system);
 + free(event-name);
 + free(event);

At this point, the 'event' also has fields and format information and
they all need to be freed.  Looks like calling pevent_free_format()
would be the right thing IMHO.

Thanks,
Namhyung

   return ret;
  }
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 28/30] perf evsel: Provide a new constructor for tracepoints

2012-09-24 Thread Namhyung Kim
On Mon, 24 Sep 2012 12:59:42 -0300, Arnaldo Carvalho de Melo wrote:
 From: Arnaldo Carvalho de Melo a...@redhat.com

 The existing constructor receives a perf_event_attr filled with the
 event type and the config.

 To reduce the boilerplate for tracepoints, provide a new constructor,
 perf_evsel__newtp() that receives the tracepoint name and will open
 the debugfs file, call into libtraceevent new pevent_parse_format file
 to fill its -tp_format member, so that users can then just call
 perf_evsel__field() to access its fields.
[snip]
 +static struct event_format *event_format__new(const char *sys, const char 
 *name)
 +{
 + int fd, n;
 + char *filename;
 + void *bf = NULL, *nbf;
 + size_t size = 0, alloc_size = 0;
 + struct event_format *format = NULL;
 +
 + if (asprintf(filename, %s/%s/%s/format, tracing_events_path, sys, 
 name)  0)
 + goto out;
 +
 + fd = open(filename, O_RDONLY);
 + if (fd  0)
 + goto out_free_filename;
 +
 + do {
 + if (size == alloc_size) {
 + alloc_size += BUFSIZ;
 + nbf = realloc(bf, alloc_size);
 + if (nbf == NULL)
 + goto out_free_bf;
 + bf = nbf;
 + }
 +
 + n = read(fd, bf + size, BUFSIZ);

Wouldn't it be better doing s/BUFSIZ/alloc_size - size/ ?  Although
there'll be no partial reading issue when working on debugfs I guess.

Thanks,
Namhyung


 + if (n  0)
 + goto out_free_bf;
 + size += n;
 + } while (n  0);
 +
 + pevent_parse_format(format, bf, size, sys);
 +
 +out_free_bf:
 + free(bf);
 + close(fd);
 +out_free_filename:
 + free(filename);
 +out:
 + return format;
 +}
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 29/30] perf test: Add test for the sched tracepoint format fields

2012-09-24 Thread Namhyung Kim
On Mon, 24 Sep 2012 12:59:43 -0300, Arnaldo Carvalho de Melo wrote:
 From: Arnaldo Carvalho de Melo a...@redhat.com

 So that we make sure the routines that do event format parsing are
 working on at least two well know scheduler tracepoints.

It caused a build error and I posted a fix, please see:

https://lkml.org/lkml/2012/9/24/689

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC/PATCHSET 00/15] perf report: Add support to accumulate hist periods

2012-09-24 Thread Namhyung Kim
Ping.  Any comments for this?

Arun, thanks for testing!
Namhyung


On Thu, 13 Sep 2012 16:19:56 +0900, Namhyung Kim wrote:
 Hi,

 This is my first attempt to implement cumulative hist period report.
 This work begins from Arun's SORT_INCLUSIVE patch [1] but I completely
 rewrote it from scratch.

 It basically adds period in a sample to every node in the callchain.
 A hist_entry now has an additional fields to keep the cumulative
 period if --cumulate option is given on perf report.

 Let me show you an example:

   $ cat abc.c
   #define barrier() asm volatile( ::: memory)
   
   void a(void)
   {
   int i;
   
   for (i = 0; i  100; i++)
   barrier();
   }
   
   void b(void)
   {
   a();
   }
   
   void c(void)
   {
   b();
   }
   
   int main(void)
   {
   c();
   
   return 0;
   }
   
 With this simple program I ran perf record and report:

   $ perf record -g -e cycles:u ./abc
   $ perf report -g none --stdio
   [snip]
   # Overhead  Command   Shared Object  Symbol
   #   ...  ..  ..
   #
   93.35%  abc  abc [.] a 
5.17%  abc  ld-2.15.so  [.] _dl_map_object_from_fd
1.13%  abc  ld-2.15.so  [.] _dl_start 
0.29%  abc  libpthread-2.15.so  [.] __libc_close  
0.07%  abc  [kernel.kallsyms]   [k] page_fault
0.00%  abc  ld-2.15.so  [.] _start
   
 When --cumulate option is given, it'll be shown like this:

$ perf report --cumulate
(...)
+  93.63%  abc  libc-2.15.so[.] __libc_start_main
+  93.35%  abc  abc [.] main
+  93.35%  abc  abc [.] c
+  93.35%  abc  abc [.] b
+  93.35%  abc  abc [.] a
+   5.17%  abc  ld-2.15.so  [.] _dl_map_object
+   5.17%  abc  ld-2.15.so  [.] _dl_map_object_from_fd
+   1.13%  abc  ld-2.15.so  [.] _dl_start_user
+   1.13%  abc  ld-2.15.so  [.] _dl_start
+   0.29%  abc  perf[.] main
+   0.29%  abc  perf[.] run_builtin
+   0.29%  abc  perf[.] cmd_record
+   0.29%  abc  libpthread-2.15.so  [.] __libc_close
+   0.07%  abc  ld-2.15.so  [.] _start
+   0.07%  abc  [kernel.kallsyms]   [k] page_fault

 (This output came from TUI since stdio bothered by callchains)

 As you can see __libc_start_main - main - c - b - a callchain show
 up in the output.

 It might have some rough edges or even bugs, but I really want to
 release it and get reviews.  In fact I saw some very large percentage
 or 'inf' on some callchain nodes when expanding.

 It currently ignores samples don't have symbol info when accumulating
 periods along the callchain.  Otherwise it resulted in very strangely
 large output since every node in the callchain would be added into a
 single entry which has NULL dso/sym.  Simply ignoring them solved the
 problem and I couldn't come up with a better solution.

 This patchset is based on current acme/perf/core + my small fixes [2],[3].
 You can also get this series on my tree at:

   git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git  
 perf/cumulate-v1

 Any comments are welcome, thanks.
 Namhyung

 [1] https://lkml.org/lkml/2012/3/31/6
 [2] https://lkml.org/lkml/2012/9/11/546
 [3] https://lkml.org/lkml/2012/9/12/51


 Namhyung Kim (15):
   perf hists: Add missing period_* fields when collapsing a hist entry
   perf hists: Introduce struct he_stat
   perf hists: Move he-stat.nr_events initialization to a template
   perf hists: Convert hist entry functions to use struct he_stat
   perf hists: Add more helpers for hist entry stat
   perf hists: Add support for accumulated stat of hist entry
   perf hists: Check if accumulated when adding a hist entry
   perf callchain: Add a couple of callchain helpers
   perf hists: Let add_hist_entry to make a hist entry template
   perf hists: Accumulate hist entry stat based on the callchain
   perf hists: Sort hist entries by accumulated period
   perf ui/hist: Add support to accumulated hist stat
   perf ui/browser: Add support to accumulated hist stat
   perf ui/gtk: Add support to accumulated hist stat
   perf report: Add --cumulate option

  tools/perf/builtin-report.c|   8 ++
  tools/perf/ui/browsers/hists.c |  12 +-
  tools/perf/ui/gtk/browser.c|   5 +-
  tools/perf/ui/hist.c   |  74 ++---
  tools/perf/ui/stdio/hist.c |   2 +-
  tools/perf/util/callchain.c|  15 +++
  tools/perf/util/callchain.h|  17 +++
  tools/perf/util/hist.c | 242 
 +
  tools/perf/util/sort.h |  17 ++-
  tools/perf/util/symbol.h   |   1 +
  10 files changed, 318 insertions(+), 75 deletions(-)
--
To unsubscribe from this list: send the line

Re: [PATCH 3/3] perf ui/browser: Fix stale output of sorted result

2012-09-24 Thread Namhyung Kim
Hi Arnaldo,

It seems it's not merged into your tree as I still can see this issue.
Would you consider applying?

Thanks,
Namhyung


On Fri, 14 Sep 2012 17:35:29 +0900, Namhyung Kim wrote:
 From: Namhyung Kim namhyung@lge.com

 The hist_entry__sort_snprintf() can return 0 if all of the sort keys
 are elided.  In this case a buffer which used for the function would
 contain old message or a garbage and printed like below:

   $ perf record -g -e cycles:u abc
   $ perf --report -s comm -c abc
   (...)
   + 100.00%100.00%

 Fix it by checking return value.

 Signed-off-by: Namhyung Kim namhy...@kernel.org
 ---
  tools/perf/ui/browsers/hists.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

 diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
 index a21f40bebbac..75b3898ca651 100644
 --- a/tools/perf/ui/browsers/hists.c
 +++ b/tools/perf/ui/browsers/hists.c
 @@ -664,8 +664,8 @@ static int hist_browser__show_entry(struct hist_browser 
 *browser,
   if (!browser-b.navkeypressed)
   width += 1;
  
 - hist_entry__sort_snprintf(entry, s, sizeof(s), browser-hists);
 - slsmg_write_nstring(s, width);
 + if (hist_entry__sort_snprintf(entry, s, sizeof(s), 
 browser-hists))
 + slsmg_write_nstring(s, width);
   ++row;
   ++printed;
   } else
 @@ -981,7 +981,6 @@ static int hist_browser__fprintf_entry(struct 
 hist_browser *browser,
   if (symbol_conf.use_callchain)
   folded_sign = hist_entry__folded(he);
  
 - hist_entry__sort_snprintf(he, s, sizeof(s), browser-hists);
   percent = (he-period * 100.0) / browser-hists-stats.total_period;
  
   if (symbol_conf.use_callchain)
 @@ -995,7 +994,8 @@ static int hist_browser__fprintf_entry(struct 
 hist_browser *browser,
   if (symbol_conf.show_total_period)
   printed += fprintf(fp,  %12 PRIu64, he-period);
  
 - printed += fprintf(fp, %s\n, rtrim(s));
 + if (hist_entry__sort_snprintf(he, s, sizeof(s), browser-hists))
 + printed += fprintf(fp, %s\n, rtrim(s));
  
   if (folded_sign == '-')
   printed += hist_browser__fprintf_callchain(browser, 
 he-sorted_chain, 1, fp);
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] fix compilation error of perf/core

2012-09-25 Thread Namhyung Kim
Hi Dong,

On Tue, 25 Sep 2012 16:21:25 +0800, Dong Hao wrote:
 From: Dong Hao haod...@linux.vnet.ibm.com

 The newest branch of perf/core should have compilation error!
 Error log includes:

 builtin-test.c: In function ‘perf_evsel__test_field’:
 builtin-test.c:1216:6: error:
  variable ‘ret’ set but not used [-Werror=unused-but-set-variable]
 builtin-test.c: In function ‘perf_evsel__tp_sched_test’:
 builtin-test.c:1242:6: error:
  variable ‘ret’ set but not used [-Werror=unused-but-set-variable]
 cc1: all warnings being treated as errors
 make: *** [builtin-test.o] Error 1
 -
 Fix it by replacing return value from 0 to ret.
 Then this branch can be compiled successfully.

 Signed-off-by: Dong Hao haod...@linux.vnet.ibm.com

I already sent the same patch:

  https://lkml.org/lkml/2012/9/24/689


Thanks for fixing it anyway!
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] tools lib traceevent: Fix error path on pevent_parse_event

2012-09-25 Thread Namhyung Kim
If __pevent_parse_format() succeeded but add_event() failed, 'ret' didn't
have a proper error code.  Set it to PEVENT_ERRNO__MEM_ALLOC_FAILED.

In addition, at that point 'event' also has fields and format information
and they all need to be freed.  Call pevent_free_format() to handle it.

Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/lib/traceevent/event-parse.c |8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c 
b/tools/lib/traceevent/event-parse.c
index 17c922145e88..47264b4652b9 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5044,8 +5044,10 @@ enum pevent_errno pevent_parse_event(struct pevent 
*pevent, const char *buf,
/* Add pevent to event so that it can be referenced */
event-pevent = pevent;
 
-   if (add_event(pevent, event))
+   if (add_event(pevent, event)) {
+   ret = PEVENT_ERRNO__MEM_ALLOC_FAILED;
goto event_add_failed;
+   }
 
 #define PRINT_ARGS 0
if (PRINT_ARGS  event-print_fmt.args)
@@ -5054,9 +5056,7 @@ enum pevent_errno pevent_parse_event(struct pevent 
*pevent, const char *buf,
return 0;
 
 event_add_failed:
-   free(event-system);
-   free(event-name);
-   free(event);
+   pevent_free_format(event);
return ret;
 }
 
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 1/9] perf hists: Move hists_init() from util/evsel.c to util/hist.c

2012-09-25 Thread Namhyung Kim
2012-09-25 (화), 08:05 -0300, Arnaldo Carvalho de Melo:
 Em Tue, Sep 25, 2012 at 10:25:13AM +0900, Namhyung Kim escreveu:
  On Mon, 24 Sep 2012 13:02:39 -0300, Arnaldo Carvalho de Melo wrote:
   Em Mon, Sep 24, 2012 at 11:24:03PM +0800, Feng Tang escreveu:
   Which looks more natural
  
   It is there to avoid dragging the hist code into the python binding :-\
  
  Hmm... it's so hairy.  Can't we do better?
 
 We always can do better :-)
 
 I just stated why it was at that place.
 
 When doing refactorings we're all the time trying to make it better in
 many senses, one of them is trying to isolate code that is useful in a
 general way and thus should be made available via a library/scripting
 binding.

Yeah, but the isolation sometimes got broken as code getting added like
this.  So we need a automatic way of detecting breakage.

I thought about adding a perf test entry running python/twatch.py, but
it will not work for an installed perf binary since it cannot find the
twatch.py script and perf.so extension files which are not installed.

Now I'm thinking of making it build-time test so that it can be executed
by make when specific argument is given - e.g. make C=1 ?

Thanks
Namhyung


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/4] perf annotate: configure objdump path at compile time

2012-09-25 Thread Namhyung Kim
Hi Irina,

2012-09-23 (일), 22:27 +0300, Irina Tirdea:
 From: Irina Tirdea irina.tir...@intel.com
 
 The default name for objdump is objdump. For cross-compiling the name of
 objdump will be different (e.g. arm-eabi-objdump in Android).
 
 Set the default objdump name in the Makefile with DEFAULT_OBJDUMP_PATH.

I thought about it twice and confused.

For cross-compiling, the resulting perf binary will run on target - say
Android - but the toolchain runs on host, right?  So with this change
the cross-built perf will try to find the arm-eabi-objdump on Android.
Is it an intended behavior?  Is there an arm-eabi-objdump on Android?

Thanks,
Namhyung


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: perf tools regression testing was Re: [PATCH v3 1/9] perf hists: Move hists_init() from util/evsel.c to util/hist.c

2012-09-25 Thread Namhyung Kim
2012-09-25 (화), 10:30 -0300, Arnaldo Carvalho de Melo:
 Em Tue, Sep 25, 2012 at 09:59:02PM +0900, Namhyung Kim escreveu:
  Now I'm thinking of making it build-time test so that it can be executed
  by make when specific argument is given - e.g. make C=1 ?
 
 I think there is room for a 'make -C tools/perf check' that would use
 the 'expect' tool to do not just this but also run record, report, etc
 and check its output against what is expected, perf test is ok for
 checking the APIs, but we need a test suite for the actual builtins as
 called from the command line.

Hmm.. we have 'make check' but running it ended up tons of macro
redefinition and unknown attribute warnings from sparse. :/

Thanks,
Namhyung


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 10/16] perf report: Make another loop for output resorting

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Now the event grouping viewing requires collapsing all members in a
group to the leader.  Thus hists__output_resort should be called after
collapsing all entries in evlist.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1da243dfbc3e..7729c1c290e6 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -416,6 +416,11 @@ static int __cmd_report(struct perf_report *rep)
hists-symbol_filter_str = rep-symbol_filter_str;
 
hists__collapse_resort(hists);
+   }
+
+   list_for_each_entry(pos, session-evlist-entries, node) {
+   struct hists *hists = pos-hists;
+
hists__output_resort(hists);
nr_samples += hists-stats.nr_events[PERF_RECORD_SAMPLE];
}
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/16] perf hists: Introduce struct he_stat

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

The struct he_stat is for separating out statistics data of a hist
entry.  It is required for later changes.

It's just a mechanical change and should have no functional
differences.

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/browsers/hists.c |  8 +++
 tools/perf/ui/gtk/browser.c|  2 +-
 tools/perf/ui/hist.c   | 32 +-
 tools/perf/ui/stdio/hist.c |  2 +-
 tools/perf/util/hist.c | 52 +++---
 tools/perf/util/sort.h | 16 -
 6 files changed, 60 insertions(+), 52 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a21f40bebbac..b9b1b173637c 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -569,7 +569,7 @@ static int hist_browser__show_callchain(struct hist_browser 
*browser,
 static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
 struct hist_entry *he) \
 {  \
-   double percent = 100.0 * he-_field / hpp-total_period;\
+   double percent = 100.0 * he-stat._field / hpp-total_period;   \
*(double *)hpp-ptr = percent;  \
return scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);  \
 }
@@ -982,7 +982,7 @@ static int hist_browser__fprintf_entry(struct hist_browser 
*browser,
folded_sign = hist_entry__folded(he);
 
hist_entry__sort_snprintf(he, s, sizeof(s), browser-hists);
-   percent = (he-period * 100.0) / browser-hists-stats.total_period;
+   percent = (he-stat.period * 100.0) / 
browser-hists-stats.total_period;
 
if (symbol_conf.use_callchain)
printed += fprintf(fp, %c , folded_sign);
@@ -990,10 +990,10 @@ static int hist_browser__fprintf_entry(struct 
hist_browser *browser,
printed += fprintf(fp,  %5.2f%%, percent);
 
if (symbol_conf.show_nr_samples)
-   printed += fprintf(fp,  %11u, he-nr_events);
+   printed += fprintf(fp,  %11u, he-stat.nr_events);
 
if (symbol_conf.show_total_period)
-   printed += fprintf(fp,  %12 PRIu64, he-period);
+   printed += fprintf(fp,  %12 PRIu64, he-stat.period);
 
printed += fprintf(fp, %s\n, rtrim(s));
 
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 7ff99ec1d95e..7107edc6c08d 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -49,7 +49,7 @@ static const char *perf_gtk__get_percent_color(double percent)
 static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, 
\
 struct hist_entry *he) 
\
 {  
\
-   double percent = 100.0 * he-_field / hpp-total_period;
\
+   double percent = 100.0 * he-stat._field / hpp-total_period;   
\
const char *markup; 
\
int ret = 0;
\

\
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index e3f8cd46e7d7..d6ddeb10e678 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -20,12 +20,12 @@ static int hpp__width_overhead(struct perf_hpp *hpp 
__maybe_unused)
 
 static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
-   double percent = 100.0 * he-period / hpp-total_period;
+   double percent = 100.0 * he-stat.period / hpp-total_period;
 
if (hpp-ptr) {
struct hists *old_hists = hpp-ptr;
u64 total_period = old_hists-stats.total_period;
-   u64 base_period = he-pair ? he-pair-period : 0;
+   u64 base_period = he-pair ? he-pair-stat.period : 0;
 
if (total_period)
percent = 100.0 * base_period / total_period;
@@ -38,13 +38,13 @@ static int hpp__color_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
 
 static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
-   double percent = 100.0 * he-period / hpp-total_period;
+   double percent = 100.0 * he-stat.period / hpp-total_period;
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
 
if (hpp-ptr) {
struct hists *old_hists = hpp-ptr;
u64 total_period = old_hists-stats.total_period;
-   u64 base_period = he-pair ? he-pair-period : 0;
+   u64 base_period = he-pair ? he-pair-stat.period : 0;
 
if (total_period

[PATCH 05/16] perf tools: Keep group information

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Add a few of group-related field in struct perf_{evlist,evsel} so that
the group information in a evlist can be known easily.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/evlist.c   | 10 --
 tools/perf/util/evlist.h   |  1 +
 tools/perf/util/evsel.h| 10 ++
 tools/perf/util/parse-events.c |  1 +
 tools/perf/util/parse-events.h |  1 +
 tools/perf/util/parse-events.y |  4 
 6 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 892353729c7a..199b6f1c3b22 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -111,20 +111,26 @@ void perf_evlist__splice_list_tail(struct perf_evlist 
*evlist,
 void __perf_evlist__set_leader(struct list_head *list)
 {
struct perf_evsel *evsel, *leader;
+   int count = 0;
 
leader = list_entry(list-next, struct perf_evsel, node);
leader-leader = NULL;
 
list_for_each_entry(evsel, list, node) {
-   if (evsel != leader)
+   if (evsel != leader) {
evsel-leader = leader;
+   evsel-group_idx = count++;
+   }
}
+   leader-nr_members = count;
 }
 
 void perf_evlist__set_leader(struct perf_evlist *evlist)
 {
-   if (evlist-nr_entries)
+   if (evlist-nr_entries) {
+   evlist-nr_groups = 1;
__perf_evlist__set_leader(evlist-entries);
+   }
 }
 
 int perf_evlist__add_default(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 3f2e1e4ccdd5..946a6ada817b 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -21,6 +21,7 @@ struct perf_evlist {
struct list_head entries;
struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
int  nr_entries;
+   int  nr_groups;
int  nr_fds;
int  nr_mmaps;
int  mmap_len;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index bb445d1cbc7b..820f005096c4 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -73,6 +73,10 @@ struct perf_evsel {
int exclude_GH;
struct perf_evsel   *leader;
char*group_name;
+   union {
+   int nr_members;
+   int group_idx;
+   };
 };
 
 struct cpu_map;
@@ -211,4 +215,10 @@ static inline struct perf_evsel *perf_evsel__next(struct 
perf_evsel *evsel)
 {
return list_entry(evsel-node.next, struct perf_evsel, node);
 }
+
+/* Treat a non-group event as a leader */
+static inline bool perf_evsel__is_group_leader(struct perf_evsel *evsel)
+{
+   return evsel-leader == NULL;
+}
 #endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index bf5d033ee1b4..3c52d0ab9270 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -830,6 +830,7 @@ int parse_events(struct perf_evlist *evlist, const char 
*str,
if (!ret) {
int entries = data.idx - evlist-nr_entries;
perf_evlist__splice_list_tail(evlist, data.list, entries);
+   evlist-nr_groups += data.nr_groups;
return 0;
}
 
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index c356e443448d..f6b0254afe17 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -65,6 +65,7 @@ struct parse_events__term {
 struct parse_events_data__events {
struct list_head list;
int idx;
+   int nr_groups;
 };
 
 struct parse_events_data__terms {
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index cd88209e3c58..d14bb507594b 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -122,7 +122,9 @@ group_def:
 PE_NAME '{' events '}'
 {
struct list_head *list = $3;
+   struct parse_events_data__events *data = _data;
 
+   data-nr_groups++;
parse_events__set_leader($1, list);
$$ = list;
 }
@@ -130,7 +132,9 @@ PE_NAME '{' events '}'
 '{' events '}'
 {
struct list_head *list = $2;
+   struct parse_events_data__events *data = _data;
 
+   data-nr_groups++;
parse_events__set_leader(NULL, list);
$$ = list;
 }
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 16/16] perf report: Add --group option

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Add --group option to enable event grouping.  When enabled, all the
group members information will be shown together with the leader.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 3a4bd13340db..034eec9f09f5 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -664,6 +664,8 @@ int cmd_report(int argc, const char **argv, const char 
*prefix __maybe_unused)
   Specify disassembler style (e.g. -M intel for intel 
syntax)),
OPT_BOOLEAN(0, show-total-period, symbol_conf.show_total_period,
Show a column with the sum of periods),
+   OPT_BOOLEAN(0, group, symbol_conf.event_group,
+   Show event group information together),
OPT_CALLBACK_NOOPT('b', branch-stack, sort__branch_mode, ,
use branch records for histogram filling, 
parse_branch_mode),
OPT_STRING(0, objdump, objdump_path, path,
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 15/16] perf report: Show group description when event group is enabled

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

When using event group viewer, it's better to show the group
description rather than the leader information alone.

If a leader did not contain any member, it's a non-group event.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Cc: Pekka Enberg penb...@kernel.org
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c| 18 ++
 tools/perf/ui/browsers/hists.c | 31 +++
 tools/perf/ui/gtk/browser.c| 14 +++---
 tools/perf/util/evsel.c| 25 +
 tools/perf/util/evsel.h|  8 
 5 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 52803a9d3e3e..3a4bd13340db 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -299,6 +299,24 @@ static size_t hists__fprintf_nr_sample_events(struct hists 
*self,
char unit;
unsigned long nr_samples = self-stats.nr_events[PERF_RECORD_SAMPLE];
u64 nr_events = self-stats.total_period;
+   struct perf_evsel *evsel = hists_2_evsel(self);
+   char buf[512];
+   size_t size = sizeof(buf);
+
+   if (symbol_conf.event_group  evsel-nr_members) {
+   int i;
+   struct events_stats *stats;
+
+   perf_evsel__group_desc(evsel, buf, size);
+   evname = buf;
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   stats = self-group_stats[i];
+
+   nr_samples += stats-nr_events[PERF_RECORD_SAMPLE];
+   nr_events += stats-total_period;
+   }
+   }
 
nr_samples = convert_unit(nr_samples, unit);
ret = fprintf(fp, # Samples: %lu%c, nr_samples, unit);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 82d59be3c230..7903b98913c5 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1121,6 +1121,24 @@ static int hists__browser_title(struct hists *hists, 
char *bf, size_t size,
const struct thread *thread = hists-thread_filter;
unsigned long nr_samples = hists-stats.nr_events[PERF_RECORD_SAMPLE];
u64 nr_events = hists-stats.total_period;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+   char buf[512];
+   size_t buflen = sizeof(buf);
+
+   if (symbol_conf.event_group  evsel-nr_members) {
+   int i;
+   struct events_stats *stats;
+
+   perf_evsel__group_desc(evsel, buf, buflen);
+   ev_name = buf;
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   stats = hists-group_stats[i];
+
+   nr_samples += stats-nr_events[PERF_RECORD_SAMPLE];
+   nr_events += stats-total_period;
+   }
+   }
 
nr_samples = convert_unit(nr_samples, unit);
printed = scnprintf(bf, size,
@@ -1467,6 +1485,19 @@ static void perf_evsel_menu__write(struct ui_browser 
*browser,
ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
   HE_COLORSET_NORMAL);
 
+   if (symbol_conf.event_group  evsel-nr_members) {
+   int i;
+   struct events_stats *stats;
+
+   ev_name = perf_evsel__group_name(evsel);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   stats = evsel-hists.group_stats[i];
+
+   nr_events += stats-nr_events[PERF_RECORD_SAMPLE];
+   }
+   }
+
nr_events = convert_unit(nr_events, unit);
printed = scnprintf(bf, sizeof(bf), %lu%c%s%s, nr_events,
   unit, unit == ' ' ?  :  , ev_name);
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 01bfa43db8e2..cb6241e7f9a5 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -305,10 +305,18 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist 
*evlist,
const char *evname = perf_evsel__name(pos);
GtkWidget *scrolled_window;
GtkWidget *tab_label;
+   char buf[512];
+   size_t size = sizeof(buf);
 
-   if (symbol_conf.event_group 
-   !perf_evsel__is_group_leader(pos))
-   continue;
+   if (symbol_conf.event_group) {
+   if (!perf_evsel__is_group_leader(pos))
+   continue;
+
+   if (pos-nr_members) {
+   perf_evsel__group_desc(pos, buf, size);
+   evname = buf;
+   }
+   }
 
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 00936ad29ff2

[PATCH 04/16] perf hists: Add more helpers for hist entry stat

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Add and use he_stat__add_{period,stat} for calculating hist entry's
stat.  It will be used for accumulated stats later as well.

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Stephane Eranian eran...@google.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c | 26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index ef39e6714cbb..c742a723e850 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -151,6 +151,22 @@ static void hist_entry__add_cpumode_period(struct 
hist_entry *he,
}
 }
 
+static void he_stat__add_period(struct he_stat *he_stat, u64 period)
+{
+   he_stat-period += period;
+   he_stat-nr_events  += 1;
+}
+
+static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
+{
+   dest-period+= src-period;
+   dest-period_sys+= src-period_sys;
+   dest-period_us += src-period_us;
+   dest-period_guest_sys  += src-period_guest_sys;
+   dest-period_guest_us   += src-period_guest_us;
+   dest-nr_events += src-nr_events;
+}
+
 static void hist_entry__decay(struct hist_entry *he)
 {
he-stat.period = (he-stat.period * 7) / 8;
@@ -270,8 +286,7 @@ static struct hist_entry *add_hist_entry(struct hists 
*hists,
cmp = hist_entry__cmp(entry, he);
 
if (!cmp) {
-   he-stat.period += period;
-   ++he-stat.nr_events;
+   he_stat__add_period(he-stat, period);
 
/* If the map of an existing hist_entry has
 * become out-of-date due to an exec() or
@@ -416,12 +431,7 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
 
if (!cmp) {
-   iter-stat.period   += he-stat.period;
-   iter-stat.period_sys   += he-stat.period_sys;
-   iter-stat.period_us+= he-stat.period_us;
-   iter-stat.period_guest_sys += 
he-stat.period_guest_sys;
-   iter-stat.period_guest_us  += 
he-stat.period_guest_us;
-   iter-stat.nr_events+= he-stat.nr_events;
+   he_stat__add_stat(iter-stat, he-stat);
 
if (symbol_conf.use_callchain) {
callchain_cursor_reset(callchain_cursor);
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/16] perf hists: Move he-stat.nr_events initialization to a template

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Since it is set to 1 for a new hist entry, no need to set to
separately.  Move it to a template entry.

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Stephane Eranian eran...@google.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index ab3d11491991..ef39e6714cbb 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -223,7 +223,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry 
*template)
 
if (he != NULL) {
*he = *template;
-   he-stat.nr_events = 1;
+
if (he-ms.map)
he-ms.map-referenced = true;
if (symbol_conf.use_callchain)
@@ -323,6 +323,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists 
*self,
.level  = al-level,
.stat = {
.period = period,
+   .nr_events = 1,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
@@ -347,6 +348,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
.level  = al-level,
.stat = {
.period = period,
+   .nr_events = 1,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 14/16] perf report: Bypass non-leader events when event group is enabled

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Since we have all necessary information in the leader events and
other members don't, bypass members.  Member events will be shown
along with the leaders if event group is enabled.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Cc: Pekka Enberg penb...@kernel.org
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c|  4 
 tools/perf/ui/browsers/hists.c | 39 +--
 tools/perf/ui/gtk/browser.c|  4 
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 7729c1c290e6..52803a9d3e3e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -319,6 +319,10 @@ static int perf_evlist__tty_browse_hists(struct 
perf_evlist *evlist,
struct hists *hists = pos-hists;
const char *evname = perf_evsel__name(pos);
 
+   if (symbol_conf.event_group 
+   !perf_evsel__is_group_leader(pos))
+   continue;
+
hists__fprintf_nr_sample_events(hists, evname, stdout);
hists__fprintf(hists, NULL, false, true, 0, 0, stdout);
fprintf(stdout, \n\n);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index da3d1e4a44fa..82d59be3c230 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1576,8 +1576,19 @@ out:
return key;
 }
 
+static bool filter_group_entries(struct ui_browser *self __maybe_unused,
+void *entry)
+{
+   struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
+
+   if (symbol_conf.event_group  !perf_evsel__is_group_leader(evsel))
+   return true;
+
+   return false;
+}
+
 static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
-  const char *help,
+  int nr_entries, const char *help,
   void(*timer)(void *arg), void *arg,
   int delay_secs)
 {
@@ -1588,7 +1599,8 @@ static int __perf_evlist__tui_browse_hists(struct 
perf_evlist *evlist,
.refresh= ui_browser__list_head_refresh,
.seek   = ui_browser__list_head_seek,
.write  = perf_evsel_menu__write,
-   .nr_entries = evlist-nr_entries,
+   .filter = filter_group_entries,
+   .nr_entries = nr_entries,
.priv   = evlist,
},
};
@@ -1603,7 +1615,7 @@ static int __perf_evlist__tui_browse_hists(struct 
perf_evlist *evlist,
menu.b.width = line_len;
}
 
-   return perf_evsel_menu__run(menu, evlist-nr_entries, help, timer,
+   return perf_evsel_menu__run(menu, nr_entries, help, timer,
arg, delay_secs);
 }
 
@@ -1611,15 +1623,30 @@ int perf_evlist__tui_browse_hists(struct perf_evlist 
*evlist, const char *help,
  void(*timer)(void *arg), void *arg,
  int delay_secs)
 {
-   if (evlist-nr_entries == 1) {
+   int nr_entries = evlist-nr_entries;
+
+single_entry:
+   if (nr_entries == 1) {
struct perf_evsel *first = list_entry(evlist-entries.next,
  struct perf_evsel, node);
const char *ev_name = perf_evsel__name(first);
-   return perf_evsel__hists_browse(first, evlist-nr_entries, help,
+   return perf_evsel__hists_browse(first, nr_entries, help,
ev_name, false, timer, arg,
delay_secs);
}
 
-   return __perf_evlist__tui_browse_hists(evlist, help,
+   if (symbol_conf.event_group) {
+   struct perf_evsel *pos;
+
+   nr_entries = 0;
+   list_for_each_entry(pos, evlist-entries, node)
+   if (perf_evsel__is_group_leader(pos))
+   nr_entries++;
+
+   if (nr_entries == 1)
+   goto single_entry;
+   }
+
+   return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
   timer, arg, delay_secs);
 }
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 775f209fe795..01bfa43db8e2 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -306,6 +306,10 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist 
*evlist,
GtkWidget *scrolled_window;
GtkWidget *tab_label;
 
+   if (symbol_conf.event_group

[PATCH 13/16] perf ui/gtk: Add support for event group view

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Show group members' overhead also when showing the leader's if event
group is enabled.  At this time, only implemented overhead part in
order to ease review and other parts can be added later once this
patch settled down.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Cc: Pekka Enberg penb...@kernel.org
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/gtk/browser.c | 58 +++--
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 7107edc6c08d..775f209fe795 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -45,25 +45,56 @@ static const char *perf_gtk__get_percent_color(double 
percent)
return NULL;
 }
 
+static int perf_gtk__percent_color_snprintf(char *buf, size_t size,
+   u64 period, u64 total_period)
+{
+   int ret = 0;
+   const char *markup;
+   double percent = 100.0 * period / total_period;
+
+   markup = perf_gtk__get_percent_color(percent);
+   if (markup)
+   ret += scnprintf(buf, size, markup);
+
+   ret += scnprintf(buf + ret, size - ret, %6.2f%%, percent);
+
+   if (markup)
+   ret += scnprintf(buf + ret, size - ret, /span);
+
+   return ret;
+}
+
+static int perf_gtk__hpp_color_overhead(struct perf_hpp *hpp,
+   struct hist_entry *he)
+{
+   int ret;
+
+   ret = perf_gtk__percent_color_snprintf(hpp-buf, hpp-size,
+  he-stat.period, hpp-total_period);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hpp-hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   ret += scnprintf(hpp-buf + ret, hpp-size - ret,  );
+   ret += perf_gtk__percent_color_snprintf(hpp-buf + ret,
+   hpp-size - ret,
+   he-group_stats[i].period,
+   
hpp-hists-group_stats[i].total_period);
+   }
+   }
+   return ret;
+}
+
 #define HPP__COLOR_FN(_name, _field)   
\
 static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, 
\
 struct hist_entry *he) 
\
 {  
\
-   double percent = 100.0 * he-stat._field / hpp-total_period;   
\
-   const char *markup; 
\
-   int ret = 0;
\
-   
\
-   markup = perf_gtk__get_percent_color(percent);  
\
-   if (markup) 
\
-   ret += scnprintf(hpp-buf, hpp-size, %s, markup);
\
-   ret += scnprintf(hpp-buf + ret, hpp-size - ret, %6.2f%%, percent);  
\
-   if (markup) 
\
-   ret += scnprintf(hpp-buf + ret, hpp-size - ret, /span);   
\
-   
\
-   return ret; 
\
+   return perf_gtk__percent_color_snprintf(hpp-buf, hpp-size,
\
+   he-stat._field, hpp-total_period);
\
 }
 
-HPP__COLOR_FN(overhead, period)
 HPP__COLOR_FN(overhead_sys, period_sys)
 HPP__COLOR_FN(overhead_us, period_us)
 HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
@@ -103,6 +134,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct 
hists *hists)
.buf= s,
.size   = sizeof(s),
.total_period   = hists-stats.total_period,
+   .hists  = hists,
};
 
nr_cols = 0;
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 12/16] perf ui/browser: Add support for event group view

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Show group members' overhead also when showing the leader's if event
group is enabled.  At this time, only implemented overhead part in
order to ease review and other parts can be added later once this
patch settled down.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/browsers/hists.c | 29 -
 tools/perf/ui/hist.c   |  5 -
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index b9b1b173637c..da3d1e4a44fa 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -565,6 +565,33 @@ static int hist_browser__show_callchain(struct 
hist_browser *browser,
return row - first_row;
 }
 
+static int hist_browser__hpp_color_overhead(struct perf_hpp *hpp,
+   struct hist_entry *he)
+{
+   int ret;
+   double percent = 100.0 * he-stat.period / hpp-total_period;
+
+   /* the leader determines color */
+   *(double *) hpp-ptr = percent;
+
+   ret = scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hpp-hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   u64 period = he-group_stats[i].period;
+   u64 total = hpp-hists-group_stats[i].total_period;
+
+   percent = 100.0 * period / total;
+   ret += scnprintf(hpp-buf + ret, hpp-size - ret,
+ %6.2f%%, percent);
+   }
+   }
+   return ret;
+}
+
 #define HPP__COLOR_FN(_name, _field)   \
 static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
 struct hist_entry *he) \
@@ -574,7 +601,6 @@ static int hist_browser__hpp_color_ ## _name(struct 
perf_hpp *hpp,  \
return scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);  \
 }
 
-HPP__COLOR_FN(overhead, period)
 HPP__COLOR_FN(overhead_sys, period_sys)
 HPP__COLOR_FN(overhead_us, period_us)
 HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
@@ -625,6 +651,7 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
.buf= s,
.size   = sizeof(s),
.total_period   = browser-hists-stats.total_period,
+   .hists  = browser-hists,
};
 
ui_browser__gotorc(browser-b, row, 0);
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index b8e97c3577c1..d8491fcff6ee 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -422,6 +422,9 @@ unsigned int hists__sort_list_width(struct hists *hists)
 {
struct sort_entry *se;
int i, ret = 0;
+   struct perf_hpp dummy_hpp = {
+   .hists  = hists,
+   };
 
for (i = 0; i  PERF_HPP__MAX_INDEX; i++) {
if (!perf_hpp__format[i].cond)
@@ -429,7 +432,7 @@ unsigned int hists__sort_list_width(struct hists *hists)
if (i)
ret += 2;
 
-   ret += perf_hpp__format[i].width(NULL);
+   ret += perf_hpp__format[i].width(dummy_hpp);
}
 
list_for_each_entry(se, hist_entry__sort_list, list)
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 11/16] perf ui/hist: Add support for event group view

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Show group members' overhead also when showing the leader's if event
group is enabled.  At this time, only implemented overhead part in
order to ease review and other parts can be added later once this
patch settled down.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/hist.c   | 67 +-
 tools/perf/ui/stdio/hist.c |  2 ++
 tools/perf/util/hist.h |  1 +
 3 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index d6ddeb10e678..b8e97c3577c1 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -3,23 +3,40 @@
 #include ../util/hist.h
 #include ../util/util.h
 #include ../util/sort.h
+#include ../util/evsel.h
 
 
 /* hist period print (hpp) functions */
 static int hpp__header_overhead(struct perf_hpp *hpp)
 {
+   int len = 8;
const char *fmt = hpp-ptr ? Baseline : Overhead;
 
-   return scnprintf(hpp-buf, hpp-size, fmt);
+   if (symbol_conf.event_group) {
+   struct perf_evsel *evsel = hists_2_evsel(hpp-hists);
+
+   BUG_ON(!perf_evsel__is_group_leader(evsel));
+
+   len += evsel-nr_members * 8;
+   }
+   return scnprintf(hpp-buf, hpp-size, %*s, len, fmt);
 }
 
-static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused)
+static int hpp__width_overhead(struct perf_hpp *hpp)
 {
-   return 8;
+   int len = 8;
+
+   if (symbol_conf.event_group) {
+   struct perf_evsel *evsel = hists_2_evsel(hpp-hists);
+
+   len += evsel-nr_members * 8;
+   }
+   return len;
 }
 
 static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
+   int ret;
double percent = 100.0 * he-stat.period / hpp-total_period;
 
if (hpp-ptr) {
@@ -33,11 +50,29 @@ static int hpp__color_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
percent = 0.0;
}
 
-   return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
+   ret = percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hpp-hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   u64 period = he-group_stats[i].period;
+   u64 total = hpp-hists-group_stats[i].total_period;
+
+   percent = 100.0 * period / total;
+   ret += percent_color_snprintf(hpp-buf + ret,
+ hpp-size - ret,
+  %6.2f%%, percent);
+   }
+
+   }
+   return ret;
 }
 
 static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
+   int ret;
double percent = 100.0 * he-stat.period / hpp-total_period;
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
 
@@ -52,13 +87,32 @@ static int hpp__entry_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
percent = 0.0;
}
 
-   return scnprintf(hpp-buf, hpp-size, fmt, percent);
+   ret = scnprintf(hpp-buf, hpp-size, fmt, percent);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hpp-hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   u64 period = he-group_stats[i].period;
+   u64 total = hpp-hists-group_stats[i].total_period;
+
+   if (symbol_conf.field_sep) {
+   ret += scnprintf(hpp-buf + ret,
+hpp-size - ret,  );
+   }
+   percent = 100.0 * period / total;
+   ret += scnprintf(hpp-buf + ret, hpp-size - ret,
+fmt, percent);
+   }
+
+   }
+   return ret;
 }
 
 static int hpp__header_overhead_sys(struct perf_hpp *hpp)
 {
const char *fmt = symbol_conf.field_sep ? %s : %7s;
-
return scnprintf(hpp-buf, hpp-size, fmt, sys);
 }
 
@@ -84,7 +138,6 @@ static int hpp__entry_overhead_sys(struct perf_hpp *hpp, 
struct hist_entry *he)
 static int hpp__header_overhead_us(struct perf_hpp *hpp)
 {
const char *fmt = symbol_conf.field_sep ? %s : %7s;
-
return scnprintf(hpp-buf, hpp-size, fmt, user);
 }
 
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 4382a1995cda..8c417f036613 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -316,6 +316,7 @@ static int hist_entry__fprintf(struct hist_entry *he, 
size_t size,
.buf= bf,
.size   = size

[PATCH 09/16] perf hists: Maintain total periods of group members in the leader

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Like group_stats in hist_entry, total periods information also need to
be known to the leader.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c | 25 +
 tools/perf/util/hist.h |  1 +
 2 files changed, 26 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 319822dee77b..8f01fc46ca88 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -194,6 +194,28 @@ static void hist_entry__add_group_stat(struct hist_entry 
*he_dest,
he_stat__add_stat(he_dest-group_stats[evsel-group_idx], src);
 }
 
+static void hists__add_group_stat(struct hists *hists)
+{
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+   struct perf_evsel *leader = evsel-leader;
+   struct hists *leader_hists;
+
+   if (perf_evsel__is_group_leader(evsel))
+   return;
+
+   leader_hists = leader-hists;
+
+   if (!leader_hists-group_stats) {
+   leader_hists-group_stats = calloc(leader-nr_members,
+  sizeof(struct events_stats));
+   if (!leader_hists-group_stats)
+   return;
+   }
+
+   memcpy(leader_hists-group_stats[evsel-group_idx],
+  hists-stats, sizeof(struct events_stats));
+}
+
 static void hist_entry__decay(struct hist_entry *he)
 {
he-stat.period = (he-stat.period * 7) / 8;
@@ -557,6 +579,9 @@ static void __hists__collapse_resort(struct hists *hists, 
bool threaded)
hists__apply_filters(hists, n);
}
}
+
+   if (symbol_conf.event_group)
+   hists__add_group_stat(hists);
 }
 
 void hists__collapse_resort(struct hists *hists)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index f011ad4756e8..e13db91bc246 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -66,6 +66,7 @@ struct hists {
const char  *symbol_filter_str;
pthread_mutex_t lock;
struct events_stats stats;
+   struct events_stats *group_stats;
u64 event_stream;
u16 col_len[HISTC_NR_COLS];
 };
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 07/16] perf header: Add HEADER_GROUP_DESC feature

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Save group relationship information so that it can be restored when
perf report is running.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-record.c |   3 +
 tools/perf/util/header.c| 149 
 tools/perf/util/header.h|   2 +
 3 files changed, 154 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 99ad5234e6ff..b2d9c0af9a15 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -561,6 +561,9 @@ static int __cmd_record(struct perf_record *rec, int argc, 
const char **argv)
goto out_delete_session;
}
 
+   if (!evsel_list-nr_groups)
+   perf_header__clear_feat(session-header, HEADER_GROUP_DESC);
+
/*
 * perf_session__delete(session) will be called at perf_record__exit()
 */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 6aae3290358e..0039c08ad4c7 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1072,6 +1072,41 @@ static int write_pmu_mappings(int fd, struct perf_header 
*h __maybe_unused,
 }
 
 /*
+ * File format:
+ *
+ * struct group_descs {
+ * u32 nr_groups;
+ * struct group_desc {
+ * charname[];
+ * u32 leader_idx;
+ * u32 nr_members;
+ * }[nr_groups];
+ * };
+ */
+static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
+   struct perf_evlist *evlist)
+{
+   u32 nr_groups = evlist-nr_groups;
+   struct perf_evsel *evsel;
+
+   do_write(fd, nr_groups, sizeof(nr_groups));
+
+   list_for_each_entry(evsel, evlist-entries, node) {
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0) {
+   const char *name = evsel-group_name ?: {anon_group};
+   u32 leader_idx = evsel-idx;
+   u32 nr_members = evsel-nr_members;
+
+   do_write_string(fd, name);
+   do_write(fd, leader_idx, sizeof(leader_idx));
+   do_write(fd, nr_members, sizeof(nr_members));
+   }
+   }
+   return 0;
+}
+
+/*
  * default get_cpuid(): nothing gets recorded
  * actual implementation must be in arch/$(ARCH)/util/header.c
  */
@@ -1430,6 +1465,31 @@ error:
fprintf(fp, # pmu mappings: unable to read\n);
 }
 
+static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,
+FILE *fp)
+{
+   struct perf_session *session;
+   struct perf_evsel *evsel;
+   u32 nr = 0;
+
+   session = container_of(ph, struct perf_session, header);
+
+   list_for_each_entry(evsel, session-evlist-entries, node) {
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0) {
+   fprintf(fp, # group: %s{%s, evsel-group_name ?: ,
+   perf_evsel__name(evsel));
+
+   nr = evsel-nr_members;
+   } else if (nr) {
+   fprintf(fp, ,%s, perf_evsel__name(evsel));
+
+   if (--nr == 0)
+   fprintf(fp, }\n);
+   }
+   }
+}
+
 static int __event_process_build_id(struct build_id_event *bev,
char *filename,
struct perf_session *session)
@@ -1944,6 +2004,94 @@ error:
return -1;
 }
 
+static int process_group_desc(struct perf_file_section *section __maybe_unused,
+ struct perf_header *ph, int fd,
+ void *data __maybe_unused)
+{
+   size_t ret = -1;
+   u32 i, nr, nr_groups;
+   struct perf_session *session;
+   struct perf_evsel *evsel, *leader;
+   struct group_desc {
+   char *name;
+   u32 leader_idx;
+   u32 nr_members;
+   } *desc;
+
+   ret = read(fd, nr_groups, sizeof(nr_groups));
+   if (ret != sizeof(nr_groups))
+   return -1;
+
+   ph-env.nr_groups = nr_groups;
+   if (!nr_groups) {
+   pr_debug(group desc not available\n);
+   return 0;
+   }
+
+   desc = calloc(nr_groups, sizeof(*desc));
+   if (!desc)
+   return -1;
+
+   for (i = 0; i  nr_groups; i++) {
+   desc[i].name = do_read_string(fd, ph);
+   if (!desc[i].name)
+   goto out_free;
+
+   ret = read(fd, desc[i].leader_idx, sizeof(u32));
+   if (ret != sizeof(u32))
+   goto out_free;
+
+   ret = read(fd, desc[i].nr_members, sizeof(u32));
+   if (ret != sizeof(u32))
+   goto out_free

[PATCH 00/16] perf report: Add suppport for event group view (v2)

2012-09-26 Thread Namhyung Kim
Hi,

This is my second attempt to support event group on perf report.
For basic idea and usage example, please see my original post [1].

The main difference than v1 is adding HEADER_GROUP_DESC feature and
use it for regenerating group relationship on perf report.  It will
save actual (i.e. contains non-leader member) group information to
perf header.

Patch 1 is a bug fix which can be applied indenpedently.

Patch 2-4 are cleanups to facilitate later changes and came from my
cumulative report series [2].

You can also access it via my tree at:

git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git  
perf/group-v2

Any comments are welcome, thanks,
Namhyung

v1 - v2:
 * save group relation to header (Jiri)
 * rebase on top of current acme/perf/core


[1] https://lkml.org/lkml/2012/7/24/81
[2] https://lkml.org/lkml/2012/9/13/81

Namhyung Kim (16):
  perf hists: Add missing period_* fields when collapsing a hist entry
  perf hists: Introduce struct he_stat
  perf hists: Move he-stat.nr_events initialization to a template
  perf hists: Add more helpers for hist entry stat
  perf tools: Keep group information
  perf evlist: Add perf_evlist__recalc_nr_groups
  perf header: Add HEADER_GROUP_DESC feature
  perf hists: Collapse group hist_entries to a leader
  perf hists: Maintain total periods of group members in the leader
  perf report: Make another loop for output resorting
  perf ui/hist: Add support for event group view
  perf ui/browser: Add support for event group view
  perf ui/gtk: Add support for event group view
  perf report: Bypass non-leader events when event group is enabled
  perf report: Show group description when event group is enabled
  perf report: Add --group option

 tools/perf/builtin-record.c|   6 ++
 tools/perf/builtin-report.c|  29 +++
 tools/perf/ui/browsers/hists.c | 107 ---
 tools/perf/ui/gtk/browser.c|  70 ---
 tools/perf/ui/hist.c   | 104 +--
 tools/perf/ui/stdio/hist.c |   4 +-
 tools/perf/util/evlist.c   |  26 +-
 tools/perf/util/evlist.h   |   2 +
 tools/perf/util/evsel.c|  25 ++
 tools/perf/util/evsel.h|  23 +
 tools/perf/util/header.c   | 149 
 tools/perf/util/header.h   |   2 +
 tools/perf/util/hist.c | 188 +++--
 tools/perf/util/hist.h |   2 +
 tools/perf/util/parse-events.c |   1 +
 tools/perf/util/parse-events.h |   1 +
 tools/perf/util/parse-events.y |   4 +
 tools/perf/util/sort.h |  17 ++--
 tools/perf/util/symbol.c   |   4 +
 tools/perf/util/symbol.h   |   3 +-
 20 files changed, 683 insertions(+), 84 deletions(-)

-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 08/16] perf hists: Collapse group hist_entries to a leader

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

To support viewing an event group together, collapse all of members in
the group to the leader's tree.  The entries in the leaders' tree will
have group_stats to store those information.

This patch introduced an additional field 'event_group' in symbol_conf
to distinguish whether event grouping is enabled or not.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/evsel.h  |   5 +++
 tools/perf/util/hist.c   | 106 +++
 tools/perf/util/sort.h   |   1 +
 tools/perf/util/symbol.c |   4 ++
 tools/perf/util/symbol.h |   3 +-
 5 files changed, 110 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 820f005096c4..95f0bf17e79c 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -221,4 +221,9 @@ static inline bool perf_evsel__is_group_leader(struct 
perf_evsel *evsel)
 {
return evsel-leader == NULL;
 }
+
+static inline struct perf_evsel *hists_2_evsel(struct hists *hists)
+{
+   return container_of(hists, struct perf_evsel, hists);
+}
 #endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index c742a723e850..319822dee77b 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -4,6 +4,7 @@
 #include hist.h
 #include session.h
 #include sort.h
+#include evsel.h
 #include math.h
 
 static bool hists__filter_entry_by_dso(struct hists *hists,
@@ -167,6 +168,32 @@ static void he_stat__add_stat(struct he_stat *dest, struct 
he_stat *src)
dest-nr_events += src-nr_events;
 }
 
+static void hist_entry__add_group_stat(struct hist_entry *he_dest,
+  struct he_stat *src,
+  struct perf_evsel *evsel)
+{
+   struct perf_evsel *leader = evsel-leader;
+
+   if (perf_evsel__is_group_leader(evsel))
+   leader = evsel;
+
+   if (leader-nr_members  !he_dest-group_stats) {
+   /*
+* A group whose nr_members equals to 0 is a leader-only group.
+* So no need to allocate group_stats.
+*/
+   he_dest-group_stats = calloc(leader-nr_members,
+ sizeof(struct he_stat));
+   if (!he_dest-group_stats)
+   return;
+   }
+
+   if (perf_evsel__is_group_leader(evsel))
+   he_stat__add_stat(he_dest-stat, src);
+   else
+   he_stat__add_stat(he_dest-group_stats[evsel-group_idx], src);
+}
+
 static void hist_entry__decay(struct hist_entry *he)
 {
he-stat.period = (he-stat.period * 7) / 8;
@@ -415,13 +442,14 @@ void hist_entry__free(struct hist_entry *he)
  * collapse the histogram
  */
 
-static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+static bool hists__collapse_insert_entry(struct hists *hists,
 struct rb_root *root,
 struct hist_entry *he)
 {
struct rb_node **p = root-rb_node;
struct rb_node *parent = NULL;
struct hist_entry *iter;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
int64_t cmp;
 
while (*p != NULL) {
@@ -431,7 +459,10 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
 
if (!cmp) {
-   he_stat__add_stat(iter-stat, he-stat);
+   if (symbol_conf.event_group)
+   hist_entry__add_group_stat(iter, he-stat, 
evsel);
+   else
+   he_stat__add_stat(iter-stat, he-stat);
 
if (symbol_conf.use_callchain) {
callchain_cursor_reset(callchain_cursor);
@@ -449,6 +480,17 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
p = (*p)-rb_right;
}
 
+   if (symbol_conf.event_group) {
+   /*
+* 'he' is not found in the leader's tree.
+* Insert it to the tree and setup stats properly.
+*/
+   hist_entry__add_group_stat(he, he-stat, evsel);
+
+   if (!perf_evsel__is_group_leader(evsel))
+   memset(he-stat, 0, sizeof(he-stat));
+   }
+
rb_link_node(he-rb_node_in, parent, p);
rb_insert_color(he-rb_node_in, root);
return true;
@@ -479,6 +521,7 @@ static void hists__apply_filters(struct hists *hists, 
struct hist_entry *he)
 static void __hists__collapse_resort(struct hists *hists, bool threaded)
 {
struct rb_root *root;
+   struct rb_root *dest;
struct rb_node *next;
struct hist_entry *n;
 
@@ -486,14 +529,26 @@ static void

[PATCH 06/16] perf evlist: Add perf_evlist__recalc_nr_groups

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

During the event parsing, perf_evlist can have leader-only groups
which has nr_members as 1.  Since they has no difference than a normal
non-group event don't count them as a event group.

Add perf_evlist__recalc_nr_groups to count actual group numbers.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-record.c |  3 +++
 tools/perf/util/evlist.c| 16 
 tools/perf/util/evlist.h|  1 +
 3 files changed, 20 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 2cb74343de3e..99ad5234e6ff 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -212,6 +212,9 @@ static int perf_record__open(struct perf_record *rec)
if (opts-group)
perf_evlist__set_leader(evlist);
 
+   if (evlist-nr_groups)
+   perf_evlist__recalc_nr_groups(evlist);
+
list_for_each_entry(pos, evlist-entries, node) {
struct perf_event_attr *attr = pos-attr;
/*
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 199b6f1c3b22..0dcc443716b7 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -133,6 +133,22 @@ void perf_evlist__set_leader(struct perf_evlist *evlist)
}
 }
 
+void perf_evlist__recalc_nr_groups(struct perf_evlist *evlist)
+{
+   int count = 0;
+   struct perf_evsel *evsel;
+
+   list_for_each_entry(evsel, evlist-entries, node) {
+   /*
+* Don't count leader-only groups for simplicity.
+*/
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0)
+   count++;
+   }
+   evlist-nr_groups = count;
+}
+
 int perf_evlist__add_default(struct perf_evlist *evlist)
 {
struct perf_event_attr attr = {
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 946a6ada817b..439b1375c4ea 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -120,6 +120,7 @@ int perf_evlist__set_filters(struct perf_evlist *evlist);
 
 void __perf_evlist__set_leader(struct list_head *list);
 void perf_evlist__set_leader(struct perf_evlist *evlist);
+void perf_evlist__recalc_nr_groups(struct perf_evlist *evlist);
 
 u64 perf_evlist__sample_type(struct perf_evlist *evlist);
 bool perf_evlist__sample_id_all(struct perf_evlist *evlist);
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/16] perf hists: Add missing period_* fields when collapsing a hist entry

2012-09-26 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

So that the perf report won't lost the cpu utilization information.

For example, if there're two process that have same name.

  $ perf report --stdio --showcpuutilization -s pid
  [SNIP]
  #   Overhead   sysus  Command:  Pid
  #         .
  #
55.12% 0.01%55.10%  noploop:28781
44.88% 0.06%44.83%  noploop:28782

Before:
  $ perf report --stdio --showcpuutilization -s comm
  [SNIP]
  #   Overhead   sysus
  #       
  #
   100.00% 0.06%44.83%

After:
  $ perf report --stdio --showcpuutilization -s comm
  [SNIP]
  #   Overhead   sysus
  #       
  #
   100.00% 0.07%99.93%

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 6ec5398de89d..236bc9d98ff2 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -410,8 +410,13 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
 
if (!cmp) {
-   iter-period += he-period;
-   iter-nr_events += he-nr_events;
+   iter-period+= he-period;
+   iter-period_sys+= he-period_sys;
+   iter-period_us += he-period_us;
+   iter-period_guest_sys  += he-period_guest_sys;
+   iter-period_guest_us   += he-period_guest_us;
+   iter-nr_events += he-nr_events;
+
if (symbol_conf.use_callchain) {
callchain_cursor_reset(callchain_cursor);
callchain_merge(callchain_cursor,
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/4] perf annotate: configure objdump path at compile time

2012-09-26 Thread Namhyung Kim
On Thu, 27 Sep 2012 03:51:07 +0300, Irina Tirdea wrote:
 On Tue, Sep 25, 2012 at 4:08 PM, Namhyung Kim namhy...@kernel.org wrote:
 I thought about it twice and confused.

 For cross-compiling, the resulting perf binary will run on target - say
 Android - but the toolchain runs on host, right?  So with this change
 the cross-built perf will try to find the arm-eabi-objdump on Android.
 Is it an intended behavior?  Is there an arm-eabi-objdump on Android?


 Apparently I got confused about this as well...

:)


 There are two perf binaries built for Android: one for the target
 (that will run on Android) and the other one for the host (that can be
 used to analyse data recorded on the target).

 As you mentioned, the perf built to run on Android needs to use
 objdump as objdump (actually Android does not yet have objdump, but
 this is the naming convention). In this case, objdump should not have
 the CROSS_COMPILE prefix.

Ok.


 The perf built to run on the host needs to use arm-eabi-objdump from
 the toolchain so that it can analyse data recorded on Android. This
 patch is targeting this scenario, not the previous one. In this case,
 the CROSS_COMPILE option would be different than arm-eabi- so using
 $(CROSS_COMPILE)objdump would be wrong. objdump should be overridden
 when running make since there is no connection between the toolchain
 used here and the path for objdump. I am always overriding objdump
 when calling make, so I did not catch this.

 I think that I should change DEFAULT_OBJDUMP_PATH=objdump in the
 Makefile to handle the first scenario. I'll also explain this in the
 commit message so that it is more clear and make the same change for
 the addr2line patch.

 What do you think?

I think the right thing to do is finding a correct objdump at runtime in
some way.  Why do you want to make it compile-time configurable?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 8/9] perf hists browser: Add option for runtime switching perf data file

2012-09-26 Thread Namhyung Kim
Hi Feng,

On Wed, 26 Sep 2012 15:57:07 +0800, Feng Tang wrote:
 On Tue, Sep 25, 2012 at 08:17:03AM -0300, Arnaldo Carvalho de Melo wrote:
 Em Tue, Sep 25, 2012 at 04:20:53PM +0800, Feng Tang escreveu:
  On Tue, 25 Sep 2012 11:11:21 +0900
  Namhyung Kim namhy...@kernel.org wrote:
   Ditto.  Plus it might leak previous input_name.
  
  Nice catch, will check the return value of strdup. 
  
  For input_name mem leak, in some cases the input_name can't be called
   with free(), like those got from parse -i option. In case the old
  input_name is got from malloc through strdup, I think it's not a big
  issue given that buffer will be freed any way when the application exit.
 
 I think this is a matter of discipline, leaking is bad, kernel or
 userspace, why special case it?


 I see, then we need make sure all input_name point to a malloced buffer, 
 here is a initial debug patch will only touch the annotate/report/script
 cmds, pls review and more suggestions are welcomed:

Well, how about adding a flag like input_name_alloced and checking it
before new allocation?  This way we can avoid needless strdup when
runtime switching is not used.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



[BUG] build error on compiling builtin-trace

2012-09-26 Thread Namhyung Kim
Hi Arnaldo,

I've encountered a following error when building current acme/perf/core:

CC builtin-trace.o
builtin-trace.c:7:22: fatal error: libaudit.h: No such file or directory
compilation terminated.
make: *** [builtin-trace.o] Error 1

It'd better if you post patches to the list before updating your
perf/core branch as many people rebase on the branch regularly.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/9] perf script: Add more filter to find_scripts()

2012-09-26 Thread Namhyung Kim
On Wed, 26 Sep 2012 16:56:41 +0800, Feng Tang wrote:
 On Tue, 25 Sep 2012 10:47:03 +0900
 Namhyung Kim namhy...@kernel.org wrote:
 It can't recognize extra spaces, multiple events connected by commas,
 event groups and probably more..  So I think it'd better if we can use
 parse_events() here - but w/o an evlist.  Jiri, what do you think?

 Yes, this func was really a pain to me :) And fortunately, current
 intree xxx-record scripts are all in simple format: -e eventname ,
 and this lightweight func basically works fine.

 I agree that we'd better have a separate parse_events() similar func 
 to cherry-pick the events names in parse-events.c, to not make
 hists.c too heavy. 

 And frankly speaking, I'm not familiar at all with these flex/bison
 handling, so can we do things in steps: fixes those space issue, add
 a fixme in comments and push the basically working version first?

It'd not that hard.  How about using below (untested) patch?

Thanks,
Namhyung


diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index bf5d033ee1b4..5dc71f598028 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -817,6 +817,21 @@ int parse_events_terms(struct list_head *terms, const char 
*str)
return ret;
 }
 
+int __parse_events(struct list_head *evsel_list, const char *str)
+{
+   int ret;
+   struct parse_events_data__events data = {
+   .list = LIST_HEAD_INIT(data.list),
+   };
+
+   ret = parse_events__scanner(str, data, PE_START_EVENTS);
+   if (!ret) {
+   list_splice(evsel_list, data.list);
+   return 0;
+   }
+   return -1;
+}
+
 int parse_events(struct perf_evlist *evlist, const char *str,
 int unset __maybe_unused)
 {
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index c356e443448d..c13e9bd0f041 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -32,6 +32,7 @@ extern int parse_events_option(const struct option *opt, 
const char *str,
 extern int parse_events(struct perf_evlist *evlist, const char *str,
int unset);
 extern int parse_events_terms(struct list_head *terms, const char *str);
+extern int __parse_events(struct list_head *evsel_list, const char *str);
 extern int parse_filter(const struct option *opt, const char *str, int unset);
 
 #define EVENTS_HELP_MAX (128*1024)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 3/9] perf script: Add more filter to find_scripts()

2012-09-27 Thread Namhyung Kim
On Thu, 27 Sep 2012 13:45:30 +0900, Namhyung Kim wrote:
 It'd not that hard.  How about using below (untested) patch?

Hmm... it won't work for some cases.  Please ignore this.

Thanks,
Namhyung


 diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
 index bf5d033ee1b4..5dc71f598028 100644
 --- a/tools/perf/util/parse-events.c
 +++ b/tools/perf/util/parse-events.c
 @@ -817,6 +817,21 @@ int parse_events_terms(struct list_head *terms, const 
 char *str)
   return ret;
  }
  
 +int __parse_events(struct list_head *evsel_list, const char *str)
 +{
 + int ret;
 + struct parse_events_data__events data = {
 + .list = LIST_HEAD_INIT(data.list),
 + };
 +
 + ret = parse_events__scanner(str, data, PE_START_EVENTS);
 + if (!ret) {
 + list_splice(evsel_list, data.list);
 + return 0;
 + }
 + return -1;
 +}
 +
  int parse_events(struct perf_evlist *evlist, const char *str,
int unset __maybe_unused)
  {
 diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
 index c356e443448d..c13e9bd0f041 100644
 --- a/tools/perf/util/parse-events.h
 +++ b/tools/perf/util/parse-events.h
 @@ -32,6 +32,7 @@ extern int parse_events_option(const struct option *opt, 
 const char *str,
  extern int parse_events(struct perf_evlist *evlist, const char *str,
   int unset);
  extern int parse_events_terms(struct list_head *terms, const char *str);
 +extern int __parse_events(struct list_head *evsel_list, const char *str);
  extern int parse_filter(const struct option *opt, const char *str, int 
 unset);
  
  #define EVENTS_HELP_MAX (128*1024)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] perf tools: Check libaudit for perf-trace builtin

2012-09-27 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

The newly added trace command requires an external audit library.
However it can cause a build error because it's not checked whether
the libaudit is installed on system:

CC builtin-trace.o
  builtin-trace.c:7:22: fatal error: libaudit.h: No such file or directory
  compilation terminated.
  make: *** [builtin-trace.o] Error 1

Cc: David Ahern dsah...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Makefile | 16 ++--
 tools/perf/config/feature-tests.mak | 11 +++
 tools/perf/perf.c   |  2 ++
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 6958ba4f5dcb..5973f383eb8e 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -102,7 +102,7 @@ ifdef PARSER_DEBUG
 endif
 
 CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra 
-std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) 
$(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
-EXTLIBS = -lpthread -lrt -lelf -lm -laudit
+EXTLIBS = -lpthread -lrt -lelf -lm
 ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 
-D_GNU_SOURCE
 ALL_LDFLAGS = $(LDFLAGS)
 STRIP ?= strip
@@ -442,7 +442,6 @@ BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
 BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
 BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
 BUILTIN_OBJS += $(OUTPUT)builtin-test.o
-BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
 BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
 
 PERFLIBS = $(LIB_FILE) $(LIBTRACEEVENT)
@@ -560,6 +559,19 @@ else
LIB_OBJS += $(OUTPUT)util/unwind.o
 endif
 
+ifdef NO_LIBAUDIT
+   BASIC_CFLAGS += -DNO_LIBAUDIT_SUPPORT
+else
+   FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
+   ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y)
+   msg := $(warning No libaudit.h found, please install 
audit-libs-devel or libaudit-dev);
+   BASIC_CFLAGS += -DNO_LIBAUDIT_SUPPORT
+   else
+   BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
+   EXTLIBS += -laudit
+   endif
+endif
+
 ifdef NO_NEWT
BASIC_CFLAGS += -DNO_NEWT_SUPPORT
 else
diff --git a/tools/perf/config/feature-tests.mak 
b/tools/perf/config/feature-tests.mak
index 116690a669d2..4add41bb0c7e 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -193,3 +193,14 @@ int main(void)
 }
 endef
 endif
+
+ifndef NO_LIBAUDIT
+define SOURCE_LIBAUDIT
+#include libaudit.h
+
+int main(void)
+{
+   return audit_open();
+}
+endef
+endif
\ No newline at end of file
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 3fb052c9a27f..fc2f770e3027 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -55,7 +55,9 @@ static struct cmd_struct commands[] = {
{ lock,   cmd_lock,   0 },
{ kvm,cmd_kvm,0 },
{ test,   cmd_test,   0 },
+#ifndef NO_LIBAUDIT_SUPPORT
{ trace,  cmd_trace,  0 },
+#endif
{ inject, cmd_inject, 0 },
 };
 
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/4] perf annotate: configure objdump path at compile time

2012-09-27 Thread Namhyung Kim
On Thu, 27 Sep 2012 14:25:10 +0300, Irina Tirdea wrote:
 The perf built to run on the host needs to use arm-eabi-objdump from
 the toolchain so that it can analyse data recorded on Android. This
 patch is targeting this scenario, not the previous one. In this case,
 the CROSS_COMPILE option would be different than arm-eabi- so using
 $(CROSS_COMPILE)objdump would be wrong. objdump should be overridden
 when running make since there is no connection between the toolchain
 used here and the path for objdump. I am always overriding objdump
 when calling make, so I did not catch this.

 I think that I should change DEFAULT_OBJDUMP_PATH=objdump in the
 Makefile to handle the first scenario. I'll also explain this in the
 commit message so that it is more clear and make the same change for
 the addr2line patch.

 What do you think?

 I think the right thing to do is finding a correct objdump at runtime in
 some way.  Why do you want to make it compile-time configurable?


 The correct objdump path can be detected at runtime by setting the
 toolchain path. But since the name is arm-eabi-objdump and not
 objdump, it does not know to use it instead.

 The only way (I can think of) to change objdump at runtime would be to
 use the --objdump option for perf annotate (and provide a similar
 option for addr2line). The problem with this approach is that the user
 has to be aware that perf annotate uses the objdump tool and that he
 has to use the cross-compiler version instead. Since the user will
 have perf compiled for host as part of his Android tree, he will
 expect it to work without these further changes from his part. The
 path for objdump can be set in the Android Makefile at compile time so
 that the user doesn't need to be aware of it.

What I'm thinking is that perf can try to find cross-built binutils when
it detects perf.data file is came from other machine/architecture.
Fortunately perf_session_env was added recently and it has the arch
information from the file so we can use it to find the path.

Following patch is a proof-of-concept patch and only build tested.
What do you think?  Could you play with it for some time? :)

Thanks,
Namhyung


From 7068a43a4b450c60fdcc8a3916ce624c1ef2c9b2 Mon Sep 17 00:00:00 2001
From: Namhyung Kim namhyung@lge.com
Date: Thu, 27 Sep 2012 21:54:33 +0900
Subject: [RFC] perf tools: Try to find cross-built objdump path

As we have architecture information of saved perf.data file, we can
try to find cross-built objdump path.

The triplets are incomplete and maybe need some regexp works.

Cc: Irina Tirdea irina.tir...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/Makefile   |  2 +
 tools/perf/arch/common.c  | 42 +++
 tools/perf/builtin-annotate.c |  3 ++
 tools/perf/util/annotate.c| 96 +++
 tools/perf/util/annotate.h| 10 +
 5 files changed, 153 insertions(+)
 create mode 100644 tools/perf/arch/common.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5973f383eb8e..b189229eb576 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -412,6 +412,8 @@ LIB_OBJS += $(OUTPUT)ui/helpline.o
 LIB_OBJS += $(OUTPUT)ui/hist.o
 LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
 
+LIB_OBJS += $(OUTPUT)arch/common.o
+
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
 # Benchmark modules
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
new file mode 100644
index ..c3872427d135
--- /dev/null
+++ b/tools/perf/arch/common.c
@@ -0,0 +1,42 @@
+#include stdio.h
+
+const char * const arm_triplets[] = {
+   arm-eabi-,
+   arm-unknown-linux-,
+   arm-unknown-linux-gnu-,
+   arm-unknown-linux-gnueabi-,
+   NULL
+};
+
+const char * const powerpc_triplets[] = {
+   powerpc-unknown-linux-gnu-,
+   powerpc64-unknown-linux-gnu-,
+   NULL
+};
+
+const char * const s390_triplets[] = {
+   s390-ibm-linux-,
+   NULL
+};
+
+const char * const sh_triplets[] = {
+   sh-unknown-linux-gnu-,
+   sh64-unknown-linux-gnu-,
+   NULL
+};
+
+const char * const sparc_triplets[] = {
+   sparc-unknown-linux-gnu-,
+   sparc64-unknown-linux-gnu-,
+   NULL
+};
+
+const char * const x86_triplets[] = {
+   x86_64-pc-linux-gnu-,
+   x86_64-unknown-linux-gnu-,
+   i686-pc-linux-gnu-,
+   i586-pc-linux-gnu-,
+   i486-pc-linux-gnu-,
+   i386-pc-linux-gnu-,
+   NULL
+};
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 9ea38540b873..20fe9bb6505b 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -186,6 +186,9 @@ static int __cmd_annotate(struct perf_annotate *ann)
goto out_delete;
}
 
+   if (!objdump_path)
+   try_objdump_path(session);
+
ret = perf_session__process_events(session, ann-tool);
if (ret)
goto out_delete;
diff

[RFC v2] perf tools: Try to find cross-built objdump path

2012-09-27 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

As we have architecture information of saved perf.data file, we can
try to find cross-built objdump path.

The triplets are incomplete and maybe need some regexp works.

Cc: Irina Tirdea irina.tir...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
v2: don't modify env string

 tools/perf/Makefile   |   2 +
 tools/perf/arch/common.c  |  42 +
 tools/perf/builtin-annotate.c |   3 ++
 tools/perf/util/annotate.c| 103 ++
 tools/perf/util/annotate.h|  10 
 5 files changed, 160 insertions(+)
 create mode 100644 tools/perf/arch/common.c

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 5973f383eb8e..b189229eb576 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -412,6 +412,8 @@ LIB_OBJS += $(OUTPUT)ui/helpline.o
 LIB_OBJS += $(OUTPUT)ui/hist.o
 LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
 
+LIB_OBJS += $(OUTPUT)arch/common.o
+
 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
 # Benchmark modules
diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c
new file mode 100644
index ..c3872427d135
--- /dev/null
+++ b/tools/perf/arch/common.c
@@ -0,0 +1,42 @@
+#include stdio.h
+
+const char * const arm_triplets[] = {
+   arm-eabi-,
+   arm-unknown-linux-,
+   arm-unknown-linux-gnu-,
+   arm-unknown-linux-gnueabi-,
+   NULL
+};
+
+const char * const powerpc_triplets[] = {
+   powerpc-unknown-linux-gnu-,
+   powerpc64-unknown-linux-gnu-,
+   NULL
+};
+
+const char * const s390_triplets[] = {
+   s390-ibm-linux-,
+   NULL
+};
+
+const char * const sh_triplets[] = {
+   sh-unknown-linux-gnu-,
+   sh64-unknown-linux-gnu-,
+   NULL
+};
+
+const char * const sparc_triplets[] = {
+   sparc-unknown-linux-gnu-,
+   sparc64-unknown-linux-gnu-,
+   NULL
+};
+
+const char * const x86_triplets[] = {
+   x86_64-pc-linux-gnu-,
+   x86_64-unknown-linux-gnu-,
+   i686-pc-linux-gnu-,
+   i586-pc-linux-gnu-,
+   i486-pc-linux-gnu-,
+   i386-pc-linux-gnu-,
+   NULL
+};
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 9ea38540b873..20fe9bb6505b 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -186,6 +186,9 @@ static int __cmd_annotate(struct perf_annotate *ann)
goto out_delete;
}
 
+   if (!objdump_path)
+   try_objdump_path(session);
+
ret = perf_session__process_events(session, ann-tool);
if (ret)
goto out_delete;
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index f0a910371377..df17c443e3b3 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -15,6 +15,7 @@
 #include debug.h
 #include annotate.h
 #include pthread.h
+#include sys/utsname.h
 
 const char *disassembler_style;
 const char *objdump_path;
@@ -1140,3 +1141,105 @@ int symbol__tty_annotate(struct symbol *sym, struct map 
*map, int evidx,
 
return 0;
 }
+
+static bool lookup_path(char *name)
+{
+   bool found = false;
+   char *path, *tmp;
+   char buf[PATH_MAX];
+   char *env = getenv(PATH);
+
+   if (!env)
+   return false;
+
+   env = strdup(env);
+   if (!env)
+   return false;
+
+   path = strtok_r(env, :, tmp);
+   while (path) {
+   scnprintf(buf, sizeof(buf), %s%s, path, name);
+   if (access(buf, F_OK) == 0) {
+   found = true;
+   break;
+   }
+   strtok_r(NULL, :, tmp);
+   }
+   free(env);
+   return found;
+}
+
+static int lookup_triplets(const char **triplets, const char *name)
+{
+   int i;
+   char buf[PATH_MAX];
+
+   for (i = 0; triplets[i] != NULL; i++) {
+   scnprintf(buf, sizeof(buf), %s%s, triplets[i], name);
+   if (lookup_path(buf))
+   return i;
+   }
+   return -1;
+}
+
+static char *try_binutils_path(struct perf_session *session, const char *name)
+{
+   int idx;
+   char *arch, *env;
+   struct utsname uts;
+   const char **path_list;
+   char buf[PATH_MAX];
+
+   if (uname(uts)  0)
+   return NULL;
+
+   /*
+* We don't need to try to find objdump path for native system.
+* Just use default objdump.
+*/
+   if (!strcmp(uts.machine, session-header.env.arch))
+   return NULL;
+
+   env = getenv(CROSS_COMPILE);
+   if (env) {
+   scnprintf(buf, sizeof(buf), %s%s, env, name);
+   if (buf[0] == '/') {
+   if (access(buf, F_OK) == 0)
+   return strdup(buf);
+
+   return NULL;
+   }
+
+   if (lookup_path(buf))
+   return

Re: [PATCH 05/16] perf tools: Keep group information

2012-09-27 Thread Namhyung Kim
Hi Jiri,

On Thu, 27 Sep 2012 19:03:52 +0200, Jiri Olsa wrote:
 diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
 index bf5d033ee1b4..3c52d0ab9270 100644
 --- a/tools/perf/util/parse-events.c
 +++ b/tools/perf/util/parse-events.c
 @@ -830,6 +830,7 @@ int parse_events(struct perf_evlist *evlist, const char 
 *str,
  if (!ret) {
  int entries = data.idx - evlist-nr_entries;
  perf_evlist__splice_list_tail(evlist, data.list, entries);
 +evlist-nr_groups += data.nr_groups;
  return 0;
  }
  
 diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
 index c356e443448d..f6b0254afe17 100644
 --- a/tools/perf/util/parse-events.h
 +++ b/tools/perf/util/parse-events.h
 @@ -65,6 +65,7 @@ struct parse_events__term {
  struct parse_events_data__events {
  struct list_head list;
  int idx;
 +int nr_groups;
  };
  
  struct parse_events_data__terms {
 diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
 index cd88209e3c58..d14bb507594b 100644
 --- a/tools/perf/util/parse-events.y
 +++ b/tools/perf/util/parse-events.y
 @@ -122,7 +122,9 @@ group_def:
  PE_NAME '{' events '}'
  {
  struct list_head *list = $3;
 +struct parse_events_data__events *data = _data;
  
 +data-nr_groups++;

 perhaps if you inc nr_groups only if there's more than 1 event,
 you would not need your next patch:
   perf evlist: Add perf_evlist__recalc_nr_groups

 something like:

 if (!list_is_last(list))
   data-nr_groups++;


Right!  Will use it in next version.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC/PATCHSET 00/15] perf report: Add support to accumulate hist periods

2012-09-27 Thread Namhyung Kim
Hi Frederic,

On Fri, 28 Sep 2012 01:01:48 +0200, Frederic Weisbecker wrote:
 When Arun was working on this, I asked him to explore if it could make sense 
 to reuse
 the -b, --branch-stack  perf report option. Because after all, this feature 
 is doing
 about the same than -b except it's using callchains instead of full branch 
 tracing.
 But callchains are branches. Just a limited subset of all branches taken on 
 excecution.
 So you can probably reuse some interface and even ground code there.

 What do you think?

Umm.. first of all, I'm not familiar with the branch stack thing.  It's
intel-specific, right?

Also I don't understand what exactly you want here.  What kind of
interface did you say?  Can you elaborate it bit more?

And AFAIK branch stack can collect much more branch information than
just callstacks.  Can we differentiate which is which easily?  Is there
any limitation on using it?  What if callstacks are not sync'ed with
branch stacks - is it possible though?

But I think it'd be good if the branch stack can be changed to call
stack in general.  Did you mean this?

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 03/14] perf hists: Separate overhead and baseline columns

2012-09-28 Thread Namhyung Kim
On Thu, 27 Sep 2012 13:09:24 +0200, Jiri Olsa wrote:
 Currently the overhead and baseline columns are handled within
 single function and the distinction is made by 'baseline hists'
 pointer passed by 'struct perf_hpp::ptr'.

 Since hists pointer is now part of each hist_entry, it's possible
 to locate paired hists pointer directly from the passed struct
 hist_entry pointer.

 Also separating those 2 columns makes the code more obvious.

Yes, it was thinking about something like this.



 Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
 Cc: Peter Zijlstra a.p.zijls...@chello.nl
 Cc: Ingo Molnar mi...@elte.hu
 Cc: Paul Mackerras pau...@samba.org
 Cc: Corey Ashford cjash...@linux.vnet.ibm.com
 Cc: Frederic Weisbecker fweis...@gmail.com
 Cc: Namhyung Kim namhy...@kernel.org
 Signed-off-by: Jiri Olsa jo...@redhat.com
 ---
[snip]
 +static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he)
 +{
 + double percent = baseline_percent(he);
 +
 + return percent_color_snprintf(hpp-buf, hpp-size,   %5.2f%%, 
 percent);

Is it possible to have a baseline value over 100%?  I changed 'overhead'
colum format from '2 spaces + %5.2f + %' to '1 space + %6.2f + %' for
the case.  Probably it'd better using it here too for consistency.


 +}
 +
 +static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he)
 +{
 + double percent = baseline_percent(he);
 + const char *fmt = symbol_conf.field_sep ? %.2f :   %5.2f%%;

Ditto.

Thanks,
Namhyung

 +
 + return scnprintf(hpp-buf, hpp-size, fmt, percent);
 +}
 +
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 06/14] perf tool: Add hpp interface to enable/disable hpp column

2012-09-28 Thread Namhyung Kim
On Thu, 27 Sep 2012 13:09:27 +0200, Jiri Olsa wrote:
 Adding perf_hpp__column_enable function to enable/disable hists
 column and removing diff command specific stuff 'need_pair and
 show_displacement' from hpp code.

 The diff command now enables/disables columns separately according
 to the user arguments. This will be helpful in future patches where
 more columns are added into diff output.

This is what I wanted to do. :)

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] perf tool: Fix build for NO_DWARF=1 case

2012-10-03 Thread Namhyung Kim
Hi all,

On Wed, 3 Oct 2012 12:29:28 +0200, Jiri Olsa wrote:
 On Tue, Oct 02, 2012 at 06:45:36PM -0300, Arnaldo Carvalho de Melo wrote:
 Em Tue, Oct 02, 2012 at 03:10:49PM +0200, Jiri Olsa escreveu:
  On Tue, Oct 02, 2012 at 07:39:23AM -0400, Ben Guthro wrote:
   Actually - I hadn't noticed these warnings before.
 
   After installing libdw-dev - the perf build completed successfully.
   Perhaps this should be fatal, rather than a warning?
 
  attached patch fixies the issue for me. Adding Arnaldo to the loop.
 
 [acme@sandy linux]$ make -j8 -C tools/perf/ LIBUNWIND_DIR=/opt/libunwind 
 O=/home/acme/git/build/perf install
 cc1: warnings being treated as errors
 arch/x86/util/dwarf-regs.c:72: error: no previous prototype for 
 ‘get_arch_regstr’
 make: *** [/home/acme/git/build/perf/arch/x86/util/dwarf-regs.o] Error 1
 make: *** Waiting for unfinished jobs
 make: Leaving directory `/home/git/linux/tools/perf'
 [acme@sandy linux]$
 
 - Arnaldo

 ugh.. forgot the way you build perf ;)
 (also smells like 'automated make test' adept)

 Anyway, there's Makefile dependency on PERF_HAVE_DWARF_REGS which
 is defined in arch/x86/Makefile.

 So, there's only one right place for '-include arch/$(ARCH)/Makefile'.
 We should think of some other solution, since this seems fragile.

 I checked your make and simple make with attached patch
 (only x86_64 arch, and with and without libdw installed).

I posted similar patch few days ago and it slipped into acme/perf/core:

  https://lkml.org/lkml/2012/9/28/194

Can you reproduce it with above change?  Anyway, my apologies, sorry for
the inconvenience.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] perf tools: Check existence of _get_comp_words_by_ref when bash completing

2012-10-03 Thread Namhyung Kim
Hi Frederic,

On Tue, 2 Oct 2012 17:54:10 +0200, Frederic Weisbecker wrote:
 On Wed, Oct 03, 2012 at 12:21:32AM +0900, Namhyung Kim wrote:
 The '_get_comp_words_by_ref' function is available from the bash
 completion v1.2 so that earlier version emits following warning:
 
   $ perf reTAB_get_comp_words_by_ref: command not found
 
 Use older '_get_cword' method when the above function doesn't exist.

 May be only use _get_cword then, if it works everywhere?

It'll work but it's deprecated.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] perf tools: Complete tracepoint event names

2012-10-03 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Currently tracepoint events cannot be completed because they contain a
colon (:) character.  The colon is considered as a word separator when
bash completion is done - variable COMP_WORDBREAKS contains colon - so
if a word being completed contains a colon it can be a problem.

Recent versions of bash completion provide -n switch to
_get_comp_words_by_ref and __ltrim_colon_completions functions in
order to resolve this issue.  Copy the latter in case not exists.

Cc: Frederic Weisbecker fweis...@gmail.com
Cc: David Ahern dsah...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
This patch is based on my previous completion updates set.

 tools/perf/bash_completion | 18 --
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion
index 5c355ababf80..56e6a12aab59 100644
--- a/tools/perf/bash_completion
+++ b/tools/perf/bash_completion
@@ -6,6 +6,19 @@ function_exists()
return $?
 }
 
+function_exists __ltrim_colon_completions ||
+__ltrim_colon_completions()
+{
+   if [[ $1 == *:*  $COMP_WORDBREAKS == *:* ]]; then
+   # Remove colon-word prefix from COMPREPLY items
+   local colon_word=${1%${1##*:}}
+   local i=${#COMPREPLY[*]}
+   while [[ $((--i)) -ge 0 ]]; do
+   COMPREPLY[$i]=${COMPREPLY[$i]#$colon_word}
+   done
+   fi
+}
+
 have perf 
 _perf()
 {
@@ -13,9 +26,9 @@ _perf()
 
COMPREPLY=()
if function_exists _get_comp_words_by_ref; then
-   _get_comp_words_by_ref cur prev
+   _get_comp_words_by_ref -n : cur prev
else
-   cur=$(_get_cword)
+   cur=$(_get_cword :)
prev=${COMP_WORDS[COMP_CWORD-1]}
fi
 
@@ -35,6 +48,7 @@ _perf()
elif [[ $prev == -e  ${COMP_WORDS[1]} == @(record|stat|top) ]]; 
then
evts=$($cmd list --raw-dump)
COMPREPLY=( $( compgen -W '$evts' -- $cur ) )
+   __ltrim_colon_completions $cur
# List long option names
elif [[ $cur == --* ]];  then
subcmd=${COMP_WORDS[1]}
-- 
1.7.11.4

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 14/14] perf diff: Display empty space for non paired samples

2012-10-04 Thread Namhyung Kim
On Thu, 27 Sep 2012 13:09:35 +0200, Jiri Olsa wrote:
 Currently in 'Baseline' and 'Period Base' columns zero values are
 displayed in case no pair is found for the sample. This might be
 confusing, using empty space instead.
[snip]
 @@ -246,8 +249,12 @@ static int hpp__entry_period_baseline(struct perf_hpp 
 *hpp, struct hist_entry *h
   u64 period = pair ? pair-period : 0;
   const char *fmt = symbol_conf.field_sep ? % PRIu64 : %12 PRIu64;
  
 - return scnprintf(hpp-buf, hpp-size, fmt, period);
 + if (pair)
 + return scnprintf(hpp-buf, hpp-size, fmt, period);
 + else
 + return scnprintf(hpp-buf, hpp-size, );

It seems that it's not needed when -t (field separator) switch is given.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 00/20] perf report: Add support for event group view (v3)

2012-10-04 Thread Namhyung Kim
Hi,

This is my v3 of event group view support.
For basic idea and usage example, please see my original post [1].

I rebased the series on top of selected hpp changes from Jiri's diff
patchset [2] since it contains cleanups and improves that can be used
in this series too.

You can also get it via my tree at:

git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git  
perf/group-v3

Any comments are welcome, thanks,
Namhyung

v2 - v3:
 * drop patch 1 since it's merged into acme/perf/core
 * cherry-pick Jiri's hpp changes
 * add missing bswap_32 on reading nr_groups (Jiri)
 * remove perf_evlist__recalc_nr_groups() in favor of list_is_last (Jiri)

v1 - v2:
 * save group relation to header (Jiri)

[1] https://lkml.org/lkml/2012/7/24/81
[2] https://lkml.org/lkml/2012/9/27/254

Jiri Olsa (6):
  perf hists: Add struct hists pointer to struct hist_entry
  perf diff: Refactor diff displacement possition info
  perf hists: Separate overhead and baseline columns
  perf tools: Removing hists pair argument from output path
  perf tool: Add hpp interface to enable/disable hpp column
  perf diff: Removing the total_period argument from output code

Namhyung Kim (14):
  perf hists: Introduce struct he_stat
  perf hists: Move he-stat.nr_events initialization to a template
  perf hists: Add more helpers for hist entry stat
  perf tools: Keep group information
  perf header: Add HEADER_GROUP_DESC feature
  perf hists: Collapse group hist_entries to a leader
  perf hists: Maintain total periods of group members in the leader
  perf report: Make another loop for output resorting
  perf ui/hist: Add support for event group view
  perf ui/browser: Add support for event group view
  perf ui/gtk: Add support for event group view
  perf report: Bypass non-leader events when event group is enabled
  perf report: Show group description when event group is enabled
  perf report: Add --group option

 tools/perf/builtin-diff.c  |   68 ++
 tools/perf/builtin-record.c|3 +
 tools/perf/builtin-report.c|   33 ++-
 tools/perf/builtin-top.c   |2 +-
 tools/perf/ui/browsers/hists.c |  115 +++---
 tools/perf/ui/gtk/browser.c|   74 ---
 tools/perf/ui/hist.c   |  204 +---
 tools/perf/ui/setup.c  |2 +-
 tools/perf/ui/stdio/hist.c |   47 -
 tools/perf/util/evlist.c   |   10 +-
 tools/perf/util/evlist.h   |1 +
 tools/perf/util/evsel.c|   25 +
 tools/perf/util/evsel.h|   23 +
 tools/perf/util/header.c   |  152 ++
 tools/perf/util/header.h   |2 +
 tools/perf/util/hist.c |  195 --
 tools/perf/util/hist.h |   12 +--
 tools/perf/util/parse-events.c |1 +
 tools/perf/util/parse-events.h |1 +
 tools/perf/util/parse-events.y |   10 ++
 tools/perf/util/sort.h |   20 ++--
 tools/perf/util/symbol.c   |4 +
 tools/perf/util/symbol.h   |3 +-
 23 files changed, 826 insertions(+), 181 deletions(-)

-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 01/20] perf hists: Add struct hists pointer to struct hist_entry

2012-10-04 Thread Namhyung Kim
From: Jiri Olsa jo...@redhat.com

Adding pointer back to the parent struct hists for struct hists_entry.

This will be useful in future for any hist_entry's data computation,
that depends on total data of its parent hists.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c |2 ++
 tools/perf/util/sort.h |1 +
 2 files changed, 3 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 236bc9d98ff2..040f34c79a53 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -325,6 +325,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists 
*self,
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.branch_info = bi,
+   .hists  = self,
};
 
return add_hist_entry(self, entry, al, period);
@@ -346,6 +347,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
.period = period,
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
+   .hists  = self,
};
 
return add_hist_entry(self, entry, al, period);
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 12d634792de5..eb3959b8e9d9 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -79,6 +79,7 @@ struct hist_entry {
struct rb_rootsorted_chain;
};
struct branch_info  *branch_info;
+   struct hists*hists;
struct callchain_root   callchain[0];
 };
 
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 02/20] perf diff: Refactor diff displacement possition info

2012-10-04 Thread Namhyung Kim
From: Jiri Olsa jo...@redhat.com

Moving the position calculation into the diff command, so the position
is prepared inside struct hist_entry data and there's no need to compute
in the output display path.

Removing 'displacement' from struct perf_hpp as it is no longer needed.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c   |   49 ---
 tools/perf/builtin-report.c |2 +-
 tools/perf/builtin-top.c|2 +-
 tools/perf/ui/hist.c|8 ---
 tools/perf/ui/stdio/hist.c  |   17 +++
 tools/perf/util/hist.h  |4 +---
 tools/perf/util/sort.h  |2 +-
 7 files changed, 44 insertions(+), 40 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 761f4197a9e2..5cb577a3c5b2 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -70,8 +70,8 @@ static struct perf_tool tool = {
.ordering_requires_timestamps = true,
 };
 
-static void perf_session__insert_hist_entry_by_name(struct rb_root *root,
-   struct hist_entry *he)
+static void insert_hist_entry_by_name(struct rb_root *root,
+ struct hist_entry *he)
 {
struct rb_node **p = root-rb_node;
struct rb_node *parent = NULL;
@@ -90,7 +90,7 @@ static void perf_session__insert_hist_entry_by_name(struct 
rb_root *root,
rb_insert_color(he-rb_node, root);
 }
 
-static void hists__resort_entries(struct hists *self)
+static void hists__name_resort(struct hists *self, bool sort)
 {
unsigned long position = 1;
struct rb_root tmp = RB_ROOT;
@@ -100,12 +100,16 @@ static void hists__resort_entries(struct hists *self)
struct hist_entry *n = rb_entry(next, struct hist_entry, 
rb_node);
 
next = rb_next(n-rb_node);
-   rb_erase(n-rb_node, self-entries);
n-position = position++;
-   perf_session__insert_hist_entry_by_name(tmp, n);
+
+   if (sort) {
+   rb_erase(n-rb_node, self-entries);
+   insert_hist_entry_by_name(tmp, n);
+   }
}
 
-   self-entries = tmp;
+   if (sort)
+   self-entries = tmp;
 }
 
 static struct hist_entry *hists__find_entry(struct hists *self,
@@ -121,7 +125,7 @@ static struct hist_entry *hists__find_entry(struct hists 
*self,
n = n-rb_left;
else if (cmp  0)
n = n-rb_right;
-   else 
+   else
return iter;
}
 
@@ -150,6 +154,24 @@ static struct perf_evsel *evsel_match(struct perf_evsel 
*evsel,
return NULL;
 }
 
+static void perf_evlist__resort_hists(struct perf_evlist *evlist, bool name)
+{
+   struct perf_evsel *evsel;
+
+   list_for_each_entry(evsel, evlist-entries, node) {
+   struct hists *hists = evsel-hists;
+
+   hists__output_resort(hists);
+
+   /*
+* The hists__name_resort only sets possition
+* if name is false.
+*/
+   if (name || ((!name)  show_displacement))
+   hists__name_resort(hists, name);
+   }
+}
+
 static int __cmd_diff(void)
 {
int ret, i;
@@ -176,15 +198,8 @@ static int __cmd_diff(void)
evlist_old = older-evlist;
evlist_new = newer-evlist;
 
-   list_for_each_entry(evsel, evlist_new-entries, node)
-   hists__output_resort(evsel-hists);
-
-   list_for_each_entry(evsel, evlist_old-entries, node) {
-   hists__output_resort(evsel-hists);
-
-   if (show_displacement)
-   hists__resort_entries(evsel-hists);
-   }
+   perf_evlist__resort_hists(evlist_old, true);
+   perf_evlist__resort_hists(evlist_new, false);
 
list_for_each_entry(evsel, evlist_new-entries, node) {
struct perf_evsel *evsel_old;
@@ -200,7 +215,7 @@ static int __cmd_diff(void)
 
hists__match(evsel_old-hists, evsel-hists);
hists__fprintf(evsel-hists, evsel_old-hists,
-  show_displacement, true, 0, 0, stdout);
+  true, 0, 0, stdout);
}
 
 out_delete:
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 1da243dfbc3e..6748cac919d1 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -320,7 +320,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist 
*evlist,
const char

[PATCH 04/20] perf tools: Removing hists pair argument from output path

2012-10-04 Thread Namhyung Kim
From: Jiri Olsa jo...@redhat.com

The hists pointer is now part of the 'struct hist_entry'.

And since the overhead and baseline columns are split now,
there's no reason to pass it through the output path.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c   |3 +--
 tools/perf/builtin-report.c |2 +-
 tools/perf/builtin-top.c|2 +-
 tools/perf/ui/hist.c|9 +
 tools/perf/ui/stdio/hist.c  |   10 +++---
 tools/perf/util/hist.h  |4 ++--
 6 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 5cb577a3c5b2..413c65a1ba39 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -214,8 +214,7 @@ static int __cmd_diff(void)
first = false;
 
hists__match(evsel_old-hists, evsel-hists);
-   hists__fprintf(evsel-hists, evsel_old-hists,
-  true, 0, 0, stdout);
+   hists__fprintf(evsel-hists, true, 0, 0, stdout);
}
 
 out_delete:
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 6748cac919d1..95e7ea879b8a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -320,7 +320,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist 
*evlist,
const char *evname = perf_evsel__name(pos);
 
hists__fprintf_nr_sample_events(hists, evname, stdout);
-   hists__fprintf(hists, NULL, true, 0, 0, stdout);
+   hists__fprintf(hists, true, 0, 0, stdout);
fprintf(stdout, \n\n);
}
 
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 6b8c62918f41..dd7ff2b74675 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -316,7 +316,7 @@ static void perf_top__print_sym_table(struct perf_top *top)
hists__output_recalc_col_len(top-sym_evsel-hists,
 top-winsize.ws_row - 3);
putchar('\n');
-   hists__fprintf(top-sym_evsel-hists, NULL, false,
+   hists__fprintf(top-sym_evsel-hists, false,
   top-winsize.ws_row - 4 - printed, win_width, stdout);
 }
 
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 532a60177c32..6b0138e5f332 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -228,16 +228,17 @@ static int hpp__width_delta(struct perf_hpp *hpp 
__maybe_unused)
 
 static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he)
 {
-   struct hists *pair_hists = hpp-ptr;
+   struct hist_entry *pair = he-pair;
+   struct hists *pair_hists = pair ? pair-hists : NULL;
u64 old_total, new_total;
double old_percent = 0, new_percent = 0;
double diff;
const char *fmt = symbol_conf.field_sep ? %s : %7.7s;
char buf[32] =  ;
 
-   old_total = pair_hists-stats.total_period;
-   if (old_total  0  he-pair)
-   old_percent = 100.0 * he-pair-period / old_total;
+   old_total = pair_hists ? pair_hists-stats.total_period : 0;
+   if (old_total  0  pair)
+   old_percent = 100.0 * pair-period / old_total;
 
new_total = hpp-total_period;
if (new_total  0)
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 0aa6776caba5..1340c93aa619 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -307,8 +307,7 @@ static size_t hist_entry__callchain_fprintf(struct 
hist_entry *he,
 }
 
 static int hist_entry__fprintf(struct hist_entry *he, size_t size,
-  struct hists *hists, struct hists *pair_hists,
-  u64 total_period, FILE *fp)
+  struct hists *hists, u64 total_period, FILE *fp)
 {
char bf[512];
int ret;
@@ -316,7 +315,6 @@ static int hist_entry__fprintf(struct hist_entry *he, 
size_t size,
.buf= bf,
.size   = size,
.total_period   = total_period,
-   .ptr= pair_hists,
};
bool color = !symbol_conf.field_sep;
 
@@ -335,8 +333,7 @@ static int hist_entry__fprintf(struct hist_entry *he, 
size_t size,
return ret;
 }
 
-size_t hists__fprintf(struct hists *hists, struct hists *pair,
- bool show_header, int max_rows,
+size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
  int max_cols, FILE *fp)
 {
struct sort_entry *se;
@@ -351,7 +348,6 @@ size_t hists__fprintf(struct hists *hists, struct hists 
*pair

[PATCH 05/20] perf tool: Add hpp interface to enable/disable hpp column

2012-10-04 Thread Namhyung Kim
From: Jiri Olsa jo...@redhat.com

Adding perf_hpp__column_enable function to enable/disable hists
column and removing diff command specific stuff 'need_pair and
show_displacement' from hpp code.

The diff command now enables/disables columns separately according
to the user arguments. This will be helpful in future patches where
more columns are added into diff output.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-diff.c  |   18 +-
 tools/perf/builtin-report.c|2 +-
 tools/perf/ui/browsers/hists.c |2 +-
 tools/perf/ui/gtk/browser.c|2 +-
 tools/perf/ui/hist.c   |   15 ++-
 tools/perf/ui/setup.c  |2 +-
 tools/perf/util/hist.h |3 ++-
 7 files changed, 29 insertions(+), 15 deletions(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 413c65a1ba39..a0b531c14b97 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -256,6 +256,21 @@ static const struct option options[] = {
OPT_END()
 };
 
+static void ui_init(void)
+{
+   perf_hpp__init();
+
+   /* No overhead column. */
+   perf_hpp__column_enable(PERF_HPP__OVERHEAD, false);
+
+   /* Display baseline/delta/displacement columns. */
+   perf_hpp__column_enable(PERF_HPP__BASELINE, true);
+   perf_hpp__column_enable(PERF_HPP__DELTA, true);
+
+   if (show_displacement)
+   perf_hpp__column_enable(PERF_HPP__DISPL, true);
+}
+
 int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
 {
sort_order = diff__default_sort_order;
@@ -278,7 +293,8 @@ int cmd_diff(int argc, const char **argv, const char 
*prefix __maybe_unused)
if (symbol__init()  0)
return -1;
 
-   perf_hpp__init(true, show_displacement);
+   ui_init();
+
setup_sorting(diff_usage, options);
setup_pager();
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 95e7ea879b8a..a61725d89d3e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -691,7 +691,7 @@ int cmd_report(int argc, const char **argv, const char 
*prefix __maybe_unused)
setup_browser(true);
else {
use_browser = 0;
-   perf_hpp__init(false, false);
+   perf_hpp__init();
}
 
setup_sorting(report_usage, options);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a21f40bebbac..bbd11c2f69db 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -584,7 +584,7 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
 
 void hist_browser__init_hpp(void)
 {
-   perf_hpp__init(false, false);
+   perf_hpp__init();
 
perf_hpp__format[PERF_HPP__OVERHEAD].color =
hist_browser__hpp_color_overhead;
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 7ff99ec1d95e..2bc08f6af714 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -73,7 +73,7 @@ HPP__COLOR_FN(overhead_guest_us, period_guest_us)
 
 void perf_gtk__init_hpp(void)
 {
-   perf_hpp__init(false, false);
+   perf_hpp__init();
 
perf_hpp__format[PERF_HPP__OVERHEAD].color =
perf_gtk__hpp_color_overhead;
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 6b0138e5f332..e8853f7780a3 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -302,7 +302,7 @@ struct perf_hpp_fmt perf_hpp__format[] = {
 #undef HPP__COLOR_PRINT_FNS
 #undef HPP__PRINT_FNS
 
-void perf_hpp__init(bool need_pair, bool show_displacement)
+void perf_hpp__init(void)
 {
if (symbol_conf.show_cpu_utilization) {
perf_hpp__format[PERF_HPP__OVERHEAD_SYS].cond = true;
@@ -319,15 +319,12 @@ void perf_hpp__init(bool need_pair, bool 
show_displacement)
 
if (symbol_conf.show_total_period)
perf_hpp__format[PERF_HPP__PERIOD].cond = true;
+}
 
-   if (need_pair) {
-   perf_hpp__format[PERF_HPP__OVERHEAD].cond = false;
-   perf_hpp__format[PERF_HPP__BASELINE].cond = true;
-   perf_hpp__format[PERF_HPP__DELTA].cond = true;
-
-   if (show_displacement)
-   perf_hpp__format[PERF_HPP__DISPL].cond = true;
-   }
+void perf_hpp__column_enable(unsigned col, bool enable)
+{
+   BUG_ON(col = PERF_HPP__MAX_INDEX);
+   perf_hpp__format[col].cond = enable;
 }
 
 static inline void advance_hpp(struct perf_hpp *hpp, int inc)
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index

[PATCH 07/20] perf hists: Introduce struct he_stat

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

The struct he_stat is for separating out statistics data of a hist
entry.  It is required for later changes.

It's just a mechanical change and should have no functional
differences.

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/browsers/hists.c |8 +++
 tools/perf/ui/gtk/browser.c|2 +-
 tools/perf/ui/hist.c   |   30 +++
 tools/perf/ui/stdio/hist.c |2 +-
 tools/perf/util/hist.c |   52 +---
 tools/perf/util/sort.h |   16 -
 6 files changed, 59 insertions(+), 51 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d359795454d0..0568536ecf67 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -570,7 +570,7 @@ static int hist_browser__hpp_color_ ## _name(struct 
perf_hpp *hpp,  \
 struct hist_entry *he) \
 {  \
struct hists *hists = he-hists;\
-   double percent = 100.0 * he-_field / hists-stats.total_period;\
+   double percent = 100.0 * he-stat._field / hists-stats.total_period; \
*(double *)hpp-ptr = percent;  \
return scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);  \
 }
@@ -982,7 +982,7 @@ static int hist_browser__fprintf_entry(struct hist_browser 
*browser,
folded_sign = hist_entry__folded(he);
 
hist_entry__sort_snprintf(he, s, sizeof(s), browser-hists);
-   percent = (he-period * 100.0) / browser-hists-stats.total_period;
+   percent = (he-stat.period * 100.0) / 
browser-hists-stats.total_period;
 
if (symbol_conf.use_callchain)
printed += fprintf(fp, %c , folded_sign);
@@ -990,10 +990,10 @@ static int hist_browser__fprintf_entry(struct 
hist_browser *browser,
printed += fprintf(fp,  %5.2f%%, percent);
 
if (symbol_conf.show_nr_samples)
-   printed += fprintf(fp,  %11u, he-nr_events);
+   printed += fprintf(fp,  %11u, he-stat.nr_events);
 
if (symbol_conf.show_total_period)
-   printed += fprintf(fp,  %12 PRIu64, he-period);
+   printed += fprintf(fp,  %12 PRIu64, he-stat.period);
 
printed += fprintf(fp, %s\n, rtrim(s));
 
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 3cbb1d622ed2..4125c6284114 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -50,7 +50,7 @@ static int perf_gtk__hpp_color_ ## _name(struct perf_hpp 
*hpp,\
 struct hist_entry *he) 
\
 {  
\
struct hists *hists = he-hists;
\
-   double percent = 100.0 * he-_field / hists-stats.total_period;
\
+   double percent = 100.0 * he-stat._field / hists-stats.total_period;   
\
const char *markup; 
\
int ret = 0;
\

\
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 7f043394bef1..f5a1e4f65263 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -19,7 +19,7 @@ static int hpp__width_overhead(struct perf_hpp *hpp 
__maybe_unused)
 static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
struct hists *hists = he-hists;
-   double percent = 100.0 * he-period / hists-stats.total_period;
+   double percent = 100.0 * he-stat.period / hists-stats.total_period;
 
return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
 }
@@ -27,7 +27,7 @@ static int hpp__color_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
 static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
struct hists *hists = he-hists;
-   double percent = 100.0 * he-period / hists-stats.total_period;
+   double percent = 100.0 * he-stat.period / hists-stats.total_period;
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
 
return scnprintf(hpp-buf, hpp-size, fmt, percent);
@@ -48,7 +48,7 @@ static int hpp__width_overhead_sys(struct perf_hpp *hpp 
__maybe_unused)
 static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
 {
struct hists *hists = he-hists;
-   double percent = 100.0 * he-period_sys / hists-stats.total_period;
+   double percent = 100.0 * he-stat.period_sys / 
hists-stats.total_period;
 
return

[PATCH 09/20] perf hists: Add more helpers for hist entry stat

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Add and use he_stat__add_{period,stat} for calculating hist entry's
stat.  It will be used for accumulated stats later as well.

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Stephane Eranian eran...@google.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c |   26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 02476cb3167d..277947a669b2 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -151,6 +151,22 @@ static void hist_entry__add_cpumode_period(struct 
hist_entry *he,
}
 }
 
+static void he_stat__add_period(struct he_stat *he_stat, u64 period)
+{
+   he_stat-period += period;
+   he_stat-nr_events  += 1;
+}
+
+static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
+{
+   dest-period+= src-period;
+   dest-period_sys+= src-period_sys;
+   dest-period_us += src-period_us;
+   dest-period_guest_sys  += src-period_guest_sys;
+   dest-period_guest_us   += src-period_guest_us;
+   dest-nr_events += src-nr_events;
+}
+
 static void hist_entry__decay(struct hist_entry *he)
 {
he-stat.period = (he-stat.period * 7) / 8;
@@ -270,8 +286,7 @@ static struct hist_entry *add_hist_entry(struct hists 
*hists,
cmp = hist_entry__cmp(entry, he);
 
if (!cmp) {
-   he-stat.period += period;
-   ++he-stat.nr_events;
+   he_stat__add_period(he-stat, period);
 
/* If the map of an existing hist_entry has
 * become out-of-date due to an exec() or
@@ -418,12 +433,7 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
 
if (!cmp) {
-   iter-stat.period   += he-stat.period;
-   iter-stat.period_sys   += he-stat.period_sys;
-   iter-stat.period_us+= he-stat.period_us;
-   iter-stat.period_guest_sys += 
he-stat.period_guest_sys;
-   iter-stat.period_guest_us  += 
he-stat.period_guest_us;
-   iter-stat.nr_events+= he-stat.nr_events;
+   he_stat__add_stat(iter-stat, he-stat);
 
if (symbol_conf.use_callchain) {
callchain_cursor_reset(callchain_cursor);
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 17/20] perf ui/gtk: Add support for event group view

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Show group members' overhead also when showing the leader's if event
group is enabled.  At this time, only implemented overhead part in
order to ease review and other parts can be added later once this
patch settled down.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Cc: Pekka Enberg penb...@kernel.org
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/gtk/browser.c |   60 +--
 1 file changed, 46 insertions(+), 14 deletions(-)

diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 4125c6284114..b2c8b8e69e4d 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -45,26 +45,57 @@ static const char *perf_gtk__get_percent_color(double 
percent)
return NULL;
 }
 
+static int perf_gtk__percent_color_snprintf(char *buf, size_t size,
+   u64 period, u64 total_period)
+{
+   int ret = 0;
+   const char *markup;
+   double percent = 100.0 * period / total_period;
+
+   markup = perf_gtk__get_percent_color(percent);
+   if (markup)
+   ret += scnprintf(buf, size, markup);
+
+   ret += scnprintf(buf + ret, size - ret, %6.2f%%, percent);
+
+   if (markup)
+   ret += scnprintf(buf + ret, size - ret, /span);
+
+   return ret;
+}
+
+static int perf_gtk__hpp_color_overhead(struct perf_hpp *hpp,
+   struct hist_entry *he)
+{
+   int ret;
+   struct hists *hists = he-hists;
+
+   ret = perf_gtk__percent_color_snprintf(hpp-buf, hpp-size,
+   he-stat.period, hists-stats.total_period);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   ret += scnprintf(hpp-buf + ret, hpp-size - ret,  );
+   ret += perf_gtk__percent_color_snprintf(hpp-buf + ret,
+   hpp-size - ret,
+   he-group_stats[i].period,
+   hists-group_stats[i].total_period);
+   }
+   }
+   return ret;
+}
+
 #define HPP__COLOR_FN(_name, _field)   
\
 static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, 
\
 struct hist_entry *he) 
\
 {  
\
-   struct hists *hists = he-hists;
\
-   double percent = 100.0 * he-stat._field / hists-stats.total_period;   
\
-   const char *markup; 
\
-   int ret = 0;
\
-   
\
-   markup = perf_gtk__get_percent_color(percent);  
\
-   if (markup) 
\
-   ret += scnprintf(hpp-buf, hpp-size, %s, markup);
\
-   ret += scnprintf(hpp-buf + ret, hpp-size - ret, %6.2f%%, percent);  
\
-   if (markup) 
\
-   ret += scnprintf(hpp-buf + ret, hpp-size - ret, /span);   
\
-   
\
-   return ret; 
\
+   return perf_gtk__percent_color_snprintf(hpp-buf, hpp-size,
\
+   he-stat._field, he-hists-stats.total_period);
\
 }
 
-HPP__COLOR_FN(overhead, period)
 HPP__COLOR_FN(overhead_sys, period_sys)
 HPP__COLOR_FN(overhead_us, period_us)
 HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
@@ -103,6 +134,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct 
hists *hists)
struct perf_hpp hpp = {
.buf= s,
.size   = sizeof(s),
+   .ptr= hists_2_evsel(hists),
};
 
nr_cols = 0;
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 19/20] perf report: Show group description when event group is enabled

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

When using event group viewer, it's better to show the group
description rather than the leader information alone.

If a leader did not contain any member, it's a non-group event.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Cc: Pekka Enberg penb...@kernel.org
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c|   18 ++
 tools/perf/ui/browsers/hists.c |   31 +++
 tools/perf/ui/gtk/browser.c|   14 +++---
 tools/perf/util/evsel.c|   25 +
 tools/perf/util/evsel.h|8 
 5 files changed, 93 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index ba5cfb40818d..e9c9687e021a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -299,6 +299,24 @@ static size_t hists__fprintf_nr_sample_events(struct hists 
*self,
char unit;
unsigned long nr_samples = self-stats.nr_events[PERF_RECORD_SAMPLE];
u64 nr_events = self-stats.total_period;
+   struct perf_evsel *evsel = hists_2_evsel(self);
+   char buf[512];
+   size_t size = sizeof(buf);
+
+   if (symbol_conf.event_group  evsel-nr_members) {
+   int i;
+   struct events_stats *stats;
+
+   perf_evsel__group_desc(evsel, buf, size);
+   evname = buf;
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   stats = self-group_stats[i];
+
+   nr_samples += stats-nr_events[PERF_RECORD_SAMPLE];
+   nr_events += stats-total_period;
+   }
+   }
 
nr_samples = convert_unit(nr_samples, unit);
ret = fprintf(fp, # Samples: %lu%c, nr_samples, unit);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 43eb90969799..e81773bd272e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1123,6 +1123,24 @@ static int hists__browser_title(struct hists *hists, 
char *bf, size_t size,
const struct thread *thread = hists-thread_filter;
unsigned long nr_samples = hists-stats.nr_events[PERF_RECORD_SAMPLE];
u64 nr_events = hists-stats.total_period;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+   char buf[512];
+   size_t buflen = sizeof(buf);
+
+   if (symbol_conf.event_group  evsel-nr_members) {
+   int i;
+   struct events_stats *stats;
+
+   perf_evsel__group_desc(evsel, buf, buflen);
+   ev_name = buf;
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   stats = hists-group_stats[i];
+
+   nr_samples += stats-nr_events[PERF_RECORD_SAMPLE];
+   nr_events += stats-total_period;
+   }
+   }
 
nr_samples = convert_unit(nr_samples, unit);
printed = scnprintf(bf, size,
@@ -1469,6 +1487,19 @@ static void perf_evsel_menu__write(struct ui_browser 
*browser,
ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
   HE_COLORSET_NORMAL);
 
+   if (symbol_conf.event_group  evsel-nr_members) {
+   int i;
+   struct events_stats *stats;
+
+   ev_name = perf_evsel__group_name(evsel);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   stats = evsel-hists.group_stats[i];
+
+   nr_events += stats-nr_events[PERF_RECORD_SAMPLE];
+   }
+   }
+
nr_events = convert_unit(nr_events, unit);
printed = scnprintf(bf, sizeof(bf), %lu%c%s%s, nr_events,
   unit, unit == ' ' ?  :  , ev_name);
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index ae6b941ef3d4..2c0e3e95dbca 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -305,10 +305,18 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist 
*evlist,
const char *evname = perf_evsel__name(pos);
GtkWidget *scrolled_window;
GtkWidget *tab_label;
+   char buf[512];
+   size_t size = sizeof(buf);
 
-   if (symbol_conf.event_group 
-   !perf_evsel__is_group_leader(pos))
-   continue;
+   if (symbol_conf.event_group) {
+   if (!perf_evsel__is_group_leader(pos))
+   continue;
+
+   if (pos-nr_members) {
+   perf_evsel__group_desc(pos, buf, size);
+   evname = buf;
+   }
+   }
 
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index

[PATCH 10/20] perf tools: Keep group information

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Add a few of group-related field in struct perf_{evlist,evsel} so that
the group information in a evlist can be known easily.  It only counts
groups which have more than 1 members since leader-only groups are
treated as non-group events.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/evlist.c   |   10 --
 tools/perf/util/evlist.h   |1 +
 tools/perf/util/evsel.h|   10 ++
 tools/perf/util/parse-events.c |1 +
 tools/perf/util/parse-events.h |1 +
 tools/perf/util/parse-events.y |   10 ++
 6 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index ae89686102f4..ac9730c12884 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -111,20 +111,26 @@ void perf_evlist__splice_list_tail(struct perf_evlist 
*evlist,
 void __perf_evlist__set_leader(struct list_head *list)
 {
struct perf_evsel *evsel, *leader;
+   int count = 0;
 
leader = list_entry(list-next, struct perf_evsel, node);
leader-leader = NULL;
 
list_for_each_entry(evsel, list, node) {
-   if (evsel != leader)
+   if (evsel != leader) {
evsel-leader = leader;
+   evsel-group_idx = count++;
+   }
}
+   leader-nr_members = count;
 }
 
 void perf_evlist__set_leader(struct perf_evlist *evlist)
 {
-   if (evlist-nr_entries)
+   if (evlist-nr_entries) {
+   evlist-nr_groups = evlist-nr_entries  1 ? 1 : 0;
__perf_evlist__set_leader(evlist-entries);
+   }
 }
 
 int perf_evlist__add_default(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 3f1fb66be022..a3a4906d4a4e 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -21,6 +21,7 @@ struct perf_evlist {
struct list_head entries;
struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
int  nr_entries;
+   int  nr_groups;
int  nr_fds;
int  nr_mmaps;
int  mmap_len;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 3ead0d59c03d..407c8e84fee3 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -74,6 +74,10 @@ struct perf_evsel {
int exclude_GH;
struct perf_evsel   *leader;
char*group_name;
+   union {
+   int nr_members;
+   int group_idx;
+   };
 };
 
 struct cpu_map;
@@ -225,4 +229,10 @@ static inline struct perf_evsel *perf_evsel__next(struct 
perf_evsel *evsel)
 {
return list_entry(evsel-node.next, struct perf_evsel, node);
 }
+
+/* Treat a non-group event as a leader */
+static inline bool perf_evsel__is_group_leader(struct perf_evsel *evsel)
+{
+   return evsel-leader == NULL;
+}
 #endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index aed38e4b9dfa..364e518b0fce 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -816,6 +816,7 @@ int parse_events(struct perf_evlist *evlist, const char 
*str,
if (!ret) {
int entries = data.idx - evlist-nr_entries;
perf_evlist__splice_list_tail(evlist, data.list, entries);
+   evlist-nr_groups += data.nr_groups;
return 0;
}
 
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
index c356e443448d..f6b0254afe17 100644
--- a/tools/perf/util/parse-events.h
+++ b/tools/perf/util/parse-events.h
@@ -65,6 +65,7 @@ struct parse_events__term {
 struct parse_events_data__events {
struct list_head list;
int idx;
+   int nr_groups;
 };
 
 struct parse_events_data__terms {
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
index cd88209e3c58..a7810dd0938a 100644
--- a/tools/perf/util/parse-events.y
+++ b/tools/perf/util/parse-events.y
@@ -122,6 +122,11 @@ group_def:
 PE_NAME '{' events '}'
 {
struct list_head *list = $3;
+   struct parse_events_data__events *data = _data;
+
+   /* Count groups only have more than 1 members */
+   if (!list_is_last(list-next, list))
+   data-nr_groups++;
 
parse_events__set_leader($1, list);
$$ = list;
@@ -130,6 +135,11 @@ PE_NAME '{' events '}'
 '{' events '}'
 {
struct list_head *list = $2;
+   struct parse_events_data__events *data = _data;
+
+   /* Count groups only have more than 1 members */
+   if (!list_is_last(list-next, list))
+   data-nr_groups++;
 
parse_events__set_leader(NULL, list);
$$ = list;
-- 
1.7.9.2

--
To unsubscribe from this list: send the line

[PATCH 12/20] perf hists: Collapse group hist_entries to a leader

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

To support viewing an event group together, collapse all of members in
the group to the leader's tree.  The entries in the leaders' tree will
have group_stats to store those information.

This patch introduced an additional field 'event_group' in symbol_conf
to distinguish whether event grouping is enabled or not.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/evsel.h  |5 +++
 tools/perf/util/hist.c   |  108 ++
 tools/perf/util/sort.h   |1 +
 tools/perf/util/symbol.c |4 ++
 tools/perf/util/symbol.h |3 +-
 5 files changed, 112 insertions(+), 9 deletions(-)

diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 407c8e84fee3..039c67297388 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -235,4 +235,9 @@ static inline bool perf_evsel__is_group_leader(struct 
perf_evsel *evsel)
 {
return evsel-leader == NULL;
 }
+
+static inline struct perf_evsel *hists_2_evsel(struct hists *hists)
+{
+   return container_of(hists, struct perf_evsel, hists);
+}
 #endif /* __PERF_EVSEL_H */
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 277947a669b2..95415716c708 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -4,6 +4,7 @@
 #include hist.h
 #include session.h
 #include sort.h
+#include evsel.h
 #include math.h
 
 static bool hists__filter_entry_by_dso(struct hists *hists,
@@ -167,6 +168,32 @@ static void he_stat__add_stat(struct he_stat *dest, struct 
he_stat *src)
dest-nr_events += src-nr_events;
 }
 
+static void hist_entry__add_group_stat(struct hist_entry *he_dest,
+  struct he_stat *src,
+  struct perf_evsel *evsel)
+{
+   struct perf_evsel *leader = evsel-leader;
+
+   if (perf_evsel__is_group_leader(evsel))
+   leader = evsel;
+
+   if (leader-nr_members  !he_dest-group_stats) {
+   /*
+* A group whose nr_members equals to 0 is a leader-only group.
+* So no need to allocate group_stats.
+*/
+   he_dest-group_stats = calloc(leader-nr_members,
+ sizeof(struct he_stat));
+   if (!he_dest-group_stats)
+   return;
+   }
+
+   if (perf_evsel__is_group_leader(evsel))
+   he_stat__add_stat(he_dest-stat, src);
+   else
+   he_stat__add_stat(he_dest-group_stats[evsel-group_idx], src);
+}
+
 static void hist_entry__decay(struct hist_entry *he)
 {
he-stat.period = (he-stat.period * 7) / 8;
@@ -417,13 +444,14 @@ void hist_entry__free(struct hist_entry *he)
  * collapse the histogram
  */
 
-static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
+static bool hists__collapse_insert_entry(struct hists *hists,
 struct rb_root *root,
 struct hist_entry *he)
 {
struct rb_node **p = root-rb_node;
struct rb_node *parent = NULL;
struct hist_entry *iter;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
int64_t cmp;
 
while (*p != NULL) {
@@ -433,7 +461,10 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
 
if (!cmp) {
-   he_stat__add_stat(iter-stat, he-stat);
+   if (symbol_conf.event_group)
+   hist_entry__add_group_stat(iter, he-stat, 
evsel);
+   else
+   he_stat__add_stat(iter-stat, he-stat);
 
if (symbol_conf.use_callchain) {
callchain_cursor_reset(callchain_cursor);
@@ -451,6 +482,19 @@ static bool hists__collapse_insert_entry(struct hists 
*hists __maybe_unused,
p = (*p)-rb_right;
}
 
+   if (symbol_conf.event_group) {
+   /*
+* 'he' is not found in the leader's tree.
+* Insert it to the tree and setup stats properly.
+*/
+   hist_entry__add_group_stat(he, he-stat, evsel);
+
+   if (!perf_evsel__is_group_leader(evsel)) {
+   he-hists = evsel-leader-hists;
+   memset(he-stat, 0, sizeof(he-stat));
+   }
+   }
+
rb_link_node(he-rb_node_in, parent, p);
rb_insert_color(he-rb_node_in, root);
return true;
@@ -481,6 +525,7 @@ static void hists__apply_filters(struct hists *hists, 
struct hist_entry *he)
 static void __hists__collapse_resort(struct hists *hists, bool threaded)
 {
struct rb_root *root;
+   struct rb_root *dest;
struct

[PATCH 14/20] perf report: Make another loop for output resorting

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Now the event grouping viewing requires collapsing all members in a
group to the leader.  Thus hists__output_resort should be called after
collapsing all entries in evlist.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index a61725d89d3e..b7e250d63892 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -416,6 +416,11 @@ static int __cmd_report(struct perf_report *rep)
hists-symbol_filter_str = rep-symbol_filter_str;
 
hists__collapse_resort(hists);
+   }
+
+   list_for_each_entry(pos, session-evlist-entries, node) {
+   struct hists *hists = pos-hists;
+
hists__output_resort(hists);
nr_samples += hists-stats.nr_events[PERF_RECORD_SAMPLE];
}
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 16/20] perf ui/browser: Add support for event group view

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Show group members' overhead also when showing the leader's if event
group is enabled.  At this time, only implemented overhead part in
order to ease review and other parts can be added later once this
patch settled down.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/browsers/hists.c |   33 +++--
 tools/perf/ui/hist.c   |5 -
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 0568536ecf67..df0ddeeeb860 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -565,6 +565,34 @@ static int hist_browser__show_callchain(struct 
hist_browser *browser,
return row - first_row;
 }
 
+static int hist_browser__hpp_color_overhead(struct perf_hpp *hpp,
+   struct hist_entry *he)
+{
+   int ret;
+   struct hists *hists = he-hists;
+   double percent = 100.0 * he-stat.period / hists-stats.total_period;
+
+   /* the leader determines color */
+   *(double *) hpp-ptr = percent;
+
+   ret = scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   u64 period = he-group_stats[i].period;
+   u64 total = hists-group_stats[i].total_period;
+
+   percent = 100.0 * period / total;
+   ret += scnprintf(hpp-buf + ret, hpp-size - ret,
+ %6.2f%%, percent);
+   }
+   }
+   return ret;
+}
+
 #define HPP__COLOR_FN(_name, _field)   \
 static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
 struct hist_entry *he) \
@@ -575,7 +603,6 @@ static int hist_browser__hpp_color_ ## _name(struct 
perf_hpp *hpp,  \
return scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);  \
 }
 
-HPP__COLOR_FN(overhead, period)
 HPP__COLOR_FN(overhead_sys, period_sys)
 HPP__COLOR_FN(overhead_us, period_us)
 HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
@@ -610,6 +637,7 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
char folded_sign = ' ';
bool current_entry = ui_browser__is_current_entry(browser-b, row);
off_t row_offset = entry-row_offset;
+   bool first = true;
 
if (current_entry) {
browser-he_selection = entry;
@@ -633,10 +661,11 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
if (!perf_hpp__format[i].cond)
continue;
 
-   if (i) {
+   if (!first) {
slsmg_printf(  );
width -= 2;
}
+   first = false;
 
if (perf_hpp__format[i].color) {
hpp.ptr = percent;
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index ad4efb772796..624f3d08937f 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -462,6 +462,9 @@ unsigned int hists__sort_list_width(struct hists *hists)
 {
struct sort_entry *se;
int i, ret = 0;
+   struct perf_hpp dummy_hpp = {
+   .ptr= hists_2_evsel(hists),
+   };
 
for (i = 0; i  PERF_HPP__MAX_INDEX; i++) {
if (!perf_hpp__format[i].cond)
@@ -469,7 +472,7 @@ unsigned int hists__sort_list_width(struct hists *hists)
if (i)
ret += 2;
 
-   ret += perf_hpp__format[i].width(NULL);
+   ret += perf_hpp__format[i].width(dummy_hpp);
}
 
list_for_each_entry(se, hist_entry__sort_list, list)
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 20/20] perf report: Add --group option

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Add --group option to enable event grouping.  When enabled, all the
group members information will be shown together with the leader.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index e9c9687e021a..9ed3a64315da 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -664,6 +664,8 @@ int cmd_report(int argc, const char **argv, const char 
*prefix __maybe_unused)
   Specify disassembler style (e.g. -M intel for intel 
syntax)),
OPT_BOOLEAN(0, show-total-period, symbol_conf.show_total_period,
Show a column with the sum of periods),
+   OPT_BOOLEAN(0, group, symbol_conf.event_group,
+   Show event group information together),
OPT_CALLBACK_NOOPT('b', branch-stack, sort__branch_mode, ,
use branch records for histogram filling, 
parse_branch_mode),
OPT_STRING(0, objdump, objdump_path, path,
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 18/20] perf report: Bypass non-leader events when event group is enabled

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Since we have all necessary information in the leader events and
other members don't, bypass members.  Member events will be shown
along with the leaders if event group is enabled.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Cc: Pekka Enberg penb...@kernel.org
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-report.c|4 
 tools/perf/ui/browsers/hists.c |   39 +--
 tools/perf/ui/gtk/browser.c|4 
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index b7e250d63892..ba5cfb40818d 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -319,6 +319,10 @@ static int perf_evlist__tty_browse_hists(struct 
perf_evlist *evlist,
struct hists *hists = pos-hists;
const char *evname = perf_evsel__name(pos);
 
+   if (symbol_conf.event_group 
+   !perf_evsel__is_group_leader(pos))
+   continue;
+
hists__fprintf_nr_sample_events(hists, evname, stdout);
hists__fprintf(hists, true, 0, 0, stdout);
fprintf(stdout, \n\n);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index df0ddeeeb860..43eb90969799 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1578,8 +1578,19 @@ out:
return key;
 }
 
+static bool filter_group_entries(struct ui_browser *self __maybe_unused,
+void *entry)
+{
+   struct perf_evsel *evsel = list_entry(entry, struct perf_evsel, node);
+
+   if (symbol_conf.event_group  !perf_evsel__is_group_leader(evsel))
+   return true;
+
+   return false;
+}
+
 static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
-  const char *help,
+  int nr_entries, const char *help,
   void(*timer)(void *arg), void *arg,
   int delay_secs)
 {
@@ -1590,7 +1601,8 @@ static int __perf_evlist__tui_browse_hists(struct 
perf_evlist *evlist,
.refresh= ui_browser__list_head_refresh,
.seek   = ui_browser__list_head_seek,
.write  = perf_evsel_menu__write,
-   .nr_entries = evlist-nr_entries,
+   .filter = filter_group_entries,
+   .nr_entries = nr_entries,
.priv   = evlist,
},
};
@@ -1605,7 +1617,7 @@ static int __perf_evlist__tui_browse_hists(struct 
perf_evlist *evlist,
menu.b.width = line_len;
}
 
-   return perf_evsel_menu__run(menu, evlist-nr_entries, help, timer,
+   return perf_evsel_menu__run(menu, nr_entries, help, timer,
arg, delay_secs);
 }
 
@@ -1613,15 +1625,30 @@ int perf_evlist__tui_browse_hists(struct perf_evlist 
*evlist, const char *help,
  void(*timer)(void *arg), void *arg,
  int delay_secs)
 {
-   if (evlist-nr_entries == 1) {
+   int nr_entries = evlist-nr_entries;
+
+single_entry:
+   if (nr_entries == 1) {
struct perf_evsel *first = list_entry(evlist-entries.next,
  struct perf_evsel, node);
const char *ev_name = perf_evsel__name(first);
-   return perf_evsel__hists_browse(first, evlist-nr_entries, help,
+   return perf_evsel__hists_browse(first, nr_entries, help,
ev_name, false, timer, arg,
delay_secs);
}
 
-   return __perf_evlist__tui_browse_hists(evlist, help,
+   if (symbol_conf.event_group) {
+   struct perf_evsel *pos;
+
+   nr_entries = 0;
+   list_for_each_entry(pos, evlist-entries, node)
+   if (perf_evsel__is_group_leader(pos))
+   nr_entries++;
+
+   if (nr_entries == 1)
+   goto single_entry;
+   }
+
+   return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
   timer, arg, delay_secs);
 }
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index b2c8b8e69e4d..ae6b941ef3d4 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -306,6 +306,10 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist 
*evlist,
GtkWidget *scrolled_window;
GtkWidget *tab_label;
 
+   if (symbol_conf.event_group

[PATCH 15/20] perf ui/hist: Add support for event group view

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Show group members' overhead also when showing the leader's if event
group is enabled.  At this time, only implemented overhead part in
order to ease review and other parts can be added later once this
patch settled down.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/hist.c   |   66 
 tools/perf/ui/stdio/hist.c |2 ++
 2 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index f5a1e4f65263..ad4efb772796 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -3,34 +3,90 @@
 #include ../util/hist.h
 #include ../util/util.h
 #include ../util/sort.h
+#include ../util/evsel.h
 
 
 /* hist period print (hpp) functions */
 static int hpp__header_overhead(struct perf_hpp *hpp)
 {
-   return scnprintf(hpp-buf, hpp-size, Overhead);
+   int len = 8;
+
+   if (symbol_conf.event_group) {
+   struct perf_evsel *evsel = hpp-ptr;
+
+   BUG_ON(!perf_evsel__is_group_leader(evsel));
+
+   len += evsel-nr_members * 8;
+   }
+   return scnprintf(hpp-buf, hpp-size, %*s, len, Overhead);
 }
 
-static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused)
+static int hpp__width_overhead(struct perf_hpp *hpp)
 {
-   return 8;
+   int len = 8;
+
+   if (symbol_conf.event_group) {
+   struct perf_evsel *evsel = hpp-ptr;
+
+   len += evsel-nr_members * 8;
+   }
+   return len;
 }
 
 static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
+   int ret;
struct hists *hists = he-hists;
double percent = 100.0 * he-stat.period / hists-stats.total_period;
 
-   return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
+   ret = percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   u64 period = he-group_stats[i].period;
+   u64 total = hists-group_stats[i].total_period;
+
+   percent = 100.0 * period / total;
+   ret += percent_color_snprintf(hpp-buf + ret,
+ hpp-size - ret,
+  %6.2f%%, percent);
+   }
+
+   }
+   return ret;
 }
 
 static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
+   int ret;
struct hists *hists = he-hists;
double percent = 100.0 * he-stat.period / hists-stats.total_period;
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
 
-   return scnprintf(hpp-buf, hpp-size, fmt, percent);
+   ret = scnprintf(hpp-buf, hpp-size, fmt, percent);
+
+   if (symbol_conf.event_group) {
+   int i;
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+
+   for (i = 0; i  evsel-nr_members; i++) {
+   u64 period = he-group_stats[i].period;
+   u64 total = hists-group_stats[i].total_period;
+
+   if (symbol_conf.field_sep) {
+   ret += scnprintf(hpp-buf + ret,
+hpp-size - ret,  );
+   }
+   percent = 100.0 * period / total;
+   ret += scnprintf(hpp-buf + ret, hpp-size - ret,
+fmt, percent);
+   }
+
+   }
+   return ret;
 }
 
 static int hpp__header_overhead_sys(struct perf_hpp *hpp)
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index fbd4e32d0743..1d4f1ddc8bf8 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -3,6 +3,7 @@
 #include ../../util/util.h
 #include ../../util/hist.h
 #include ../../util/sort.h
+#include ../../util/evsel.h
 
 
 static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
@@ -346,6 +347,7 @@ size_t hists__fprintf(struct hists *hists, bool 
show_header, int max_rows,
struct perf_hpp dummy_hpp = {
.buf= bf,
.size   = sizeof(bf),
+   .ptr= hists_2_evsel(hists),
};
bool first = true;
 
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 13/20] perf hists: Maintain total periods of group members in the leader

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Like group_stats in hist_entry, total periods information also need to
be known to the leader.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c |   25 +
 tools/perf/util/hist.h |1 +
 2 files changed, 26 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 95415716c708..48488057c3da 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -194,6 +194,28 @@ static void hist_entry__add_group_stat(struct hist_entry 
*he_dest,
he_stat__add_stat(he_dest-group_stats[evsel-group_idx], src);
 }
 
+static void hists__add_group_stat(struct hists *hists)
+{
+   struct perf_evsel *evsel = hists_2_evsel(hists);
+   struct perf_evsel *leader = evsel-leader;
+   struct hists *leader_hists;
+
+   if (perf_evsel__is_group_leader(evsel))
+   return;
+
+   leader_hists = leader-hists;
+
+   if (!leader_hists-group_stats) {
+   leader_hists-group_stats = calloc(leader-nr_members,
+  sizeof(struct events_stats));
+   if (!leader_hists-group_stats)
+   return;
+   }
+
+   memcpy(leader_hists-group_stats[evsel-group_idx],
+  hists-stats, sizeof(struct events_stats));
+}
+
 static void hist_entry__decay(struct hist_entry *he)
 {
he-stat.period = (he-stat.period * 7) / 8;
@@ -561,6 +583,9 @@ static void __hists__collapse_resort(struct hists *hists, 
bool threaded)
hists__apply_filters(hists, n);
}
}
+
+   if (symbol_conf.event_group)
+   hists__add_group_stat(hists);
 }
 
 void hists__collapse_resort(struct hists *hists)
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 66cb31fe81d2..e150cf86b94a 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -66,6 +66,7 @@ struct hists {
const char  *symbol_filter_str;
pthread_mutex_t lock;
struct events_stats stats;
+   struct events_stats *group_stats;
u64 event_stream;
u16 col_len[HISTC_NR_COLS];
 };
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 11/20] perf header: Add HEADER_GROUP_DESC feature

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Save group relationship information so that it can be restored when
perf report is running.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/builtin-record.c |3 +
 tools/perf/util/header.c|  152 +++
 tools/perf/util/header.h|2 +
 3 files changed, 157 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 8c029fe2e22c..7940f0dd3db9 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -558,6 +558,9 @@ static int __cmd_record(struct perf_record *rec, int argc, 
const char **argv)
goto out_delete_session;
}
 
+   if (!evsel_list-nr_groups)
+   perf_header__clear_feat(session-header, HEADER_GROUP_DESC);
+
/*
 * perf_session__delete(session) will be called at perf_record__exit()
 */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 7daad237dea5..caceb33d8d1b 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1072,6 +1072,41 @@ static int write_pmu_mappings(int fd, struct perf_header 
*h __maybe_unused,
 }
 
 /*
+ * File format:
+ *
+ * struct group_descs {
+ * u32 nr_groups;
+ * struct group_desc {
+ * charname[];
+ * u32 leader_idx;
+ * u32 nr_members;
+ * }[nr_groups];
+ * };
+ */
+static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
+   struct perf_evlist *evlist)
+{
+   u32 nr_groups = evlist-nr_groups;
+   struct perf_evsel *evsel;
+
+   do_write(fd, nr_groups, sizeof(nr_groups));
+
+   list_for_each_entry(evsel, evlist-entries, node) {
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0) {
+   const char *name = evsel-group_name ?: {anon_group};
+   u32 leader_idx = evsel-idx;
+   u32 nr_members = evsel-nr_members;
+
+   do_write_string(fd, name);
+   do_write(fd, leader_idx, sizeof(leader_idx));
+   do_write(fd, nr_members, sizeof(nr_members));
+   }
+   }
+   return 0;
+}
+
+/*
  * default get_cpuid(): nothing gets recorded
  * actual implementation must be in arch/$(ARCH)/util/header.c
  */
@@ -1432,6 +1467,31 @@ error:
fprintf(fp, # pmu mappings: unable to read\n);
 }
 
+static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,
+FILE *fp)
+{
+   struct perf_session *session;
+   struct perf_evsel *evsel;
+   u32 nr = 0;
+
+   session = container_of(ph, struct perf_session, header);
+
+   list_for_each_entry(evsel, session-evlist-entries, node) {
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0) {
+   fprintf(fp, # group: %s{%s, evsel-group_name ?: ,
+   perf_evsel__name(evsel));
+
+   nr = evsel-nr_members;
+   } else if (nr) {
+   fprintf(fp, ,%s, perf_evsel__name(evsel));
+
+   if (--nr == 0)
+   fprintf(fp, }\n);
+   }
+   }
+}
+
 static int __event_process_build_id(struct build_id_event *bev,
char *filename,
struct perf_session *session)
@@ -1946,6 +2006,97 @@ error:
return -1;
 }
 
+static int process_group_desc(struct perf_file_section *section __maybe_unused,
+ struct perf_header *ph, int fd,
+ void *data __maybe_unused)
+{
+   size_t ret = -1;
+   u32 i, nr, nr_groups;
+   struct perf_session *session;
+   struct perf_evsel *evsel, *leader;
+   struct group_desc {
+   char *name;
+   u32 leader_idx;
+   u32 nr_members;
+   } *desc;
+
+   ret = read(fd, nr_groups, sizeof(nr_groups));
+   if (ret != sizeof(nr_groups))
+   return -1;
+
+   if (ph-needs_swap)
+   nr_groups = bswap_32(nr_groups);
+
+   ph-env.nr_groups = nr_groups;
+   if (!nr_groups) {
+   pr_debug(group desc not available\n);
+   return 0;
+   }
+
+   desc = calloc(nr_groups, sizeof(*desc));
+   if (!desc)
+   return -1;
+
+   for (i = 0; i  nr_groups; i++) {
+   desc[i].name = do_read_string(fd, ph);
+   if (!desc[i].name)
+   goto out_free;
+
+   ret = read(fd, desc[i].leader_idx, sizeof(u32));
+   if (ret != sizeof(u32))
+   goto out_free;
+
+   ret = read(fd, desc[i].nr_members, sizeof(u32

[PATCH 06/20] perf diff: Removing the total_period argument from output code

2012-10-04 Thread Namhyung Kim
From: Jiri Olsa jo...@redhat.com

The total_period is available in struct hists data via the 'struct
hist_entry::hists' pointer. There's no need to carry it through the
output code path.

Removing 'struct perf_hpp::total_period' pointer, because it's no
longer needed.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/browsers/hists.c |4 ++--
 tools/perf/ui/gtk/browser.c|4 ++--
 tools/perf/ui/hist.c   |   37 ++---
 tools/perf/ui/stdio/hist.c |   15 +--
 tools/perf/util/hist.h |1 -
 5 files changed, 35 insertions(+), 26 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index bbd11c2f69db..d359795454d0 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -569,7 +569,8 @@ static int hist_browser__show_callchain(struct hist_browser 
*browser,
 static int hist_browser__hpp_color_ ## _name(struct perf_hpp *hpp, \
 struct hist_entry *he) \
 {  \
-   double percent = 100.0 * he-_field / hpp-total_period;\
+   struct hists *hists = he-hists;\
+   double percent = 100.0 * he-_field / hists-stats.total_period;\
*(double *)hpp-ptr = percent;  \
return scnprintf(hpp-buf, hpp-size, %6.2f%%, percent);  \
 }
@@ -624,7 +625,6 @@ static int hist_browser__show_entry(struct hist_browser 
*browser,
struct perf_hpp hpp = {
.buf= s,
.size   = sizeof(s),
-   .total_period   = browser-hists-stats.total_period,
};
 
ui_browser__gotorc(browser-b, row, 0);
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c
index 2bc08f6af714..3cbb1d622ed2 100644
--- a/tools/perf/ui/gtk/browser.c
+++ b/tools/perf/ui/gtk/browser.c
@@ -49,7 +49,8 @@ static const char *perf_gtk__get_percent_color(double percent)
 static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, 
\
 struct hist_entry *he) 
\
 {  
\
-   double percent = 100.0 * he-_field / hpp-total_period;
\
+   struct hists *hists = he-hists;
\
+   double percent = 100.0 * he-_field / hists-stats.total_period;
\
const char *markup; 
\
int ret = 0;
\

\
@@ -102,7 +103,6 @@ static void perf_gtk__show_hists(GtkWidget *window, struct 
hists *hists)
struct perf_hpp hpp = {
.buf= s,
.size   = sizeof(s),
-   .total_period   = hists-stats.total_period,
};
 
nr_cols = 0;
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index e8853f7780a3..7f043394bef1 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -18,14 +18,16 @@ static int hpp__width_overhead(struct perf_hpp *hpp 
__maybe_unused)
 
 static int hpp__color_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
-   double percent = 100.0 * he-period / hpp-total_period;
+   struct hists *hists = he-hists;
+   double percent = 100.0 * he-period / hists-stats.total_period;
 
return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
 }
 
 static int hpp__entry_overhead(struct perf_hpp *hpp, struct hist_entry *he)
 {
-   double percent = 100.0 * he-period / hpp-total_period;
+   struct hists *hists = he-hists;
+   double percent = 100.0 * he-period / hists-stats.total_period;
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
 
return scnprintf(hpp-buf, hpp-size, fmt, percent);
@@ -45,13 +47,16 @@ static int hpp__width_overhead_sys(struct perf_hpp *hpp 
__maybe_unused)
 
 static int hpp__color_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he)
 {
-   double percent = 100.0 * he-period_sys / hpp-total_period;
+   struct hists *hists = he-hists;
+   double percent = 100.0 * he-period_sys / hists-stats.total_period;
+
return percent_color_snprintf(hpp-buf, hpp-size, %6.2f%%, percent);
 }
 
 static int hpp__entry_overhead_sys(struct perf_hpp *hpp, struct hist_entry *he

[PATCH 08/20] perf hists: Move he-stat.nr_events initialization to a template

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Since it is set to 1 for a new hist entry, no need to set to
separately.  Move it to a template entry.

Cc: Jiri Olsa jo...@redhat.com
Cc: Arun Sharma asha...@fb.com
Cc: Stephane Eranian eran...@google.com
Cc: Frederic Weisbecker fweis...@gmail.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/util/hist.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 3197f3f50018..02476cb3167d 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -223,7 +223,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry 
*template)
 
if (he != NULL) {
*he = *template;
-   he-stat.nr_events = 1;
+
if (he-ms.map)
he-ms.map-referenced = true;
if (symbol_conf.use_callchain)
@@ -323,6 +323,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists 
*self,
.level  = al-level,
.stat = {
.period = period,
+   .nr_events = 1,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
@@ -348,6 +349,7 @@ struct hist_entry *__hists__add_entry(struct hists *self,
.level  = al-level,
.stat = {
.period = period,
+   .nr_events = 1,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
-- 
1.7.9.2

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 03/20] perf hists: Separate overhead and baseline columns

2012-10-04 Thread Namhyung Kim
From: Jiri Olsa jo...@redhat.com

Currently the overhead and baseline columns are handled within
single function and the distinction is made by 'baseline hists'
pointer passed by 'struct perf_hpp::ptr'.

Since hists pointer is now part of each hist_entry, it's possible
to locate paired hists pointer directly from the passed struct
hist_entry pointer.

Also separating those 2 columns makes the code more obvious.

Cc: Arnaldo Carvalho de Melo a...@ghostprotocols.net
Cc: Peter Zijlstra a.p.zijls...@chello.nl
Cc: Ingo Molnar mi...@elte.hu
Cc: Paul Mackerras pau...@samba.org
Cc: Corey Ashford cjash...@linux.vnet.ibm.com
Cc: Frederic Weisbecker fweis...@gmail.com
Cc: Namhyung Kim namhy...@kernel.org
Signed-off-by: Jiri Olsa jo...@redhat.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
 tools/perf/ui/hist.c   |   74 
 tools/perf/ui/stdio/hist.c |   11 +--
 tools/perf/util/hist.h |1 +
 3 files changed, 58 insertions(+), 28 deletions(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 55b9ca8f084c..532a60177c32 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -8,9 +8,7 @@
 /* hist period print (hpp) functions */
 static int hpp__header_overhead(struct perf_hpp *hpp)
 {
-   const char *fmt = hpp-ptr ? Baseline : Overhead;
-
-   return scnprintf(hpp-buf, hpp-size, fmt);
+   return scnprintf(hpp-buf, hpp-size, Overhead);
 }
 
 static int hpp__width_overhead(struct perf_hpp *hpp __maybe_unused)
@@ -22,17 +20,6 @@ static int hpp__color_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
 {
double percent = 100.0 * he-period / hpp-total_period;
 
-   if (hpp-ptr) {
-   struct hists *old_hists = hpp-ptr;
-   u64 total_period = old_hists-stats.total_period;
-   u64 base_period = he-pair ? he-pair-period : 0;
-
-   if (total_period)
-   percent = 100.0 * base_period / total_period;
-   else
-   percent = 0.0;
-   }
-
return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
 }
 
@@ -41,17 +28,6 @@ static int hpp__entry_overhead(struct perf_hpp *hpp, struct 
hist_entry *he)
double percent = 100.0 * he-period / hpp-total_period;
const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
 
-   if (hpp-ptr) {
-   struct hists *old_hists = hpp-ptr;
-   u64 total_period = old_hists-stats.total_period;
-   u64 base_period = he-pair ? he-pair-period : 0;
-
-   if (total_period)
-   percent = 100.0 * base_period / total_period;
-   else
-   percent = 0.0;
-   }
-
return scnprintf(hpp-buf, hpp-size, fmt, percent);
 }
 
@@ -159,6 +135,47 @@ static int hpp__entry_overhead_guest_us(struct perf_hpp 
*hpp,
return scnprintf(hpp-buf, hpp-size, fmt, percent);
 }
 
+static int hpp__header_baseline(struct perf_hpp *hpp)
+{
+   return scnprintf(hpp-buf, hpp-size, Baseline);
+}
+
+static int hpp__width_baseline(struct perf_hpp *hpp __maybe_unused)
+{
+   return 8;
+}
+
+static double baseline_percent(struct hist_entry *he)
+{
+   struct hist_entry *pair = he-pair;
+   struct hists *pair_hists = pair ? pair-hists : NULL;
+   double percent = 0.0;
+
+   if (pair) {
+   u64 total_period = pair_hists-stats.total_period;
+   u64 base_period  = pair-period;
+
+   percent = 100.0 * base_period / total_period;
+   }
+
+   return percent;
+}
+
+static int hpp__color_baseline(struct perf_hpp *hpp, struct hist_entry *he)
+{
+   double percent = baseline_percent(he);
+
+   return percent_color_snprintf(hpp-buf, hpp-size,  %6.2f%%, percent);
+}
+
+static int hpp__entry_baseline(struct perf_hpp *hpp, struct hist_entry *he)
+{
+   double percent = baseline_percent(he);
+   const char *fmt = symbol_conf.field_sep ? %.2f :  %6.2f%%;
+
+   return scnprintf(hpp-buf, hpp-size, fmt, percent);
+}
+
 static int hpp__header_samples(struct perf_hpp *hpp)
 {
const char *fmt = symbol_conf.field_sep ? %s : %11s;
@@ -269,6 +286,7 @@ static int hpp__entry_displ(struct perf_hpp *hpp,
.entry  = hpp__entry_ ## _name
 
 struct perf_hpp_fmt perf_hpp__format[] = {
+   { .cond = false, HPP__COLOR_PRINT_FNS(baseline) },
{ .cond = true,  HPP__COLOR_PRINT_FNS(overhead) },
{ .cond = false, HPP__COLOR_PRINT_FNS(overhead_sys) },
{ .cond = false, HPP__COLOR_PRINT_FNS(overhead_us) },
@@ -302,6 +320,8 @@ void perf_hpp__init(bool need_pair, bool show_displacement)
perf_hpp__format[PERF_HPP__PERIOD].cond = true;
 
if (need_pair) {
+   perf_hpp__format[PERF_HPP__OVERHEAD].cond = false;
+   perf_hpp__format[PERF_HPP__BASELINE].cond = true;
perf_hpp__format[PERF_HPP__DELTA].cond = true

[PATCH UPDATED 11/20] perf header: Add HEADER_GROUP_DESC feature

2012-10-04 Thread Namhyung Kim
From: Namhyung Kim namhyung@lge.com

Save group relationship information so that it can be restored when
perf report is running.

Cc: Jiri Olsa jo...@redhat.com
Cc: Stephane Eranian eran...@google.com
Signed-off-by: Namhyung Kim namhy...@kernel.org
---
Initialize leader to NULL in order to avoid 'may be used uninitialized'
warning from gcc (gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1))

 tools/perf/builtin-record.c |3 +
 tools/perf/util/header.c|  152 +++
 tools/perf/util/header.h|2 +
 3 files changed, 157 insertions(+)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 8c029fe2e22c..7940f0dd3db9 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -558,6 +558,9 @@ static int __cmd_record(struct perf_record *rec, int argc, 
const char **argv)
goto out_delete_session;
}
 
+   if (!evsel_list-nr_groups)
+   perf_header__clear_feat(session-header, HEADER_GROUP_DESC);
+
/*
 * perf_session__delete(session) will be called at perf_record__exit()
 */
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 7daad237dea5..8969c20986c2 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1072,6 +1072,41 @@ static int write_pmu_mappings(int fd, struct perf_header 
*h __maybe_unused,
 }
 
 /*
+ * File format:
+ *
+ * struct group_descs {
+ * u32 nr_groups;
+ * struct group_desc {
+ * charname[];
+ * u32 leader_idx;
+ * u32 nr_members;
+ * }[nr_groups];
+ * };
+ */
+static int write_group_desc(int fd, struct perf_header *h __maybe_unused,
+   struct perf_evlist *evlist)
+{
+   u32 nr_groups = evlist-nr_groups;
+   struct perf_evsel *evsel;
+
+   do_write(fd, nr_groups, sizeof(nr_groups));
+
+   list_for_each_entry(evsel, evlist-entries, node) {
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0) {
+   const char *name = evsel-group_name ?: {anon_group};
+   u32 leader_idx = evsel-idx;
+   u32 nr_members = evsel-nr_members;
+
+   do_write_string(fd, name);
+   do_write(fd, leader_idx, sizeof(leader_idx));
+   do_write(fd, nr_members, sizeof(nr_members));
+   }
+   }
+   return 0;
+}
+
+/*
  * default get_cpuid(): nothing gets recorded
  * actual implementation must be in arch/$(ARCH)/util/header.c
  */
@@ -1432,6 +1467,31 @@ error:
fprintf(fp, # pmu mappings: unable to read\n);
 }
 
+static void print_group_desc(struct perf_header *ph, int fd __maybe_unused,
+FILE *fp)
+{
+   struct perf_session *session;
+   struct perf_evsel *evsel;
+   u32 nr = 0;
+
+   session = container_of(ph, struct perf_session, header);
+
+   list_for_each_entry(evsel, session-evlist-entries, node) {
+   if (perf_evsel__is_group_leader(evsel) 
+   evsel-nr_members  0) {
+   fprintf(fp, # group: %s{%s, evsel-group_name ?: ,
+   perf_evsel__name(evsel));
+
+   nr = evsel-nr_members;
+   } else if (nr) {
+   fprintf(fp, ,%s, perf_evsel__name(evsel));
+
+   if (--nr == 0)
+   fprintf(fp, }\n);
+   }
+   }
+}
+
 static int __event_process_build_id(struct build_id_event *bev,
char *filename,
struct perf_session *session)
@@ -1946,6 +2006,97 @@ error:
return -1;
 }
 
+static int process_group_desc(struct perf_file_section *section __maybe_unused,
+ struct perf_header *ph, int fd,
+ void *data __maybe_unused)
+{
+   size_t ret = -1;
+   u32 i, nr, nr_groups;
+   struct perf_session *session;
+   struct perf_evsel *evsel, *leader = NULL;
+   struct group_desc {
+   char *name;
+   u32 leader_idx;
+   u32 nr_members;
+   } *desc;
+
+   ret = read(fd, nr_groups, sizeof(nr_groups));
+   if (ret != sizeof(nr_groups))
+   return -1;
+
+   if (ph-needs_swap)
+   nr_groups = bswap_32(nr_groups);
+
+   ph-env.nr_groups = nr_groups;
+   if (!nr_groups) {
+   pr_debug(group desc not available\n);
+   return 0;
+   }
+
+   desc = calloc(nr_groups, sizeof(*desc));
+   if (!desc)
+   return -1;
+
+   for (i = 0; i  nr_groups; i++) {
+   desc[i].name = do_read_string(fd, ph);
+   if (!desc[i].name)
+   goto out_free;
+
+   ret = read(fd, desc[i].leader_idx, sizeof(u32));
+   if (ret

  1   2   3   4   5   6   7   8   9   10   >