[PATCH 38/52] perf stat report: Add report command

From: Jiri Olsa
Date: Sun Oct 25 2015 - 10:56:32 EST


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

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

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 70eee1c2c444..95f492828657 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:
@@ -170,6 +174,14 @@ Stores stat data into perf data file.
--output file::
Output file name.

+STAT REPORT
+-----------
+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 54050095ee43..1491cce68da3 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -60,6 +60,8 @@
#include "util/thread_map.h"
#include "util/counts.h"
#include "util/session.h"
+#include "util/tool.h"
+#include "asm/bug.h"

#include <stdlib.h>
#include <sys/prctl.h>
@@ -129,6 +131,7 @@ struct perf_stat {
struct perf_data_file file;
struct perf_session *session;
u64 bytes_written;
+ struct perf_tool tool;
};

static struct perf_stat perf_stat;
@@ -1036,8 +1039,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);
@@ -1455,6 +1458,55 @@ static int __cmd_record(int argc, const char **argv)
return argc;
}

+static const char * const report_usage[] = {
+ "perf stat report [<options>]",
+ NULL,
+};
+
+static struct perf_stat perf_stat = {
+ .tool = {
+ .attr = perf_event__process_attr,
+ },
+};
+
+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 stat st;
+ int ret;
+
+ argc = parse_options(argc, argv, options, report_usage, 0);
+
+ if (!input_name || !strlen(input_name)) {
+ if (!fstat(STDIN_FILENO, &st) && S_ISFIFO(st.st_mode))
+ input_name = "-";
+ else
+ input_name = "perf.data";
+ }
+
+ perf_stat.file.path = input_name;
+ perf_stat.file.mode = PERF_DATA_MODE_READ;
+
+ session = perf_session__new(&perf_stat.file, false, &perf_stat.tool);
+ if (session == NULL)
+ return -1;
+
+ perf_stat.session = session;
+ 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;
@@ -1528,7 +1580,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, "");

@@ -1544,7 +1596,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 dafdbda37411..647be278a48f 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -37,6 +37,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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/