diff options
author | 2017-12-06 17:20:04 +0100 | |
---|---|---|
committer | 2017-12-06 17:20:04 +0100 | |
commit | c32909741fe93032705e6da29b564b8fec84f415 (patch) | |
tree | 5f82c3f5f1c573f304feeff7c8c5428200e696dd /tools/perf/builtin-script.c | |
parent | Merge branch 'perf/urgent' into perf/core, to pick up fixes (diff) | |
parent | perf tools: Rename 'backward' to 'overwrite' in evlist, mmap and record (diff) | |
download | wireguard-linux-c32909741fe93032705e6da29b564b8fec84f415.tar.xz wireguard-linux-c32909741fe93032705e6da29b564b8fec84f415.zip |
Merge tag 'perf-core-for-mingo-4.16-20171206' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Improve build messages for files needed by Intel-PT, originally copied
from the kernel sources, that drifted from its original (Adrian Hunter)
- Allow computing 'perf stat' style metrics in 'perf script' (Andi Kleen)
- Fix 'perf report -D' output for user metadata events (Arnaldo Carvalho de Melo)
- Add feature test for pthread_barrier_t availability (Arnaldo Carvalho de Melo)
- Allow again using x86's asm.h when building for the 'bpf' clang target,
making some 'perf test' LLVM/BPF entries work again (Arnaldo Carvalho de Melo)
- Use cpumaps in 'perf bench futex', eliminating some code duplication
(Davidlohr Bueso)
- Improve PMU infrastructure to support amp64's ThunderX2 implementation
defined core events (Ganapatrao Kulkarni)
- Add hint about how to add USDT probes for Node.js (Hansuk Hong)
- s/390 needs -fPIC to be incrementally linked or linked to shared
libraries (Hendrik Brueckner)
- Use pthread_barrier to synch 'perf bench futex wake-parallel' waker
threads (James Yang)
- Fix up build in hardened environments, such as Fedora 27 (Jiri Olsa)
- Add a tip about cacheline events in 'perf c2c' (Sangwon Hong)
- Set browser mode right before setup_browser(), because we may have
errors printed before that, which were getting lost (Seokho Song)
- s390x doesn't support PERF_TYPE_BREAKPOINT, so disable 'perf test'
cases 19 and 20 on s390x, that tests that feature (Thomas Richter)
- Fix unnecessary memory allocation for s390x 'perf annotate' objdump
parsing, which could lead to thousands of needless entries in the
instruction handling array (Thomas Richter)
- Fix objdump comment parsing for Intel mov dissassembly (Thomas Richter)
- Clarify usage of 'overwrite' and 'backward' in the evlist/mmap code,
removing the 'overwrite' parameter from several functions as it was
always used it as 'false' (Wang Nan)
- Fix 'perf record' backward recording, it wasn't doing what was
expected: overwriting records when the ring buffer gets full (Wang Nan)
- Use more flexible pattern matching for CPU identification for perf
vendor event's mapfile.csv, removing the need for a new perf binary
for a sligthly different chip revision that shares the same set of
counters (William Cohen)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index ee7c7aaaae72..39d8b55f0db3 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -22,6 +22,7 @@ #include "util/cpumap.h" #include "util/thread_map.h" #include "util/stat.h" +#include "util/color.h" #include "util/string2.h" #include "util/thread-stack.h" #include "util/time-utils.h" @@ -90,6 +91,7 @@ enum perf_output_field { PERF_OUTPUT_SYNTH = 1U << 25, PERF_OUTPUT_PHYS_ADDR = 1U << 26, PERF_OUTPUT_UREGS = 1U << 27, + PERF_OUTPUT_METRIC = 1U << 28, }; struct output_option { @@ -124,6 +126,7 @@ struct output_option { {.str = "brstackoff", .field = PERF_OUTPUT_BRSTACKOFF}, {.str = "synth", .field = PERF_OUTPUT_SYNTH}, {.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR}, + {.str = "metric", .field = PERF_OUTPUT_METRIC}, }; enum { @@ -215,12 +218,20 @@ struct perf_evsel_script { char *filename; FILE *fp; u64 samples; + /* For metric output */ + u64 val; + int gnum; }; +static inline struct perf_evsel_script *evsel_script(struct perf_evsel *evsel) +{ + return (struct perf_evsel_script *)evsel->priv; +} + static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel, struct perf_data *data) { - struct perf_evsel_script *es = malloc(sizeof(*es)); + struct perf_evsel_script *es = zalloc(sizeof(*es)); if (es != NULL) { if (asprintf(&es->filename, "%s.%s.dump", data->file.path, perf_evsel__name(evsel)) < 0) @@ -228,7 +239,6 @@ static struct perf_evsel_script *perf_evsel_script__new(struct perf_evsel *evsel es->fp = fopen(es->filename, "w"); if (es->fp == NULL) goto out_free_filename; - es->samples = 0; } return es; @@ -1472,6 +1482,86 @@ static int data_src__fprintf(u64 data_src, FILE *fp) return fprintf(fp, "%-*s", maxlen, out); } +struct metric_ctx { + struct perf_sample *sample; + struct thread *thread; + struct perf_evsel *evsel; + FILE *fp; +}; + +static void script_print_metric(void *ctx, const char *color, + const char *fmt, + const char *unit, double val) +{ + struct metric_ctx *mctx = ctx; + + if (!fmt) + return; + perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel, + mctx->fp); + fputs("\tmetric: ", mctx->fp); + if (color) + color_fprintf(mctx->fp, color, fmt, val); + else + printf(fmt, val); + fprintf(mctx->fp, " %s\n", unit); +} + +static void script_new_line(void *ctx) +{ + struct metric_ctx *mctx = ctx; + + perf_sample__fprintf_start(mctx->sample, mctx->thread, mctx->evsel, + mctx->fp); + fputs("\tmetric: ", mctx->fp); +} + +static void perf_sample__fprint_metric(struct perf_script *script, + struct thread *thread, + struct perf_evsel *evsel, + struct perf_sample *sample, + FILE *fp) +{ + struct perf_stat_output_ctx ctx = { + .print_metric = script_print_metric, + .new_line = script_new_line, + .ctx = &(struct metric_ctx) { + .sample = sample, + .thread = thread, + .evsel = evsel, + .fp = fp, + }, + .force_header = false, + }; + struct perf_evsel *ev2; + static bool init; + u64 val; + + if (!init) { + perf_stat__init_shadow_stats(); + init = true; + } + if (!evsel->stats) + perf_evlist__alloc_stats(script->session->evlist, false); + if (evsel_script(evsel->leader)->gnum++ == 0) + perf_stat__reset_shadow_stats(); + val = sample->period * evsel->scale; + perf_stat__update_shadow_stats(evsel, + val, + sample->cpu); + evsel_script(evsel)->val = val; + if (evsel_script(evsel->leader)->gnum == evsel->leader->nr_members) { + for_each_group_member (ev2, evsel->leader) { + perf_stat__print_shadow_stats(ev2, + evsel_script(ev2)->val, + sample->cpu, + &ctx, + NULL); + } + evsel_script(evsel->leader)->gnum = 0; + } +} + static void process_event(struct perf_script *script, struct perf_sample *sample, struct perf_evsel *evsel, struct addr_location *al, @@ -1559,6 +1649,9 @@ static void process_event(struct perf_script *script, if (PRINT_FIELD(PHYS_ADDR)) fprintf(fp, "%16" PRIx64, sample->phys_addr); fprintf(fp, "\n"); + + if (PRINT_FIELD(METRIC)) + perf_sample__fprint_metric(script, thread, evsel, sample, fp); } static struct scripting_ops *scripting_ops; |