lkml.org 
[lkml]   [2015]   [Apr]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V3 11/25] perf record: Add AUX area tracing Snapshot Mode support
    Date
    Add a new option and support for Instruction
    Tracing Snapshot Mode. When the new option is
    selected, no AUX area tracing data is
    captured until a signal (SIGUSR2) is received.

    Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
    ---
    tools/perf/Documentation/perf-record.txt | 7 ++
    tools/perf/builtin-record.c | 144 ++++++++++++++++++++++++++-----
    tools/perf/util/auxtrace.h | 11 +++
    tools/perf/util/parse-options.h | 4 +
    4 files changed, 145 insertions(+), 21 deletions(-)

    diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
    index 76a141e..57dd57b 100644
    --- a/tools/perf/Documentation/perf-record.txt
    +++ b/tools/perf/Documentation/perf-record.txt
    @@ -259,6 +259,13 @@ records. See clock_gettime(). In particular CLOCK_MONOTONIC and
    CLOCK_MONOTONIC_RAW are supported, some events might also allow
    CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI.

    +-S::
    +--snapshot::
    +Select AUX area tracing Snapshot Mode. This option is valid only with an
    +AUX area tracing event. Optionally the number of bytes to capture per
    +snapshot can be specified. In Snapshot Mode, trace data is captured only when
    +signal SIGUSR2 is received.
    +
    SEE ALSO
    --------
    linkperf:perf-stat[1], linkperf:perf-list[1]
    diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
    index dbb2c02..012e97e 100644
    --- a/tools/perf/builtin-record.c
    +++ b/tools/perf/builtin-record.c
    @@ -112,6 +112,32 @@ out:
    return rc;
    }

    +static volatile int done = 0;
    +static volatile int signr = -1;
    +static volatile int child_finished = 0;
    +static volatile int auxtrace_snapshot_enabled;
    +static volatile int auxtrace_snapshot_err;
    +static volatile int auxtrace_record__snapshot_started;
    +
    +static void sig_handler(int sig)
    +{
    + if (sig == SIGCHLD)
    + child_finished = 1;
    + else
    + signr = sig;
    +
    + done = 1;
    +}
    +
    +static void record__sig_exit(void)
    +{
    + if (signr == -1)
    + return;
    +
    + signal(signr, SIG_DFL);
    + raise(signr);
    +}
    +
    #ifdef HAVE_AUXTRACE_SUPPORT

    static int record__process_auxtrace(struct perf_tool *tool,
    @@ -167,6 +193,56 @@ static int record__auxtrace_mmap_read(struct record *rec,
    return 0;
    }

    +static int record__auxtrace_mmap_read_snapshot(struct record *rec,
    + struct auxtrace_mmap *mm)
    +{
    + int ret;
    +
    + ret = auxtrace_mmap__read_snapshot(mm, rec->itr, &rec->tool,
    + record__process_auxtrace,
    + rec->opts.auxtrace_snapshot_size);
    + if (ret < 0)
    + return ret;
    +
    + if (ret)
    + rec->samples++;
    +
    + return 0;
    +}
    +
    +static int record__auxtrace_read_snapshot_all(struct record *rec)
    +{
    + int i;
    + int rc = 0;
    +
    + for (i = 0; i < rec->evlist->nr_mmaps; i++) {
    + struct auxtrace_mmap *mm =
    + &rec->evlist->mmap[i].auxtrace_mmap;
    +
    + if (!mm->base)
    + continue;
    +
    + if (record__auxtrace_mmap_read_snapshot(rec, mm) != 0) {
    + rc = -1;
    + goto out;
    + }
    + }
    +out:
    + return rc;
    +}
    +
    +static void record__read_auxtrace_snapshot(struct record *rec)
    +{
    + pr_debug("Recording AUX area tracing snapshot\n");
    + if (record__auxtrace_read_snapshot_all(rec) < 0) {
    + auxtrace_snapshot_err = -1;
    + } else {
    + auxtrace_snapshot_err = auxtrace_record__snapshot_finish(rec->itr);
    + if (!auxtrace_snapshot_err)
    + auxtrace_snapshot_enabled = 1;
    + }
    +}
    +
    #else

    static inline
    @@ -176,31 +252,19 @@ int record__auxtrace_mmap_read(struct record *rec __maybe_unused,
    return 0;
    }

    -#endif
    -
    -static volatile int done = 0;
    -static volatile int signr = -1;
    -static volatile int child_finished = 0;
    -
    -static void sig_handler(int sig)
    +static inline
    +void record__read_auxtrace_snapshot(struct record *rec __maybe_unused)
    {
    - if (sig == SIGCHLD)
    - child_finished = 1;
    - else
    - signr = sig;
    -
    - done = 1;
    }

    -static void record__sig_exit(void)
    +static inline
    +int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused)
    {
    - if (signr == -1)
    - return;
    -
    - signal(signr, SIG_DFL);
    - raise(signr);
    + return 0;
    }

    +#endif
    +
    static int record__open(struct record *rec)
    {
    char msg[512];
    @@ -238,7 +302,8 @@ try_again:
    }

    if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false,
    - opts->auxtrace_mmap_pages, false) < 0) {
    + opts->auxtrace_mmap_pages,
    + opts->auxtrace_snapshot_mode) < 0) {
    if (errno == EPERM) {
    pr_err("Permission error mapping pages.\n"
    "Consider increasing "
    @@ -349,7 +414,7 @@ static int record__mmap_read_all(struct record *rec)
    }
    }

    - if (mm->base &&
    + if (mm->base && !rec->opts.auxtrace_snapshot_mode &&
    record__auxtrace_mmap_read(rec, mm) != 0) {
    rc = -1;
    goto out;
    @@ -404,6 +469,8 @@ static void workload_exec_failed_signal(int signo __maybe_unused,
    child_finished = 1;
    }

    +static void snapshot_sig_handler(int sig);
    +
    static int __cmd_record(struct record *rec, int argc, const char **argv)
    {
    int err;
    @@ -424,6 +491,10 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
    signal(SIGCHLD, sig_handler);
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);
    + if (rec->opts.auxtrace_snapshot_mode)
    + signal(SIGUSR2, snapshot_sig_handler);
    + else
    + signal(SIGUSR2, SIG_IGN);

    session = perf_session__new(file, false, tool);
    if (session == NULL) {
    @@ -563,14 +634,27 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
    perf_evlist__enable(rec->evlist);
    }

    + auxtrace_snapshot_enabled = 1;
    for (;;) {
    int hits = rec->samples;

    if (record__mmap_read_all(rec) < 0) {
    + auxtrace_snapshot_enabled = 0;
    err = -1;
    goto out_child;
    }

    + if (auxtrace_record__snapshot_started) {
    + auxtrace_record__snapshot_started = 0;
    + if (!auxtrace_snapshot_err)
    + record__read_auxtrace_snapshot(rec);
    + if (auxtrace_snapshot_err) {
    + pr_err("AUX area tracing snapshot failed\n");
    + err = -1;
    + goto out_child;
    + }
    + }
    +
    if (hits == rec->samples) {
    if (done || draining)
    break;
    @@ -593,10 +677,12 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)
    * disable events in this case.
    */
    if (done && !disabled && !target__none(&opts->target)) {
    + auxtrace_snapshot_enabled = 0;
    perf_evlist__disable(rec->evlist);
    disabled = true;
    }
    }
    + auxtrace_snapshot_enabled = 0;

    if (forks && workload_exec_errno) {
    char msg[STRERR_BUFSIZE];
    @@ -1068,6 +1154,8 @@ struct option __record_options[] = {
    OPT_CALLBACK('k', "clockid", &record.opts,
    "clockid", "clockid to use for events, see clock_gettime()",
    parse_clockid),
    + OPT_STRING_OPTARG('S', "snapshot", &record.opts.auxtrace_snapshot_opts,
    + "opts", "AUX area tracing Snapshot Mode", ""),
    OPT_END()
    };

    @@ -1102,6 +1190,11 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
    return err;
    }

    + err = auxtrace_parse_snapshot_options(rec->itr, &rec->opts,
    + rec->opts.auxtrace_snapshot_opts);
    + if (err)
    + return err;
    +
    err = -ENOMEM;

    symbol__init(NULL);
    @@ -1165,3 +1258,12 @@ out_symbol_exit:
    auxtrace_record__free(rec->itr);
    return err;
    }
    +
    +static void snapshot_sig_handler(int sig __maybe_unused)
    +{
    + if (!auxtrace_snapshot_enabled)
    + return;
    + auxtrace_snapshot_enabled = 0;
    + auxtrace_snapshot_err = auxtrace_record__snapshot_start(record.itr);
    + auxtrace_record__snapshot_started = 1;
    +}
    diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
    index f0bacb6..a5d0284 100644
    --- a/tools/perf/util/auxtrace.h
    +++ b/tools/perf/util/auxtrace.h
    @@ -564,6 +564,17 @@ int itrace_parse_synth_opts(const struct option *opt __maybe_unused,
    }

    static inline
    +int auxtrace_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
    + struct record_opts *opts __maybe_unused,
    + const char *str)
    +{
    + if (!str)
    + return 0;
    + pr_err("AUX area tracing not supported\n");
    + return -EINVAL;
    +}
    +
    +static inline
    int auxtrace__process_event(struct perf_session *session __maybe_unused,
    union perf_event *event __maybe_unused,
    struct perf_sample *sample __maybe_unused,
    diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
    index 59561fd..367d8b8 100644
    --- a/tools/perf/util/parse-options.h
    +++ b/tools/perf/util/parse-options.h
    @@ -123,6 +123,10 @@ struct option {
    #define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
    #define OPT_U64(s, l, v, h) { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
    #define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) }
    +#define OPT_STRING_OPTARG(s, l, v, a, h, d) \
    + { .type = OPTION_STRING, .short_name = (s), .long_name = (l), \
    + .value = check_vtype(v, const char **), (a), .help = (h), \
    + .flags = PARSE_OPT_OPTARG, .defval = (intptr_t)(d) }
    #define OPT_STRING_NOEMPTY(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h), .flags = PARSE_OPT_NOEMPTY}
    #define OPT_DATE(s, l, v, h) \
    { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
    --
    1.9.1


    \
     
     \ /
      Last update: 2015-04-24 21:41    [W:4.399 / U:1.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site