Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753924AbbHRQne (ORCPT ); Tue, 18 Aug 2015 12:43:34 -0400 Received: from mga11.intel.com ([192.55.52.93]:1540 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753719AbbHRQlX (ORCPT ); Tue, 18 Aug 2015 12:41:23 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,702,1432623600"; d="scan'208";a="786447419" From: kan.liang@intel.com To: acme@kernel.org Cc: a.p.zijlstra@chello.nl, mingo@redhat.com, jolsa@kernel.org, namhyung@kernel.org, ak@linux.intel.com, eranian@google.com, linux-kernel@vger.kernel.org, Kan Liang Subject: [PATCH RFC 07/10] perf,tools: record counter statistics during sampling Date: Tue, 18 Aug 2015 05:25:43 -0400 Message-Id: <1439889946-28986-8-git-send-email-kan.liang@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1439889946-28986-1-git-send-email-kan.liang@intel.com> References: <1439889946-28986-1-git-send-email-kan.liang@intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4115 Lines: 149 From: Kan Liang Reading at the start and the end of sampling, and save the counter statistics value to PERF_RECORD_STAT_READ. The absolate value from counter will be stored in prev_raw_counts. The detla value will be caculated and saved in PERF_RECORD_STAT_READ. Signed-off-by: Kan Liang --- tools/perf/builtin-record.c | 76 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 5b09318..0e5e4c0 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -29,6 +29,7 @@ #include "util/data.h" #include "util/auxtrace.h" #include "util/parse-branch-options.h" +#include "util/stat.h" #include #include @@ -266,6 +267,30 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) #endif +static void +free_prev_stat_counts(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + evlist__for_each(evlist, evsel) { + if (evsel->prev_raw_counts != NULL) + perf_evsel__free_prev_raw_counts(evsel); + } +} + +static int perf_evlist__alloc_prev_stat(struct perf_evlist *evlist) +{ + struct perf_evsel *evsel; + + evlist__for_each(evlist, evsel) { + if (evsel->stat_read && + (perf_evsel__alloc_prev_raw_counts(evsel, cpu_map__nr(evsel->cpus), 1) < 0)) + return -ENOMEM; + } + + return 0; +} + static int record__open(struct record *rec) { char msg[512]; @@ -352,6 +377,9 @@ try_again: goto out; } + if (perf_evlist__alloc_prev_stat(evlist)) + goto out; + session->evlist = evlist; perf_session__set_id_hdr_size(session); out: @@ -427,6 +455,50 @@ static struct perf_event_header finished_round_event = { .type = PERF_RECORD_FINISHED_ROUND, }; +static void process_stat_read_event(struct record *rec, int id, + struct perf_evsel *pos, + struct perf_counts_values *count, + u32 pos_id) +{ + union perf_event ev; + struct perf_counts_values tmp; + + memset(&ev, 0, sizeof(ev)); + ev.stat_read.header.type = PERF_RECORD_STAT_READ; + ev.stat_read.header.size = sizeof(ev.stat_read); + ev.stat_read.cpu = pos->cpus->map[id]; + ev.stat_read.pos_id = pos_id; + + BUG_ON(pos->prev_raw_counts == NULL); + tmp.val = perf_counts(pos->prev_raw_counts, id, 0)->val; + if (tmp.val) + ev.stat_read.value = count->val - tmp.val; + perf_counts(pos->prev_raw_counts, id, 0)->val = count->val; + + ev.stat_read.time = rdclock(); + + record__write(rec, &ev, sizeof(ev.stat_read)); +} + +static void perf_read_counter(struct record *rec) +{ + struct perf_evlist *evlist = rec->evlist; + struct perf_counts_values count; + struct perf_evsel *pos; + int cpu; + u32 pos_id = 0; + + evlist__for_each(evlist, pos) { + for (cpu = 0; cpu < cpu_map__nr(pos->cpus); cpu++) { + if (pos->stat_read && + !perf_evsel__read(pos, cpu, 0, &count)) { + process_stat_read_event(rec, cpu, pos, &count, pos_id); + } + } + pos_id++; + } +} + static int record__mmap_read_all(struct record *rec) { u64 bytes_written = rec->bytes_written; @@ -664,6 +736,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) perf_evlist__enable(rec->evlist); } + perf_read_counter(rec); auxtrace_snapshot_enabled = 1; for (;;) { int hits = rec->samples; @@ -708,6 +781,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) */ if (done && !disabled && !target__none(&opts->target)) { auxtrace_snapshot_enabled = 0; + perf_read_counter(rec); perf_evlist__disable(rec->evlist); disabled = true; } @@ -776,7 +850,7 @@ out_child: perf_data_file__size(file) / 1024.0 / 1024.0, file->path, samples); } - + free_prev_stat_counts(rec->evlist); out_delete_session: perf_session__delete(session); return status; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/