From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753598AbdHPCWK (ORCPT ); Tue, 15 Aug 2017 22:22:10 -0400 Received: from mga01.intel.com ([192.55.52.88]:49608 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753574AbdHPCWH (ORCPT ); Tue, 15 Aug 2017 22:22:07 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,380,1498546800"; d="scan'208";a="119442501" From: Jin Yao To: acme@kernel.org, jolsa@kernel.org, peterz@infradead.org, mingo@redhat.com, alexander.shishkin@linux.intel.com Cc: Linux-kernel@vger.kernel.org, ak@linux.intel.com, kan.liang@intel.com, yao.jin@intel.com, Jin Yao Subject: [PATCH v1 1/4] perf annotate: create a new hists to manage multiple events samples Date: Wed, 16 Aug 2017 18:18:33 +0800 Message-Id: <1502878716-30817-2-git-send-email-yao.jin@linux.intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502878716-30817-1-git-send-email-yao.jin@linux.intel.com> References: <1502878716-30817-1-git-send-email-yao.jin@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org An issue is found during using perf annotate. perf record -e cycles,branches ... perf annotate main --stdio The result only shows cycles. It should show both cycles and branches on the left side. It works with "--group", but need this to work even without groups. In current design, the hists is per event. So we need a new hists to manage the samples for multiple events and use a new hist_event data structure to save the map/symbol information for per event. Signed-off-by: Jin Yao --- tools/perf/builtin-annotate.c | 60 +++++++++++++++++++++++++++++++------------ tools/perf/util/annotate.c | 8 ++++++ tools/perf/util/annotate.h | 4 +++ tools/perf/util/sort.c | 21 +++++++++++++++ tools/perf/util/sort.h | 13 ++++++++++ 5 files changed, 89 insertions(+), 17 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 658c920..833866c 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -45,6 +45,7 @@ struct perf_annotate { bool skip_missing; const char *sym_hist_filter; const char *cpu_list; + struct hists events_hists; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); }; @@ -153,6 +154,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, struct hists *hists = evsel__hists(evsel); struct hist_entry *he; int ret; + struct hist_event *hevt; if (ann->sym_hist_filter != NULL && (al->sym == NULL || @@ -177,12 +179,30 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel, */ process_branch_stack(sample->branch_stack, al, sample); - he = hists__add_entry(hists, al, NULL, NULL, NULL, sample, true); - if (he == NULL) - return -ENOMEM; + if (symbol_conf.nr_events == 1) { + he = hists__add_entry(hists, al, NULL, NULL, NULL, + sample, true); + if (he == NULL) + return -ENOMEM; + + ret = hist_entry__inc_addr_samples(he, sample, evsel->idx, + al->addr); + hists__inc_nr_samples(hists, true); + } else { + he = hists__add_entry(&ann->events_hists, al, NULL, + NULL, NULL, sample, true); + if (he == NULL) + return -ENOMEM; + + hevt = hist_entry__event_add(he, evsel); + if (hevt == NULL) + return -ENOMEM; + + ret = hist_event__inc_addr_samples(hevt, sample, hevt->idx, + al->addr); + hists__inc_nr_samples(&ann->events_hists, true); + } - ret = hist_entry__inc_addr_samples(he, sample, evsel->idx, al->addr); - hists__inc_nr_samples(hists, true); return ret; } @@ -304,7 +324,8 @@ static int __cmd_annotate(struct perf_annotate *ann) int ret; struct perf_session *session = ann->session; struct perf_evsel *pos; - u64 total_nr_samples; + u64 total_nr_samples = 0; + struct hists *hists; if (ann->cpu_list) { ret = perf_session__cpu_bitmap(session, ann->cpu_list, @@ -335,23 +356,26 @@ static int __cmd_annotate(struct perf_annotate *ann) if (verbose > 2) perf_session__fprintf_dsos(session, stdout); - total_nr_samples = 0; - evlist__for_each_entry(session->evlist, pos) { - struct hists *hists = evsel__hists(pos); - u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; + if (symbol_conf.nr_events > 1) { + hists = &ann->events_hists; + total_nr_samples += + hists->stats.nr_events[PERF_RECORD_SAMPLE]; + + hists__collapse_resort(hists, NULL); + hists__output_resort(hists, NULL); + hists__find_annotations(hists, NULL, ann); + } else { + evlist__for_each_entry(session->evlist, pos) { + hists = evsel__hists(pos); + total_nr_samples += + hists->stats.nr_events[PERF_RECORD_SAMPLE]; - if (nr_samples > 0) { - total_nr_samples += nr_samples; hists__collapse_resort(hists, NULL); /* Don't sort callchain */ perf_evsel__reset_sample_bit(pos, CALLCHAIN); perf_evsel__output_resort(pos, NULL); - - if (symbol_conf.event_group && - !perf_evsel__is_group_leader(pos)) - continue; - hists__find_annotations(hists, pos, ann); + break; } } @@ -486,6 +510,8 @@ int cmd_annotate(int argc, const char **argv) if (ret < 0) goto out_delete; + __hists__init(&annotate.events_hists, &perf_hpp_list); + if (setup_sorting(NULL) < 0) usage_with_options(annotate_usage, options); diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 2dab0e5..16ec881 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -828,6 +828,14 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *samp return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip, sample); } +int hist_event__inc_addr_samples(struct hist_event *hevt, + struct perf_sample *sample, + int idx, u64 ip) +{ + return symbol__inc_addr_samples(hevt->ms.sym, hevt->ms.map, + idx, ip, sample); +} + static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map *map) { dl->ins.ops = ins__find(arch, dl->ins.name); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 9ce575c..0d44cfe 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -165,6 +165,10 @@ int addr_map_symbol__account_cycles(struct addr_map_symbol *ams, int hist_entry__inc_addr_samples(struct hist_entry *he, struct perf_sample *sample, int evidx, u64 addr); +int hist_event__inc_addr_samples(struct hist_event *hevt, + struct perf_sample *sample, + int idx, u64 addr); + int symbol__alloc_hist(struct symbol *sym); void symbol__annotate_zero_histograms(struct symbol *sym); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 12359bd..1500a8e 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1490,6 +1490,27 @@ struct sort_entry sort_sym_size = { .se_width_idx = HISTC_SYM_SIZE, }; +struct hist_event *hist_entry__event_add(struct hist_entry *he, + struct perf_evsel *evsel) +{ + int i; + + for (i = 0; i < he->event_nr; i++) { + if (he->events[i].evsel == evsel) + return &he->events[i]; + } + + if (i < HIST_ENTRY_EVENTS) { + memset(&he->events[i], 0, sizeof(struct hist_event)); + memcpy(&he->events[i].ms, &he->ms, sizeof(struct map_symbol)); + he->events[i].evsel = evsel; + he->events[i].idx = i; + he->event_nr++; + return &he->events[i]; + } + + return NULL; +} struct sort_dimension { const char *name; diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index b7c7559..446a2a3 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -79,6 +79,14 @@ struct hist_entry_ops { void (*free)(void *ptr); }; +#define HIST_ENTRY_EVENTS 8 + +struct hist_event { + struct map_symbol ms; + struct perf_evsel *evsel; + int idx; +}; + /** * struct hist_entry - histogram entry * @@ -95,6 +103,8 @@ struct hist_entry { struct he_stat stat; struct he_stat *stat_acc; struct map_symbol ms; + struct hist_event events[HIST_ENTRY_EVENTS]; + int event_nr; struct thread *thread; struct comm *comm; struct namespace_id cgroup_id; @@ -291,4 +301,7 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right); int64_t sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right); char *hist_entry__get_srcline(struct hist_entry *he); +struct hist_event *hist_entry__event_add(struct hist_entry *he, + struct perf_evsel *evsel); + #endif /* __PERF_SORT_H */ -- 2.7.4