aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2017-12-06 17:20:04 +0100
committerIngo Molnar <mingo@kernel.org>2017-12-06 17:20:04 +0100
commitc32909741fe93032705e6da29b564b8fec84f415 (patch)
tree5f82c3f5f1c573f304feeff7c8c5428200e696dd /tools/perf/builtin-script.c
parentMerge branch 'perf/urgent' into perf/core, to pick up fixes (diff)
parentperf tools: Rename 'backward' to 'overwrite' in evlist, mmap and record (diff)
downloadwireguard-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.c97
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;