aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-10-12 13:09:27 -0400
committerMark Brown <broonie@kernel.org>2015-10-12 13:09:27 -0400
commit79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch)
tree5e0fa7156acb75ba603022bc807df8f2fedb97a8 /tools/perf/builtin-script.c
parent721b51fcf91898299d96f4b72cb9434cda29dce6 (diff)
parent8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff)
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c104
1 files changed, 98 insertions, 6 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 24809787369f..eb51325e8ad9 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -6,6 +6,7 @@
6#include "util/exec_cmd.h" 6#include "util/exec_cmd.h"
7#include "util/header.h" 7#include "util/header.h"
8#include "util/parse-options.h" 8#include "util/parse-options.h"
9#include "util/perf_regs.h"
9#include "util/session.h" 10#include "util/session.h"
10#include "util/tool.h" 11#include "util/tool.h"
11#include "util/symbol.h" 12#include "util/symbol.h"
@@ -46,6 +47,7 @@ enum perf_output_field {
46 PERF_OUTPUT_SYMOFFSET = 1U << 11, 47 PERF_OUTPUT_SYMOFFSET = 1U << 11,
47 PERF_OUTPUT_SRCLINE = 1U << 12, 48 PERF_OUTPUT_SRCLINE = 1U << 12,
48 PERF_OUTPUT_PERIOD = 1U << 13, 49 PERF_OUTPUT_PERIOD = 1U << 13,
50 PERF_OUTPUT_IREGS = 1U << 14,
49}; 51};
50 52
51struct output_option { 53struct output_option {
@@ -66,6 +68,7 @@ struct output_option {
66 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 68 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
67 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, 69 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE},
68 {.str = "period", .field = PERF_OUTPUT_PERIOD}, 70 {.str = "period", .field = PERF_OUTPUT_PERIOD},
71 {.str = "iregs", .field = PERF_OUTPUT_IREGS},
69}; 72};
70 73
71/* default set to maintain compatibility with current format */ 74/* default set to maintain compatibility with current format */
@@ -255,6 +258,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
255 PERF_OUTPUT_PERIOD)) 258 PERF_OUTPUT_PERIOD))
256 return -EINVAL; 259 return -EINVAL;
257 260
261 if (PRINT_FIELD(IREGS) &&
262 perf_evsel__check_stype(evsel, PERF_SAMPLE_REGS_INTR, "IREGS",
263 PERF_OUTPUT_IREGS))
264 return -EINVAL;
265
258 return 0; 266 return 0;
259} 267}
260 268
@@ -352,6 +360,24 @@ out:
352 return 0; 360 return 0;
353} 361}
354 362
363static void print_sample_iregs(union perf_event *event __maybe_unused,
364 struct perf_sample *sample,
365 struct thread *thread __maybe_unused,
366 struct perf_event_attr *attr)
367{
368 struct regs_dump *regs = &sample->intr_regs;
369 uint64_t mask = attr->sample_regs_intr;
370 unsigned i = 0, r;
371
372 if (!regs)
373 return;
374
375 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) {
376 u64 val = regs->regs[i++];
377 printf("%5s:0x%"PRIx64" ", perf_reg_name(r), val);
378 }
379}
380
355static void print_sample_start(struct perf_sample *sample, 381static void print_sample_start(struct perf_sample *sample,
356 struct thread *thread, 382 struct thread *thread,
357 struct perf_evsel *evsel) 383 struct perf_evsel *evsel)
@@ -525,6 +551,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample,
525 PERF_MAX_STACK_DEPTH); 551 PERF_MAX_STACK_DEPTH);
526 } 552 }
527 553
554 if (PRINT_FIELD(IREGS))
555 print_sample_iregs(event, sample, thread, attr);
556
528 printf("\n"); 557 printf("\n");
529} 558}
530 559
@@ -623,6 +652,7 @@ struct perf_script {
623 struct perf_session *session; 652 struct perf_session *session;
624 bool show_task_events; 653 bool show_task_events;
625 bool show_mmap_events; 654 bool show_mmap_events;
655 bool show_switch_events;
626}; 656};
627 657
628static int process_attr(struct perf_tool *tool, union perf_event *event, 658static int process_attr(struct perf_tool *tool, union perf_event *event,
@@ -661,7 +691,7 @@ static int process_comm_event(struct perf_tool *tool,
661 struct thread *thread; 691 struct thread *thread;
662 struct perf_script *script = container_of(tool, struct perf_script, tool); 692 struct perf_script *script = container_of(tool, struct perf_script, tool);
663 struct perf_session *session = script->session; 693 struct perf_session *session = script->session;
664 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 694 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
665 int ret = -1; 695 int ret = -1;
666 696
667 thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); 697 thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid);
@@ -695,7 +725,7 @@ static int process_fork_event(struct perf_tool *tool,
695 struct thread *thread; 725 struct thread *thread;
696 struct perf_script *script = container_of(tool, struct perf_script, tool); 726 struct perf_script *script = container_of(tool, struct perf_script, tool);
697 struct perf_session *session = script->session; 727 struct perf_session *session = script->session;
698 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 728 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
699 729
700 if (perf_event__process_fork(tool, event, sample, machine) < 0) 730 if (perf_event__process_fork(tool, event, sample, machine) < 0)
701 return -1; 731 return -1;
@@ -727,7 +757,7 @@ static int process_exit_event(struct perf_tool *tool,
727 struct thread *thread; 757 struct thread *thread;
728 struct perf_script *script = container_of(tool, struct perf_script, tool); 758 struct perf_script *script = container_of(tool, struct perf_script, tool);
729 struct perf_session *session = script->session; 759 struct perf_session *session = script->session;
730 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 760 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
731 761
732 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid); 762 thread = machine__findnew_thread(machine, event->fork.pid, event->fork.tid);
733 if (thread == NULL) { 763 if (thread == NULL) {
@@ -759,7 +789,7 @@ static int process_mmap_event(struct perf_tool *tool,
759 struct thread *thread; 789 struct thread *thread;
760 struct perf_script *script = container_of(tool, struct perf_script, tool); 790 struct perf_script *script = container_of(tool, struct perf_script, tool);
761 struct perf_session *session = script->session; 791 struct perf_session *session = script->session;
762 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 792 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
763 793
764 if (perf_event__process_mmap(tool, event, sample, machine) < 0) 794 if (perf_event__process_mmap(tool, event, sample, machine) < 0)
765 return -1; 795 return -1;
@@ -790,7 +820,7 @@ static int process_mmap2_event(struct perf_tool *tool,
790 struct thread *thread; 820 struct thread *thread;
791 struct perf_script *script = container_of(tool, struct perf_script, tool); 821 struct perf_script *script = container_of(tool, struct perf_script, tool);
792 struct perf_session *session = script->session; 822 struct perf_session *session = script->session;
793 struct perf_evsel *evsel = perf_evlist__first(session->evlist); 823 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
794 824
795 if (perf_event__process_mmap2(tool, event, sample, machine) < 0) 825 if (perf_event__process_mmap2(tool, event, sample, machine) < 0)
796 return -1; 826 return -1;
@@ -813,6 +843,32 @@ static int process_mmap2_event(struct perf_tool *tool,
813 return 0; 843 return 0;
814} 844}
815 845
846static int process_switch_event(struct perf_tool *tool,
847 union perf_event *event,
848 struct perf_sample *sample,
849 struct machine *machine)
850{
851 struct thread *thread;
852 struct perf_script *script = container_of(tool, struct perf_script, tool);
853 struct perf_session *session = script->session;
854 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
855
856 if (perf_event__process_switch(tool, event, sample, machine) < 0)
857 return -1;
858
859 thread = machine__findnew_thread(machine, sample->pid,
860 sample->tid);
861 if (thread == NULL) {
862 pr_debug("problem processing SWITCH event, skipping it.\n");
863 return -1;
864 }
865
866 print_sample_start(sample, thread, evsel);
867 perf_event__fprintf(event, stdout);
868 thread__put(thread);
869 return 0;
870}
871
816static void sig_handler(int sig __maybe_unused) 872static void sig_handler(int sig __maybe_unused)
817{ 873{
818 session_done = 1; 874 session_done = 1;
@@ -834,6 +890,8 @@ static int __cmd_script(struct perf_script *script)
834 script->tool.mmap = process_mmap_event; 890 script->tool.mmap = process_mmap_event;
835 script->tool.mmap2 = process_mmap2_event; 891 script->tool.mmap2 = process_mmap2_event;
836 } 892 }
893 if (script->show_switch_events)
894 script->tool.context_switch = process_switch_event;
837 895
838 ret = perf_session__process_events(script->session); 896 ret = perf_session__process_events(script->session);
839 897
@@ -1532,6 +1590,22 @@ static int have_cmd(int argc, const char **argv)
1532 return 0; 1590 return 0;
1533} 1591}
1534 1592
1593static void script__setup_sample_type(struct perf_script *script)
1594{
1595 struct perf_session *session = script->session;
1596 u64 sample_type = perf_evlist__combined_sample_type(session->evlist);
1597
1598 if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) {
1599 if ((sample_type & PERF_SAMPLE_REGS_USER) &&
1600 (sample_type & PERF_SAMPLE_STACK_USER))
1601 callchain_param.record_mode = CALLCHAIN_DWARF;
1602 else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
1603 callchain_param.record_mode = CALLCHAIN_LBR;
1604 else
1605 callchain_param.record_mode = CALLCHAIN_FP;
1606 }
1607}
1608
1535int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) 1609int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1536{ 1610{
1537 bool show_full_info = false; 1611 bool show_full_info = false;
@@ -1598,7 +1672,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1598 "comma separated output fields prepend with 'type:'. " 1672 "comma separated output fields prepend with 'type:'. "
1599 "Valid types: hw,sw,trace,raw. " 1673 "Valid types: hw,sw,trace,raw. "
1600 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 1674 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
1601 "addr,symoff,period,flags", parse_output_fields), 1675 "addr,symoff,period,iregs,flags", parse_output_fields),
1602 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1676 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1603 "system-wide collection from all CPUs"), 1677 "system-wide collection from all CPUs"),
1604 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 1678 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
@@ -1618,10 +1692,19 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1618 "Show the fork/comm/exit events"), 1692 "Show the fork/comm/exit events"),
1619 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events, 1693 OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
1620 "Show the mmap events"), 1694 "Show the mmap events"),
1695 OPT_BOOLEAN('\0', "show-switch-events", &script.show_switch_events,
1696 "Show context switch events (if recorded)"),
1621 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), 1697 OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
1622 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", 1698 OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts",
1623 "Instruction Tracing options", 1699 "Instruction Tracing options",
1624 itrace_parse_synth_opts), 1700 itrace_parse_synth_opts),
1701 OPT_BOOLEAN(0, "full-source-path", &srcline_full_filename,
1702 "Show full source file name path for source lines"),
1703 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
1704 "Enable symbol demangling"),
1705 OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
1706 "Enable kernel symbol demangling"),
1707
1625 OPT_END() 1708 OPT_END()
1626 }; 1709 };
1627 const char * const script_subcommands[] = { "record", "report", NULL }; 1710 const char * const script_subcommands[] = { "record", "report", NULL };
@@ -1816,6 +1899,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1816 goto out_delete; 1899 goto out_delete;
1817 1900
1818 script.session = session; 1901 script.session = session;
1902 script__setup_sample_type(&script);
1819 1903
1820 session->itrace_synth_opts = &itrace_synth_opts; 1904 session->itrace_synth_opts = &itrace_synth_opts;
1821 1905
@@ -1830,6 +1914,14 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
1830 else 1914 else
1831 symbol_conf.use_callchain = false; 1915 symbol_conf.use_callchain = false;
1832 1916
1917 if (session->tevent.pevent &&
1918 pevent_set_function_resolver(session->tevent.pevent,
1919 machine__resolve_kernel_addr,
1920 &session->machines.host) < 0) {
1921 pr_err("%s: failed to set libtraceevent function resolver\n", __func__);
1922 return -1;
1923 }
1924
1833 if (generate_script_lang) { 1925 if (generate_script_lang) {
1834 struct stat perf_stat; 1926 struct stat perf_stat;
1835 int input; 1927 int input;