* [PATCH 01/16] perf hists: Add missing period_* fields when collapsing a hist entry
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-28 16:37 ` [tip:perf/core] " tip-bot for Namhyung Kim
2012-09-26 7:47 ` [PATCH 02/16] perf hists: Introduce struct he_stat Namhyung Kim
` (14 subsequent siblings)
15 siblings, 1 reply; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Arun Sharma,
Frederic Weisbecker
From: Namhyung Kim <namhyung.kim@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 sys us 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 sys us
# ........ ........ ........
#
100.00% 0.06% 44.83%
After:
$ perf report --stdio --showcpuutilization -s comm
[SNIP]
# Overhead sys us
# ........ ........ ........
#
100.00% 0.07% 99.93%
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [tip:perf/core] perf hists: Add missing period_* fields when collapsing a hist entry
2012-09-26 7:47 ` [PATCH 01/16] perf hists: Add missing period_* fields when collapsing a hist entry Namhyung Kim
@ 2012-09-28 16:37 ` tip-bot for Namhyung Kim
0 siblings, 0 replies; 20+ messages in thread
From: tip-bot for Namhyung Kim @ 2012-09-28 16:37 UTC (permalink / raw)
To: linux-tip-commits
Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, a.p.zijlstra,
namhyung.kim, namhyung, jolsa, fweisbec, dsahern, tglx, asharma
Commit-ID: 9ec60972a38011ad8a5676f4cd5e51ac508c36b6
Gitweb: http://git.kernel.org/tip/9ec60972a38011ad8a5676f4cd5e51ac508c36b6
Author: Namhyung Kim <namhyung.kim@lge.com>
AuthorDate: Wed, 26 Sep 2012 16:47:28 +0900
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 26 Sep 2012 20:44:11 -0300
perf hists: Add missing period_* fields when collapsing a hist entry
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 sys us 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 sys us
# ........ ........ ........
#
100.00% 0.06% 44.83%
After:
$ perf report --stdio --showcpuutilization -s comm
[SNIP]
# Overhead sys us
# ........ ........ ........
#
100.00% 0.07% 99.93%
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Arun Sharma <asharma@fb.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1348645663-25303-2-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/hist.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 6ec5398..236bc9d 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,
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/16] perf hists: Introduce struct he_stat
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
2012-09-26 7:47 ` [PATCH 01/16] perf hists: Add missing period_* fields when collapsing a hist entry Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 03/16] perf hists: Move he->stat.nr_events initialization to a template Namhyung Kim
` (13 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Arun Sharma,
Frederic Weisbecker
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@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)
percent = 100.0 * base_period / total_period;
@@ -69,13 +69,13 @@ 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;
+ double percent = 100.0 * he->stat.period_sys / hpp->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)
{
- double percent = 100.0 * he->period_sys / hpp->total_period;
+ double percent = 100.0 * he->stat.period_sys / hpp->total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -95,13 +95,13 @@ static int hpp__width_overhead_us(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period_us / hpp->total_period;
+ double percent = 100.0 * he->stat.period_us / hpp->total_period;
return percent_color_snprintf(hpp->buf, hpp->size, "%6.2f%%", percent);
}
static int hpp__entry_overhead_us(struct perf_hpp *hpp, struct hist_entry *he)
{
- double percent = 100.0 * he->period_us / hpp->total_period;
+ double percent = 100.0 * he->stat.period_us / hpp->total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : "%6.2f%%";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -120,14 +120,14 @@ static int hpp__width_overhead_guest_sys(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_guest_sys(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_sys / hpp->total_period;
+ double percent = 100.0 * he->stat.period_guest_sys / hpp->total_period;
return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent);
}
static int hpp__entry_overhead_guest_sys(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_sys / hpp->total_period;
+ double percent = 100.0 * he->stat.period_guest_sys / hpp->total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% ";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -146,14 +146,14 @@ static int hpp__width_overhead_guest_us(struct perf_hpp *hpp __maybe_unused)
static int hpp__color_overhead_guest_us(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_us / hpp->total_period;
+ double percent = 100.0 * he->stat.period_guest_us / hpp->total_period;
return percent_color_snprintf(hpp->buf, hpp->size, " %6.2f%% ", percent);
}
static int hpp__entry_overhead_guest_us(struct perf_hpp *hpp,
struct hist_entry *he)
{
- double percent = 100.0 * he->period_guest_us / hpp->total_period;
+ double percent = 100.0 * he->stat.period_guest_us / hpp->total_period;
const char *fmt = symbol_conf.field_sep ? "%.2f" : " %6.2f%% ";
return scnprintf(hpp->buf, hpp->size, fmt, percent);
@@ -175,7 +175,7 @@ static int hpp__entry_samples(struct perf_hpp *hpp, struct hist_entry *he)
{
const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%11" PRIu64;
- return scnprintf(hpp->buf, hpp->size, fmt, he->nr_events);
+ return scnprintf(hpp->buf, hpp->size, fmt, he->stat.nr_events);
}
static int hpp__header_period(struct perf_hpp *hpp)
@@ -194,7 +194,7 @@ static int hpp__entry_period(struct perf_hpp *hpp, struct hist_entry *he)
{
const char *fmt = symbol_conf.field_sep ? "%" PRIu64 : "%12" PRIu64;
- return scnprintf(hpp->buf, hpp->size, fmt, he->period);
+ return scnprintf(hpp->buf, hpp->size, fmt, he->stat.period);
}
static int hpp__header_delta(struct perf_hpp *hpp)
@@ -220,11 +220,11 @@ static int hpp__entry_delta(struct perf_hpp *hpp, struct hist_entry *he)
old_total = pair_hists->stats.total_period;
if (old_total > 0 && he->pair)
- old_percent = 100.0 * he->pair->period / old_total;
+ old_percent = 100.0 * he->pair->stat.period / old_total;
new_total = hpp->total_period;
if (new_total > 0)
- new_percent = 100.0 * he->period / new_total;
+ new_percent = 100.0 * he->stat.period / new_total;
diff = new_percent - old_percent;
if (fabs(diff) >= 0.01)
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 882461a42830..4382a1995cda 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -271,7 +271,7 @@ static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
{
switch (callchain_param.mode) {
case CHAIN_GRAPH_REL:
- return callchain__fprintf_graph(fp, &he->sorted_chain, he->period,
+ return callchain__fprintf_graph(fp, &he->sorted_chain, he->stat.period,
left_margin);
break;
case CHAIN_GRAPH_ABS:
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 236bc9d98ff2..ab3d11491991 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -135,16 +135,16 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
{
switch (cpumode) {
case PERF_RECORD_MISC_KERNEL:
- he->period_sys += period;
+ he->stat.period_sys += period;
break;
case PERF_RECORD_MISC_USER:
- he->period_us += period;
+ he->stat.period_us += period;
break;
case PERF_RECORD_MISC_GUEST_KERNEL:
- he->period_guest_sys += period;
+ he->stat.period_guest_sys += period;
break;
case PERF_RECORD_MISC_GUEST_USER:
- he->period_guest_us += period;
+ he->stat.period_guest_us += period;
break;
default:
break;
@@ -153,13 +153,13 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
static void hist_entry__decay(struct hist_entry *he)
{
- he->period = (he->period * 7) / 8;
- he->nr_events = (he->nr_events * 7) / 8;
+ he->stat.period = (he->stat.period * 7) / 8;
+ he->stat.nr_events = (he->stat.nr_events * 7) / 8;
}
static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
{
- u64 prev_period = he->period;
+ u64 prev_period = he->stat.period;
if (prev_period == 0)
return true;
@@ -167,9 +167,9 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
hist_entry__decay(he);
if (!he->filtered)
- hists->stats.total_period -= prev_period - he->period;
+ hists->stats.total_period -= prev_period - he->stat.period;
- return he->period == 0;
+ return he->stat.period == 0;
}
static void __hists__decay_entries(struct hists *hists, bool zap_user,
@@ -223,7 +223,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
if (he != NULL) {
*he = *template;
- he->nr_events = 1;
+ he->stat.nr_events = 1;
if (he->ms.map)
he->ms.map->referenced = true;
if (symbol_conf.use_callchain)
@@ -238,7 +238,7 @@ static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h)
if (!h->filtered) {
hists__calc_col_len(hists, h);
++hists->nr_entries;
- hists->stats.total_period += h->period;
+ hists->stats.total_period += h->stat.period;
}
}
@@ -270,8 +270,8 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
cmp = hist_entry__cmp(entry, he);
if (!cmp) {
- he->period += period;
- ++he->nr_events;
+ he->stat.period += period;
+ ++he->stat.nr_events;
/* If the map of an existing hist_entry has
* become out-of-date due to an exec() or
@@ -321,7 +321,9 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
.cpu = al->cpu,
.ip = bi->to.addr,
.level = al->level,
- .period = period,
+ .stat = {
+ .period = period,
+ },
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.branch_info = bi,
@@ -343,7 +345,9 @@ struct hist_entry *__hists__add_entry(struct hists *self,
.cpu = al->cpu,
.ip = al->addr,
.level = al->level,
- .period = period,
+ .stat = {
+ .period = period,
+ },
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
};
@@ -410,12 +414,12 @@ static bool hists__collapse_insert_entry(struct hists *hists __maybe_unused,
cmp = hist_entry__collapse(iter, he);
if (!cmp) {
- 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;
+ 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;
if (symbol_conf.use_callchain) {
callchain_cursor_reset(&callchain_cursor);
@@ -518,7 +522,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
parent = *p;
iter = rb_entry(parent, struct hist_entry, rb_node);
- if (he->period > iter->period)
+ if (he->stat.period > iter->stat.period)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
@@ -579,8 +583,8 @@ static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h
if (h->ms.unfolded)
hists->nr_entries += h->nr_rows;
h->row_offset = 0;
- hists->stats.total_period += h->period;
- hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->nr_events;
+ hists->stats.total_period += h->stat.period;
+ hists->stats.nr_events[PERF_RECORD_SAMPLE] += h->stat.nr_events;
hists__calc_col_len(hists, h);
}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 12d634792de5..30f2ae5be146 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -43,6 +43,15 @@ extern struct sort_entry sort_sym_from;
extern struct sort_entry sort_sym_to;
extern enum sort_type sort__first_dimension;
+struct he_stat {
+ u64 period;
+ u64 period_sys;
+ u64 period_us;
+ u64 period_guest_sys;
+ u64 period_guest_us;
+ u32 nr_events;
+};
+
/**
* struct hist_entry - histogram entry
*
@@ -52,16 +61,11 @@ extern enum sort_type sort__first_dimension;
struct hist_entry {
struct rb_node rb_node_in;
struct rb_node rb_node;
- u64 period;
- u64 period_sys;
- u64 period_us;
- u64 period_guest_sys;
- u64 period_guest_us;
+ struct he_stat stat;
struct map_symbol ms;
struct thread *thread;
u64 ip;
s32 cpu;
- u32 nr_events;
/* XXX These two should move to some tree widget lib */
u16 row_offset;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/16] perf hists: Move he->stat.nr_events initialization to a template
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
2012-09-26 7:47 ` [PATCH 01/16] perf hists: Add missing period_* fields when collapsing a hist entry Namhyung Kim
2012-09-26 7:47 ` [PATCH 02/16] perf hists: Introduce struct he_stat Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 04/16] perf hists: Add more helpers for hist entry stat Namhyung Kim
` (12 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Arun Sharma,
Frederic Weisbecker
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/16] perf hists: Add more helpers for hist entry stat
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (2 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 03/16] perf hists: Move he->stat.nr_events initialization to a template Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 05/16] perf tools: Keep group information Namhyung Kim
` (11 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Arun Sharma,
Frederic Weisbecker
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 05/16] perf tools: Keep group information
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (3 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 04/16] perf hists: Add more helpers for hist entry stat Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-27 17:03 ` Jiri Olsa
2012-09-26 7:47 ` [PATCH 06/16] perf evlist: Add perf_evlist__recalc_nr_groups Namhyung Kim
` (10 subsequent siblings)
15 siblings, 1 reply; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 05/16] perf tools: Keep group information
2012-09-26 7:47 ` [PATCH 05/16] perf tools: Keep group information Namhyung Kim
@ 2012-09-27 17:03 ` Jiri Olsa
2012-09-28 4:49 ` Namhyung Kim
0 siblings, 1 reply; 20+ messages in thread
From: Jiri Olsa @ 2012-09-27 17:03 UTC (permalink / raw)
To: Namhyung Kim
Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras,
Ingo Molnar, LKML, Stephane Eranian, David Ahern, Namhyung Kim
SNIP
> 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++;
jirka
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 05/16] perf tools: Keep group information
2012-09-27 17:03 ` Jiri Olsa
@ 2012-09-28 4:49 ` Namhyung Kim
0 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-28 4:49 UTC (permalink / raw)
To: Jiri Olsa
Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras,
Ingo Molnar, LKML, Stephane Eranian, David Ahern, 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
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 06/16] perf evlist: Add perf_evlist__recalc_nr_groups
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (4 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 05/16] perf tools: Keep group information Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 07/16] perf header: Add HEADER_GROUP_DESC feature Namhyung Kim
` (9 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/16] perf header: Add HEADER_GROUP_DESC feature
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (5 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 06/16] perf evlist: Add perf_evlist__recalc_nr_groups Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 08/16] perf hists: Collapse group hist_entries to a leader Namhyung Kim
` (8 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
Save group relationship information so that it can be restored when
perf report is running.
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
---
tools/perf/builtin-record.c | 3 +
| 149 ++++++++++++++++++++++++++++++++++++++++++++
| 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()
*/
--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 {
+ * char name[];
+ * 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;
+
+ if (ph->needs_swap) {
+ desc[i].leader_idx = bswap_32(desc[i].leader_idx);
+ desc[i].nr_members = bswap_32(desc[i].nr_members);
+ }
+ }
+
+ /*
+ * Rebuild group relationship based on the group_desc
+ */
+ session = container_of(ph, struct perf_session, header);
+ session->evlist->nr_groups = nr_groups;
+
+ i = nr = 0;
+ list_for_each_entry(evsel, &session->evlist->entries, node) {
+ if (evsel->idx == (int) desc[i].leader_idx) {
+ evsel->leader = NULL;
+ /* {anon_group} is a dummy name */
+ if (strcmp(desc[i].name, "{anon_group}"))
+ evsel->group_name = desc[i].name;
+ evsel->nr_members = desc[i].nr_members;
+
+ BUG_ON(i >= nr_groups);
+ BUG_ON(nr > 0);
+
+ leader = evsel;
+ nr = evsel->nr_members;
+ i++;
+ } else if (nr) {
+ /* This is a group member */
+ evsel->leader = leader;
+ /* group_idx starts from 0 */
+ evsel->group_idx = leader->nr_members - nr;
+ nr--;
+ }
+ }
+
+ BUG_ON(i != nr_groups);
+ BUG_ON(nr != 0);
+
+out_free:
+ while ((int) --i >= 0)
+ free(desc[i].name);
+ free(desc);
+
+ return ret;
+}
+
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);
@@ -1983,6 +2131,7 @@ static const struct feature_ops feat_ops[HEADER_LAST_FEATURE] = {
FEAT_OPF(HEADER_NUMA_TOPOLOGY, numa_topology),
FEAT_OPA(HEADER_BRANCH_STACK, branch_stack),
FEAT_OPP(HEADER_PMU_MAPPINGS, pmu_mappings),
+ FEAT_OPP(HEADER_GROUP_DESC, group_desc),
};
struct header_print_data {
--git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 99bdd3abce59..f143aa7153a2 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -29,6 +29,7 @@ enum {
HEADER_NUMA_TOPOLOGY,
HEADER_BRANCH_STACK,
HEADER_PMU_MAPPINGS,
+ HEADER_GROUP_DESC,
HEADER_LAST_FEATURE,
HEADER_FEAT_BITS = 256,
};
@@ -79,6 +80,7 @@ struct perf_session_env {
char *numa_nodes;
int nr_pmu_mappings;
char *pmu_mappings;
+ int nr_groups;
};
struct perf_header {
--
1.7.11.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/16] perf hists: Collapse group hist_entries to a leader
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (6 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 07/16] perf header: Add HEADER_GROUP_DESC feature Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 09/16] perf hists: Maintain total periods of group members in the leader Namhyung Kim
` (7 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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 __hists__collapse_resort(struct hists *hists, bool threaded)
return;
root = hists__get_rotate_entries_in(hists);
+ dest = &hists->entries_collapsed;
next = rb_first(root);
+ if (symbol_conf.event_group) {
+ /*
+ * Collapse hist entries to the leader's tree.
+ * If evsel->leader == NULL, it's the leader.
+ */
+ struct perf_evsel *leader = hists_2_evsel(hists)->leader;
+
+ if (leader)
+ dest = &leader->hists.entries_collapsed;
+ }
+
while (next) {
n = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&n->rb_node_in);
rb_erase(&n->rb_node_in, root);
- if (hists__collapse_insert_entry(hists, &hists->entries_collapsed, n)) {
+ if (hists__collapse_insert_entry(hists, dest, n)) {
/*
* If it wasn't combined with one of the entries already
* collapsed, we need to apply the filters that may have
@@ -518,13 +573,38 @@ void hists__collapse_resort_threaded(struct hists *hists)
* reverse the map, sort on period.
*/
-static void __hists__insert_output_entry(struct rb_root *entries,
+static int __hists__output_cmp(struct hist_entry *left,
+ struct hist_entry *right,
+ int nr_group_stats)
+{
+ if (left->stat.period > right->stat.period)
+ return 1;
+ if (left->stat.period < right->stat.period)
+ return -1;
+
+ if (symbol_conf.event_group) {
+ int i;
+
+ for (i = 0; i < nr_group_stats; i++) {
+ if (left->group_stats[i].period >
+ right->group_stats[i].period)
+ return 1;
+ if (left->group_stats[i].period <
+ right->group_stats[i].period)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void __hists__insert_output_entry(struct hists *hists,
struct hist_entry *he,
u64 min_callchain_hits)
{
- struct rb_node **p = &entries->rb_node;
+ struct rb_node **p = &hists->entries.rb_node;
struct rb_node *parent = NULL;
struct hist_entry *iter;
+ struct perf_evsel *evsel = hists_2_evsel(hists);
if (symbol_conf.use_callchain)
callchain_param.sort(&he->sorted_chain, he->callchain,
@@ -534,14 +614,14 @@ static void __hists__insert_output_entry(struct rb_root *entries,
parent = *p;
iter = rb_entry(parent, struct hist_entry, rb_node);
- if (he->stat.period > iter->stat.period)
+ if (__hists__output_cmp(he, iter, evsel->nr_members) > 0)
p = &(*p)->rb_left;
else
p = &(*p)->rb_right;
}
rb_link_node(&he->rb_node, parent, p);
- rb_insert_color(&he->rb_node, entries);
+ rb_insert_color(&he->rb_node, &hists->entries);
}
static void __hists__output_resort(struct hists *hists, bool threaded)
@@ -551,6 +631,16 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
struct hist_entry *n;
u64 min_callchain_hits;
+ if (symbol_conf.event_group) {
+ struct perf_evsel *evsel = hists_2_evsel(hists);
+
+ /*
+ * We've collapsed all member entries to the leader.
+ */
+ if (!perf_evsel__is_group_leader(evsel))
+ return;
+ }
+
min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
if (sort__need_collapse || threaded)
@@ -569,7 +659,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
n = rb_entry(next, struct hist_entry, rb_node_in);
next = rb_next(&n->rb_node_in);
- __hists__insert_output_entry(&hists->entries, n, min_callchain_hits);
+ __hists__insert_output_entry(hists, n, min_callchain_hits);
hists__inc_nr_entries(hists, n);
}
}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 30f2ae5be146..1780bfc348d2 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -62,6 +62,7 @@ struct hist_entry {
struct rb_node rb_node_in;
struct rb_node rb_node;
struct he_stat stat;
+ struct he_stat *group_stats;
struct map_symbol ms;
struct thread *thread;
u64 ip;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index e2e8c697cffe..bb2ef6920ccf 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -11,6 +11,7 @@
#include <inttypes.h>
#include "build-id.h"
#include "util.h"
+#include "sort.h"
#include "debug.h"
#include "symbol.h"
#include "strlist.h"
@@ -2033,6 +2034,9 @@ int symbol__init(void)
symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
+ if (symbol_conf.event_group)
+ sort__need_collapse = 1;
+
symbol_conf.initialized = true;
return 0;
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index b441b07172b7..5f2304acea95 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -97,7 +97,8 @@ struct symbol_conf {
initialized,
kptr_restrict,
annotate_asm_raw,
- annotate_src;
+ annotate_src,
+ event_group;
const char *vmlinux_name,
*kallsyms_name,
*source_prefix,
--
1.7.11.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/16] perf hists: Maintain total periods of group members in the leader
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (7 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 08/16] perf hists: Collapse group hist_entries to a leader Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 10/16] perf report: Make another loop for output resorting Namhyung Kim
` (6 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@lge.com>
Like group_stats in hist_entry, total periods information also need to
be known to the leader.
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 10/16] perf report: Make another loop for output resorting
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (8 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 09/16] perf hists: Maintain total periods of group members in the leader Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 11/16] perf ui/hist: Add support for event group view Namhyung Kim
` (5 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 11/16] perf ui/hist: Add support for event group view
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (9 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 10/16] perf report: Make another loop for output resorting Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 12/16] perf ui/browser: " Namhyung Kim
` (4 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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,
.total_period = total_period,
+ .hists = hists,
.displacement = displacement,
.ptr = pair_hists,
};
@@ -354,6 +355,7 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
struct perf_hpp dummy_hpp = {
.buf = bf,
.size = sizeof(bf),
+ .hists = hists,
.ptr = pair,
};
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index e13db91bc246..a7ccaad65f21 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -120,6 +120,7 @@ struct perf_hpp {
char *buf;
size_t size;
u64 total_period;
+ struct hists* hists;
const char *sep;
long displacement;
void *ptr;
--
1.7.11.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 12/16] perf ui/browser: Add support for event group view
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (10 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 11/16] perf ui/hist: Add support for event group view Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 13/16] perf ui/gtk: " Namhyung Kim
` (3 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 13/16] perf ui/gtk: Add support for event group view
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (11 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 12/16] perf ui/browser: " Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 14/16] perf report: Bypass non-leader events when event group is enabled Namhyung Kim
` (2 subsequent siblings)
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Pekka Enberg
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 14/16] perf report: Bypass non-leader events when event group is enabled
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (12 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 13/16] perf ui/gtk: " Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 15/16] perf report: Show group description " Namhyung Kim
2012-09-26 7:47 ` [PATCH 16/16] perf report: Add --group option Namhyung Kim
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Pekka Enberg
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@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 &&
+ !perf_evsel__is_group_leader(pos))
+ continue;
+
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
--
1.7.11.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 15/16] perf report: Show group description when event group is enabled
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (13 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 14/16] perf report: Bypass non-leader events when event group is enabled Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
2012-09-26 7:47 ` [PATCH 16/16] perf report: Add --group option Namhyung Kim
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim, Pekka Enberg
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Pekka Enberg <penberg@kernel.org>
Signed-off-by: Namhyung Kim <namhyung@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..50fa1b4c0d8b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -397,6 +397,31 @@ const char *perf_evsel__name(struct perf_evsel *evsel)
return evsel->name ?: "unknown";
}
+const char *perf_evsel__group_name(struct perf_evsel *evsel)
+{
+ return evsel->group_name ?: "anon group";
+}
+
+int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
+{
+ int ret;
+ struct perf_evsel *pos;
+ const char *group_name = perf_evsel__group_name(evsel);
+
+ ret = scnprintf(buf, size, "%s", group_name);
+
+ ret += scnprintf(buf + ret, size - ret, " { %s",
+ perf_evsel__name(evsel));
+
+ for_each_group_member(pos, evsel)
+ ret += scnprintf(buf + ret, size - ret, ", %s",
+ perf_evsel__name(pos));
+
+ ret += scnprintf(buf + ret, size - ret, " }");
+
+ return ret;
+}
+
void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
struct perf_evsel *first)
{
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 95f0bf17e79c..1fa79a0d9eb2 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -110,6 +110,8 @@ extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX];
int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result,
char *bf, size_t size);
const char *perf_evsel__name(struct perf_evsel *evsel);
+const char *perf_evsel__group_name(struct perf_evsel *evsel);
+int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
@@ -226,4 +228,10 @@ static inline struct perf_evsel *hists_2_evsel(struct hists *hists)
{
return container_of(hists, struct perf_evsel, hists);
}
+
+#define for_each_group_member(_evsel, _leader) \
+for ((_evsel) = list_entry((_leader)->node.next, struct perf_evsel, node); \
+ (_evsel) && (_evsel)->leader == (_leader); \
+ (_evsel) = list_entry((_evsel)->node.next, struct perf_evsel, node))
+
#endif /* __PERF_EVSEL_H */
--
1.7.11.4
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 16/16] perf report: Add --group option
2012-09-26 7:47 [PATCH 00/16] perf report: Add suppport for event group view (v2) Namhyung Kim
` (14 preceding siblings ...)
2012-09-26 7:47 ` [PATCH 15/16] perf report: Show group description " Namhyung Kim
@ 2012-09-26 7:47 ` Namhyung Kim
15 siblings, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2012-09-26 7:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Jiri Olsa,
Stephane Eranian, David Ahern, Namhyung Kim
From: Namhyung Kim <namhyung.kim@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 <jolsa@redhat.com>
Cc: Stephane Eranian <eranian@google.com>
Signed-off-by: Namhyung Kim <namhyung@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
^ permalink raw reply related [flat|nested] 20+ messages in thread