Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932161AbbGUMdL (ORCPT ); Tue, 21 Jul 2015 08:33:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39537 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932086AbbGUMdB (ORCPT ); Tue, 21 Jul 2015 08:33:01 -0400 From: Jiri Olsa To: Arnaldo Carvalho de Melo Cc: lkml , David Ahern , Ingo Molnar , Namhyung Kim , Peter Zijlstra Subject: [PATCH 28/47] perf stat record: Add record command Date: Tue, 21 Jul 2015 14:31:48 +0200 Message-Id: <1437481927-29538-29-git-send-email-jolsa@kernel.org> In-Reply-To: <1437481927-29538-1-git-send-email-jolsa@kernel.org> References: <1437481927-29538-1-git-send-email-jolsa@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5157 Lines: 182 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 47469abdcc1c..0ccce466ad53 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=:: @@ -158,6 +161,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 a054ddc0b2a0..f78bd3e22d40 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -58,6 +58,7 @@ #include "util/cpumap.h" #include "util/thread.h" #include "util/thread_map.h" +#include "util/session.h" #include #include @@ -120,6 +121,16 @@ static struct timespec ref_time; static struct cpu_map *aggr_map; static int (*aggr_get_id)(struct cpu_map *m, int cpu); +struct perf_stat_record { + bool enabled; + struct perf_data_file file; + struct perf_session *session; + u64 bytes_written; +}; + +static struct perf_stat_record stat_record; +#define STAT_RECORD stat_record.enabled + static volatile int done = 0; static struct perf_stat_config stat_config = { @@ -338,6 +349,15 @@ static int __run_perf_stat(int argc, const char **argv) return -1; } + if (STAT_RECORD) { + int err, fd = perf_data_file__fd(&stat_record.file); + + err = perf_session__write_header(stat_record.session, evsel_list, + fd, false); + if (err < 0) + return err; + } + /* * Enable counters and exec the command: */ @@ -1125,6 +1145,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 = &stat_record.file; + const struct option options[] = { + OPT_STRING('o', "output", &stat_record.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 (stat_record.file.is_pipe) + return -EINVAL; + + session->evlist = evsel_list; + stat_record.session = session; + stat_record.enabled = true; + return argc; +} + int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) { bool append_file = false; @@ -1198,6 +1251,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, ""); @@ -1205,8 +1259,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; @@ -1372,6 +1433,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(&stat_record.file); + + stat_record.session->header.data_size += stat_record.bytes_written; + perf_session__write_header(stat_record.session, evsel_list, fd, true); + + perf_session__delete(stat_record.session); + } + perf_evlist__free_stats(evsel_list); out: perf_evlist__delete(evsel_list); -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/