[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210622153918.688500-8-jolsa@kernel.org>
Date: Tue, 22 Jun 2021 17:39:15 +0200
From: Jiri Olsa <jolsa@...hat.com>
To: Arnaldo Carvalho de Melo <acme@...nel.org>
Cc: lkml <linux-kernel@...r.kernel.org>,
Peter Zijlstra <a.p.zijlstra@...llo.nl>,
Ingo Molnar <mingo@...nel.org>,
Mark Rutland <mark.rutland@....com>,
Namhyung Kim <namhyung@...nel.org>,
Alexander Shishkin <alexander.shishkin@...ux.intel.com>,
Michael Petlan <mpetlan@...hat.com>,
Ian Rogers <irogers@...gle.com>
Subject: [PATCH 07/10] perf record: Add support to read build id fails
Adding support to read build id fails and lost events count
and display it at the end of the record session, when recording
with --buildid-mmap.
# perf record ...
...
[ perf record: Woken up 1 times to write data ]
[ perf record: Failed to parse 4 build ids]
[ perf record: Captured and wrote 0.008 MB perf.data ]
Signed-off-by: Jiri Olsa <jolsa@...nel.org>
---
tools/lib/perf/evsel.c | 6 ++
tools/lib/perf/include/perf/evsel.h | 11 ++-
tools/perf/builtin-record.c | 90 +++++++++++++++++++++++
tools/perf/util/evsel.c | 12 +++
tools/perf/util/perf_event_attr_fprintf.c | 3 +-
5 files changed, 120 insertions(+), 2 deletions(-)
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 04e8386b3ed4..9d7b2fd49b90 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -248,6 +248,12 @@ int perf_evsel__read_size(struct perf_evsel *evsel)
if (read_format & PERF_FORMAT_ID)
entry += sizeof(u64);
+ if (read_format & PERF_FORMAT_BUILD_ID_FAULTS)
+ entry += sizeof(u64);
+
+ if (read_format & PERF_FORMAT_LOST)
+ entry += sizeof(u64);
+
if (read_format & PERF_FORMAT_GROUP) {
nr = evsel->nr_members;
size += sizeof(u64);
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index 60eae25076d3..294fc5929e1d 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -12,12 +12,21 @@ struct perf_thread_map;
struct perf_counts_values {
union {
+ /* Struct for specific perf interfaces. */
struct {
uint64_t val;
uint64_t ena;
uint64_t run;
};
- uint64_t values[3];
+ /*
+ * Values to store all non-group data:
+ * PERF_FORMAT_TOTAL_TIME_ENABLED
+ * PERF_FORMAT_TOTAL_TIME_RUNNING
+ * PERF_FORMAT_ID
+ * PERF_FORMAT_BUILD_ID_FAULTS
+ * PERF_FORMAT_LOST
+ */
+ uint64_t values[6];
};
};
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index bc3dd379eb67..bf3958ce18e3 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -49,6 +49,8 @@
#include "util/clockid.h"
#include "util/pmu-hybrid.h"
#include "util/evlist-hybrid.h"
+#include "util/counts.h"
+#include "util/stat.h"
#include "asm/bug.h"
#include "perf.h"
@@ -1226,6 +1228,90 @@ static void record__init_features(struct record *rec)
perf_header__clear_feat(&session->header, HEADER_STAT);
}
+struct session_stats {
+ u64 build_id_faults;
+ u64 lost;
+};
+
+static int
+evsel__read_session_stats(struct evsel *evsel, struct session_stats *st,
+ int nr_cpus, int nr_threads)
+{
+ u64 read_format = evsel->core.attr.read_format;
+ int idx = 1, idx_faults = 0, idx_lost = 0;
+ int cpu, thread;
+
+ if (read_format & PERF_FORMAT_GROUP)
+ return 0;
+
+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+ idx++;
+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+ idx++;
+ if (read_format & PERF_FORMAT_ID)
+ idx++;
+ if (read_format & PERF_FORMAT_BUILD_ID_FAULTS)
+ idx_faults = idx++;
+ if (read_format & PERF_FORMAT_LOST)
+ idx_lost = idx;
+
+ if (!idx_faults && !idx_lost)
+ return 0;
+
+ for (cpu = 0; cpu < nr_cpus; cpu++) {
+ for (thread = 0; thread < nr_threads; thread++) {
+ struct perf_counts_values count;
+
+ if (perf_evsel__read(&evsel->core, cpu, thread, &count))
+ return -1;
+
+ if (idx_faults)
+ st->build_id_faults += count.values[idx_faults];
+ if (idx_lost)
+ st->lost += count.values[idx_lost];
+ }
+ }
+
+ return 0;
+}
+
+static int
+evlist__read_session_stats(struct evlist *evlist, struct session_stats *st)
+{
+ int nr_threads = perf_thread_map__nr(evlist->core.threads);
+ int nr_cpus = perf_cpu_map__nr(evlist->core.cpus);
+ struct evsel *evsel;
+
+ memset(st, 0, sizeof(*st));
+
+ evlist__for_each_entry(evlist, evsel) {
+ if (evsel__read_session_stats(evsel, st, nr_cpus, nr_threads)) {
+ pr_err("FAILED to read event stats\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void read_session_stats(struct record *rec)
+{
+ struct session_stats st;
+
+ if (evlist__read_session_stats(rec->evlist, &st))
+ return;
+
+ if (st.build_id_faults) {
+ fprintf(stderr, "[ perf record: Failed to parse %lu build ids]\n",
+ st.build_id_faults);
+ }
+
+ if (st.lost) {
+ fprintf(stderr, "[ perf record: Lost %lu chunks]\n",
+ st.lost);
+ }
+}
+
static void
record__finish_output(struct record *rec)
{
@@ -1244,6 +1330,10 @@ record__finish_output(struct record *rec)
if (rec->buildid_all)
dsos__hit_all(rec->session);
}
+
+ if (rec->buildid_mmap)
+ read_session_stats(rec);
+
perf_session__write_header(rec->session, rec->evlist, fd, true);
return;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f81ac6962aec..f862cae8874f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1239,6 +1239,18 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts,
PERF_FORMAT_TOTAL_TIME_RUNNING;
}
+ /*
+ * We skip post processing for build_id, so we need
+ * to read stats via read syscall:
+ * - faults for mmap events
+ * - lost for each event
+ */
+ if (attr->build_id)
+ attr->read_format |= PERF_FORMAT_BUILD_ID_FAULTS;
+
+ if (opts->build_id)
+ attr->read_format |= PERF_FORMAT_LOST;
+
/*
* XXX see the function comment above
*
diff --git a/tools/perf/util/perf_event_attr_fprintf.c b/tools/perf/util/perf_event_attr_fprintf.c
index 30481825515b..946073024d7a 100644
--- a/tools/perf/util/perf_event_attr_fprintf.c
+++ b/tools/perf/util/perf_event_attr_fprintf.c
@@ -64,7 +64,8 @@ static void __p_read_format(char *buf, size_t size, u64 value)
#define bit_name(n) { PERF_FORMAT_##n, #n }
struct bit_names bits[] = {
bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING),
- bit_name(ID), bit_name(GROUP),
+ bit_name(ID), bit_name(GROUP), bit_name(BUILD_ID_FAULTS),
+ bit_name(LOST),
{ .name = NULL, }
};
#undef bit_name
--
2.31.1
Powered by blists - more mailing lists