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

Link: http://lkml.kernel.org/n/tip-a43rs4c6szofeuo2gjlcp...@git.kernel.org
Signed-off-by: Jiri Olsa <jo...@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

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

Reply via email to