diff options
author | Andi Kleen <ak@linux.intel.com> | 2017-09-05 14:40:57 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-09-13 08:49:14 -0400 |
commit | b1491ace8eb2e92677cd9ee966763f8f53d29d16 (patch) | |
tree | 26f3d79d66e169d76c9edd1cc56df89cef58c903 /tools/perf/builtin-script.c | |
parent | 84c417422798c897f637b0249f64a52807b4a61b (diff) |
perf script: Support user regs
Teach perf script to print user regs.
% perf record --user-regs=ip,sp ...
% perf script -F ip,sym,uregs
...
ffffffff9e060c24 native_write_msr ABI:2 SP:0x7ffd0ea06c38 IP:0x7fe77f55b637
ffffffff9e060c24 native_write_msr ABI:2 SP:0x7ffd0ea06c38 IP:0x7fe77f55b637
ffffffff9e060c24 native_write_msr ABI:2 SP:0x7ffd0ea06c38 IP:0x7fe77f55b637
ffffffff9e060c24 native_write_msr ABI:2 SP:0x7ffd0ea06c38 IP:0x7fe77f55b637
ffffffff9e00cc12 intel_pmu_handle_irq ABI:2 SP:0x7ffd0ea06c38 IP:0x7fe77f55b637
v2: Rebased on top of phys-addr patches
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Link: http://lkml.kernel.org/r/20170905184057.26135-1-andi@firstfloor.org
[ Use PRIu64 for regs->abi in print_sample_uregs() ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 3d4c3b5e1868..725dbd3dd104 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -88,6 +88,7 @@ enum perf_output_field { | |||
88 | PERF_OUTPUT_BRSTACKOFF = 1U << 24, | 88 | PERF_OUTPUT_BRSTACKOFF = 1U << 24, |
89 | PERF_OUTPUT_SYNTH = 1U << 25, | 89 | PERF_OUTPUT_SYNTH = 1U << 25, |
90 | PERF_OUTPUT_PHYS_ADDR = 1U << 26, | 90 | PERF_OUTPUT_PHYS_ADDR = 1U << 26, |
91 | PERF_OUTPUT_UREGS = 1U << 27, | ||
91 | }; | 92 | }; |
92 | 93 | ||
93 | struct output_option { | 94 | struct output_option { |
@@ -109,6 +110,7 @@ struct output_option { | |||
109 | {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, | 110 | {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, |
110 | {.str = "period", .field = PERF_OUTPUT_PERIOD}, | 111 | {.str = "period", .field = PERF_OUTPUT_PERIOD}, |
111 | {.str = "iregs", .field = PERF_OUTPUT_IREGS}, | 112 | {.str = "iregs", .field = PERF_OUTPUT_IREGS}, |
113 | {.str = "uregs", .field = PERF_OUTPUT_UREGS}, | ||
112 | {.str = "brstack", .field = PERF_OUTPUT_BRSTACK}, | 114 | {.str = "brstack", .field = PERF_OUTPUT_BRSTACK}, |
113 | {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM}, | 115 | {.str = "brstacksym", .field = PERF_OUTPUT_BRSTACKSYM}, |
114 | {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, | 116 | {.str = "data_src", .field = PERF_OUTPUT_DATA_SRC}, |
@@ -385,6 +387,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
385 | PERF_OUTPUT_IREGS)) | 387 | PERF_OUTPUT_IREGS)) |
386 | return -EINVAL; | 388 | return -EINVAL; |
387 | 389 | ||
390 | if (PRINT_FIELD(UREGS) && | ||
391 | perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_USER, "UREGS", | ||
392 | PERF_OUTPUT_UREGS)) | ||
393 | return -EINVAL; | ||
394 | |||
388 | if (PRINT_FIELD(PHYS_ADDR) && | 395 | if (PRINT_FIELD(PHYS_ADDR) && |
389 | perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", | 396 | perf_evsel__check_stype(evsel, PERF_SAMPLE_PHYS_ADDR, "PHYS_ADDR", |
390 | PERF_OUTPUT_PHYS_ADDR)) | 397 | PERF_OUTPUT_PHYS_ADDR)) |
@@ -509,6 +516,24 @@ static void print_sample_iregs(struct perf_sample *sample, | |||
509 | } | 516 | } |
510 | } | 517 | } |
511 | 518 | ||
519 | static void print_sample_uregs(struct perf_sample *sample, | ||
520 | struct perf_event_attr *attr) | ||
521 | { | ||
522 | struct regs_dump *regs = &sample->user_regs; | ||
523 | uint64_t mask = attr->sample_regs_user; | ||
524 | unsigned i = 0, r; | ||
525 | |||
526 | if (!regs || !regs->regs) | ||
527 | return; | ||
528 | |||
529 | printf(" ABI:%" PRIu64 " ", regs->abi); | ||
530 | |||
531 | for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { | ||
532 | u64 val = regs->regs[i++]; | ||
533 | printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val); | ||
534 | } | ||
535 | } | ||
536 | |||
512 | static void print_sample_start(struct perf_sample *sample, | 537 | static void print_sample_start(struct perf_sample *sample, |
513 | struct thread *thread, | 538 | struct thread *thread, |
514 | struct perf_evsel *evsel) | 539 | struct perf_evsel *evsel) |
@@ -1444,6 +1469,9 @@ static void process_event(struct perf_script *script, | |||
1444 | if (PRINT_FIELD(IREGS)) | 1469 | if (PRINT_FIELD(IREGS)) |
1445 | print_sample_iregs(sample, attr); | 1470 | print_sample_iregs(sample, attr); |
1446 | 1471 | ||
1472 | if (PRINT_FIELD(UREGS)) | ||
1473 | print_sample_uregs(sample, attr); | ||
1474 | |||
1447 | if (PRINT_FIELD(BRSTACK)) | 1475 | if (PRINT_FIELD(BRSTACK)) |
1448 | print_sample_brstack(sample, thread, attr); | 1476 | print_sample_brstack(sample, thread, attr); |
1449 | else if (PRINT_FIELD(BRSTACKSYM)) | 1477 | else if (PRINT_FIELD(BRSTACKSYM)) |
@@ -2739,7 +2767,7 @@ int cmd_script(int argc, const char **argv) | |||
2739 | "+field to add and -field to remove." | 2767 | "+field to add and -field to remove." |
2740 | "Valid types: hw,sw,trace,raw,synth. " | 2768 | "Valid types: hw,sw,trace,raw,synth. " |
2741 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," | 2769 | "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," |
2742 | "addr,symoff,period,iregs,brstack,brstacksym,flags," | 2770 | "addr,symoff,period,iregs,uregs,brstack,brstacksym,flags," |
2743 | "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", | 2771 | "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", |
2744 | parse_output_fields), | 2772 | parse_output_fields), |
2745 | OPT_BOOLEAN('a', "all-cpus", &system_wide, | 2773 | OPT_BOOLEAN('a', "all-cpus", &system_wide, |