lkml.org 
[lkml]   [2015]   [Nov]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 02/25] perf stat record: Add record command
    Date
    Add 'perf stat record' command support. It creates simple
    (header only) perf.data file ATM.

    The record command could be specified anywhere among stat
    options. All stat command options are valid for stat record
    command with '-o' option exception. If specified for record
    command it denotes the perf data file name.

    Tested-by: Kan Liang <kan.liang@intel.com>
    Link: http://lkml.kernel.org/n/tip-0av5yfkwyywwgoiali88w4hi@git.kernel.org
    Signed-off-by: Jiri Olsa <jolsa@kernel.org>
    ---
    tools/perf/Documentation/perf-stat.txt | 12 ++++++
    tools/perf/builtin-stat.c | 78 ++++++++++++++++++++++++++++++++--
    2 files changed, 87 insertions(+), 3 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=EVENT] [-a] <command>
    'perf stat' [-e <EVENT> | --event=EVENT] [-a] -- <command> [<options>]
    +'perf stat' [-e <EVENT> | --event=EVENT] [-a] record [-o file] -- <command> [<options>]

    DESCRIPTION
    -----------
    @@ -22,6 +23,8 @@ OPTIONS
    <command>...::
    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 e77880b5094d..04123835fd81 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 <stdlib.h>
    #include <sys/prctl.h>
    @@ -126,6 +127,16 @@ static bool append_file;
    static const char *output_name;
    static int output_fd;

    +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 = {
    @@ -344,6 +355,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:
    */
    @@ -1236,6 +1256,38 @@ 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 [<options>]",
    + NULL,
    +};
    +
    +static int __cmd_record(int argc, const char **argv)
    +{
    + struct perf_session *session;
    + struct perf_data_file *file = &perf_stat.file;
    +
    + argc = parse_options(argc, argv, stat_options, record_usage,
    + PARSE_OPT_STOP_AT_NON_OPTION);
    +
    + if (output_name)
    + file->path = output_name;
    +
    + 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)
    {
    const char * const stat_usage[] = {
    @@ -1246,6 +1298,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, "");

    @@ -1253,12 +1306,22 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
    if (evsel_list == NULL)
    return -ENOMEM;

    - argc = parse_options(argc, argv, stat_options, stat_usage,
    - PARSE_OPT_STOP_AT_NON_OPTION);
    + argc = parse_options_subcommand(argc, argv, stat_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;

    - if (output_name && strcmp(output_name, "-"))
    + /*
    + * For record command the -o is already taken care of.
    + */
    + if (!STAT_RECORD && output_name && strcmp(output_name, "-"))
    output = NULL;

    if (output_name && output_fd) {
    @@ -1425,6 +1488,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


    \
     
     \ /
      Last update: 2015-11-05 16:01    [W:4.101 / U:0.228 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site