[PATCH 35/47] perf stat report: Add report command

Jiri Olsa
2015-07-21T12:36:56Z

Adding 'perf stat report' command support. ATM it only
processes attr events and display nothing.

Link: http://lkml.kernel.org/n/tip-a43rs4c6szofeuo2gjlcpm0h@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
tools/perf/Documentation/perf-stat.txt | 12 ++++++++
tools/perf/builtin-stat.c | 54 +++++++++++++++++++++++++++++++---
tools/perf/util/session.c | 3 ++
3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 0ccce466ad53..f7234c6263c0 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -11,6 +11,7 @@ SYNOPSIS
'perf stat' [-e <EVENT> | --event=EVENT] [-a] <command>
'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>]
'perf stat' [-e <EVENT> | --event=EVENT] [-a] record [-o file] -- <command> [<options>]
+'perf stat' report [-i file]

DESCRIPTION
-----------
@@ -26,6 +27,9 @@ OPTIONS
record::
See STAT RECORD.

+report::
+ See STAT REPORT.
+
-e::
--event=::
Select the PMU event. Selection can be:
@@ -169,6 +173,14 @@ Stores stat data into perf data file.
--output file::
Output file name.

+STAT RECORD
+-----------
+Reads and reports stat data from perf data file.
+
+-i file::
+--input file::
+Input file name.
+

EXAMPLES
--------
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8ad497522a0e..aa2352f92878 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -59,6 +59,8 @@
#include "util/thread.h"
#include "util/thread_map.h"
#include "util/session.h"
+#include "util/tool.h"
+#include "asm/bug.h"

#include <stdlib.h>
#include <sys/prctl.h>
@@ -138,6 +140,10 @@ static struct perf_stat_config stat_config = {
.scale = true,
};

+struct perf_stat_cmd {
+ struct perf_tool tool;
+};
+
static inline void diff_timespec(struct timespec *r, struct timespec *a,
struct timespec *b)
{
@@ -970,8 +976,8 @@ static void print_header(int argc, const char **argv)
else if (target.cpu_list)
fprintf(output, "\'CPU(s) %s", target.cpu_list);
else if (!target__has_task(&target)) {
- fprintf(output, "\'%s", argv[0]);
- for (i = 1; i < argc; i++)
+ fprintf(output, "\'%s", argv ? argv[0] : "pipe");
+ for (i = 1; argv && (i < argc); i++)
fprintf(output, " %s", argv[i]);
} else if (target.pid)
fprintf(output, "process id \'%s", target.pid);
@@ -1322,6 +1328,45 @@ static int __cmd_record(int argc, const char **argv)
return argc;
}

+static const char * const report_usage[] = {
+ "perf stat report [<options>]",
+ NULL,
+};
+
+static int __cmd_report(int argc, const char **argv)
+{
+ struct perf_session *session;
+ const struct option options[] = {
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
+ OPT_END()
+ };
+ struct perf_data_file file = {
+ .mode = PERF_DATA_MODE_READ,
+ };
+ struct perf_stat_cmd stat = {
+ .tool = {
+ .attr = perf_event__process_attr,
+ },
+ };
+ int ret;
+
+ argc = parse_options(argc, argv, options, report_usage, 0);
+
+ session = perf_session__new(&file, false, &stat.tool);
+ if (session == NULL)
+ return -1;
+
+ stat_config.output = stderr;
+ evsel_list = session->evlist;
+
+ ret = perf_session__process_events(session);
+ if (ret)
+ return ret;
+
+ perf_session__delete(session);
+ return 0;
+}
+
int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
{
bool append_file = false;
@@ -1395,7 +1440,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
const char *mode;
FILE *output = stderr;
unsigned int interval;
- const char * const stat_subcommands[] = { "record" };
+ const char * const stat_subcommands[] = { "record", "report" };

setlocale(LC_ALL, "");

@@ -1411,7 +1456,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
argc = __cmd_record(argc, argv);
if (argc < 0)
return -1;
- }
+ } else if (argc && !strncmp(argv[0], "rep", 3))
+ return __cmd_report(argc, argv);

interval = stat_config.interval;

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 4b957c02fffb..4fdd0458a166 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -36,6 +36,9 @@ static int perf_session__open(struct perf_session *session)
if (perf_data_file__is_pipe(file))
return 0;

+ if (perf_header__has_feat(&session->header, HEADER_STAT))
+ return 0;
+
if (!perf_evlist__valid_sample_type(session->evlist)) {
pr_err("non matching sample_type");
return -1;
--
2.4.3