From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752694AbbJYOxL (ORCPT ); Sun, 25 Oct 2015 10:53:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42352 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752606AbbJYOxG (ORCPT ); Sun, 25 Oct 2015 10:53:06 -0400 From: Jiri Olsa To: Arnaldo Carvalho de Melo Cc: lkml , David Ahern , Ingo Molnar , Namhyung Kim , Peter Zijlstra , "Liang, Kan" Subject: [PATCH 29/52] perf stat record: Add record command Date: Sun, 25 Oct 2015 15:51:45 +0100 Message-Id: <1445784728-21732-30-git-send-email-jolsa@kernel.org> In-Reply-To: <1445784728-21732-1-git-send-email-jolsa@kernel.org> References: <1445784728-21732-1-git-send-email-jolsa@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add 'perf stat record' command support. It creates simple (header only) perf.data file ATM. Link: http://lkml.kernel.org/n/tip-0av5yfkwyywwgoiali88w4hi@git.kernel.org Signed-off-by: Jiri Olsa --- tools/perf/Documentation/perf-stat.txt | 12 ++++++ tools/perf/builtin-stat.c | 74 +++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 4e074a660826..70eee1c2c444 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -10,6 +10,7 @@ SYNOPSIS [verse] 'perf stat' [-e | --event=EVENT] [-a] 'perf stat' [-e | --event=EVENT] [-a] -- [] +'perf stat' [-e | --event=EVENT] [-a] record [-o file] -- [] DESCRIPTION ----------- @@ -22,6 +23,8 @@ OPTIONS ...:: Any command you can specify in a shell. +record:: + See STAT RECORD. -e:: --event=:: @@ -159,6 +162,15 @@ filter out the startup phase of the program, which is often very different. Print statistics of transactional execution if supported. +STAT RECORD +----------- +Stores stat data into perf data file. + +-o file:: +--output file:: +Output file name. + + EXAMPLES -------- diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a3880aa65b04..b65cc6a46226 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -59,6 +59,7 @@ #include "util/thread.h" #include "util/thread_map.h" #include "util/counts.h" +#include "util/session.h" #include #include @@ -123,6 +124,16 @@ static struct timespec ref_time; static struct cpu_map *aggr_map; static aggr_get_id_t aggr_get_id; +struct perf_stat { + bool record; + struct perf_data_file file; + struct perf_session *session; + u64 bytes_written; +}; + +static struct perf_stat perf_stat; +#define STAT_RECORD perf_stat.record + static volatile int done = 0; static struct perf_stat_config stat_config = { @@ -341,6 +352,15 @@ static int __run_perf_stat(int argc, const char **argv) return -1; } + if (STAT_RECORD) { + int err, fd = perf_data_file__fd(&perf_stat.file); + + err = perf_session__write_header(perf_stat.session, evsel_list, + fd, false); + if (err < 0) + return err; + } + /* * Enable counters and exec the command: */ @@ -1192,6 +1212,39 @@ static int add_default_attributes(void) return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); } +static const char * const recort_usage[] = { + "perf stat record []", + NULL, +}; + +static int __cmd_record(int argc, const char **argv) +{ + struct perf_session *session; + struct perf_data_file *file = &perf_stat.file; + const struct option options[] = { + OPT_STRING('o', "output", &perf_stat.file.path, "file", "output file name"), + OPT_END() + }; + + argc = parse_options(argc, argv, options, record_usage, + PARSE_OPT_STOP_AT_NON_OPTION); + + session = perf_session__new(file, false, NULL); + if (session == NULL) { + pr_err("Perf session creation failed.\n"); + return -1; + } + + /* No pipe support ATM */ + if (perf_stat.file.is_pipe) + return -EINVAL; + + session->evlist = evsel_list; + perf_stat.session = session; + perf_stat.record = true; + return argc; +} + int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) { bool append_file = false; @@ -1265,6 +1318,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" }; setlocale(LC_ALL, ""); @@ -1272,8 +1326,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) if (evsel_list == NULL) return -ENOMEM; - argc = parse_options(argc, argv, options, stat_usage, - PARSE_OPT_STOP_AT_NON_OPTION); + argc = parse_options_subcommand(argc, argv, options, stat_subcommands, + (const char **) stat_usage, + PARSE_OPT_STOP_AT_NON_OPTION); + + if (argc && !strncmp(argv[0], "rec", 3)) { + argc = __cmd_record(argc, argv); + if (argc < 0) + return -1; + } interval = stat_config.interval; @@ -1444,6 +1505,15 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) if (!forever && status != -1 && !interval) print_counters(NULL, argc, argv); + if (STAT_RECORD) { + int fd = perf_data_file__fd(&perf_stat.file); + + perf_stat.session->header.data_size += perf_stat.bytes_written; + perf_session__write_header(perf_stat.session, evsel_list, fd, true); + + perf_session__delete(perf_stat.session); + } + perf_evlist__free_stats(evsel_list); out: perf_evlist__delete(evsel_list); -- 2.4.3