]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - tools/perf/builtin-script.c
perf script: Add output of IPC ratio
[linux.git] / tools / perf / builtin-script.c
index 61cfd8f70989235de6112e114925d08831b505dc..80c722ade852f97499eab992aab6ff7d8e886239 100644 (file)
@@ -102,6 +102,7 @@ enum perf_output_field {
        PERF_OUTPUT_METRIC          = 1U << 28,
        PERF_OUTPUT_MISC            = 1U << 29,
        PERF_OUTPUT_SRCCODE         = 1U << 30,
+       PERF_OUTPUT_IPC             = 1U << 31,
 };
 
 struct output_option {
@@ -139,6 +140,7 @@ struct output_option {
        {.str = "metric", .field = PERF_OUTPUT_METRIC},
        {.str = "misc", .field = PERF_OUTPUT_MISC},
        {.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
+       {.str = "ipc", .field = PERF_OUTPUT_IPC},
 };
 
 enum {
@@ -1268,6 +1270,20 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample,
        return printed;
 }
 
+static int perf_sample__fprintf_ipc(struct perf_sample *sample,
+                                   struct perf_event_attr *attr, FILE *fp)
+{
+       unsigned int ipc;
+
+       if (!PRINT_FIELD(IPC) || !sample->cyc_cnt || !sample->insn_cnt)
+               return 0;
+
+       ipc = (sample->insn_cnt * 100) / sample->cyc_cnt;
+
+       return fprintf(fp, " \t IPC: %u.%02u (%" PRIu64 "/%" PRIu64 ") ",
+                      ipc / 100, ipc % 100, sample->insn_cnt, sample->cyc_cnt);
+}
+
 static int perf_sample__fprintf_bts(struct perf_sample *sample,
                                    struct perf_evsel *evsel,
                                    struct thread *thread,
@@ -1312,6 +1328,8 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample,
                printed += perf_sample__fprintf_addr(sample, thread, attr, fp);
        }
 
+       printed += perf_sample__fprintf_ipc(sample, attr, fp);
+
        if (print_srcline_last)
                printed += map__fprintf_srcline(al->map, al->addr, "\n  ", fp);
 
@@ -1606,6 +1624,7 @@ struct perf_script {
        bool                    show_namespace_events;
        bool                    show_lost_events;
        bool                    show_round_events;
+       bool                    show_bpf_events;
        bool                    allocated;
        bool                    per_event_dump;
        struct cpu_map          *cpus;
@@ -1858,6 +1877,9 @@ static void process_event(struct perf_script *script,
 
        if (PRINT_FIELD(PHYS_ADDR))
                fprintf(fp, "%16" PRIx64, sample->phys_addr);
+
+       perf_sample__fprintf_ipc(sample, attr, fp);
+
        fprintf(fp, "\n");
 
        if (PRINT_FIELD(SRCCODE)) {
@@ -2318,6 +2340,41 @@ process_finished_round_event(struct perf_tool *tool __maybe_unused,
        return 0;
 }
 
+static int
+process_bpf_events(struct perf_tool *tool __maybe_unused,
+                  union perf_event *event,
+                  struct perf_sample *sample,
+                  struct machine *machine)
+{
+       struct thread *thread;
+       struct perf_script *script = container_of(tool, struct perf_script, tool);
+       struct perf_session *session = script->session;
+       struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+
+       if (machine__process_ksymbol(machine, event, sample) < 0)
+               return -1;
+
+       if (!evsel->attr.sample_id_all) {
+               perf_event__fprintf(event, stdout);
+               return 0;
+       }
+
+       thread = machine__findnew_thread(machine, sample->pid, sample->tid);
+       if (thread == NULL) {
+               pr_debug("problem processing MMAP event, skipping it.\n");
+               return -1;
+       }
+
+       if (!filter_cpu(sample)) {
+               perf_sample__fprintf_start(sample, thread, evsel,
+                                          event->header.type, stdout);
+               perf_event__fprintf(event, stdout);
+       }
+
+       thread__put(thread);
+       return 0;
+}
+
 static void sig_handler(int sig __maybe_unused)
 {
        session_done = 1;
@@ -2420,6 +2477,10 @@ static int __cmd_script(struct perf_script *script)
                script->tool.ordered_events = false;
                script->tool.finished_round = process_finished_round_event;
        }
+       if (script->show_bpf_events) {
+               script->tool.ksymbol   = process_bpf_events;
+               script->tool.bpf_event = process_bpf_events;
+       }
 
        if (perf_script__setup_per_event_dump(script)) {
                pr_err("Couldn't create the per event dump files\n");
@@ -3297,6 +3358,7 @@ static int parse_call_trace(const struct option *opt __maybe_unused,
        parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0);
        itrace_parse_synth_opts(opt, "cewp", 0);
        symbol_conf.nanosecs = true;
+       symbol_conf.pad_output_len_dso = 50;
        return 0;
 }
 
@@ -3392,7 +3454,7 @@ int cmd_script(int argc, const char **argv)
                     "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
                     "addr,symoff,srcline,period,iregs,uregs,brstack,"
                     "brstacksym,flags,bpf-output,brstackinsn,brstackoff,"
-                    "callindent,insn,insnlen,synth,phys_addr,metric,misc",
+                    "callindent,insn,insnlen,synth,phys_addr,metric,misc,ipc",
                     parse_output_fields),
        OPT_BOOLEAN('a', "all-cpus", &system_wide,
                    "system-wide collection from all CPUs"),
@@ -3438,6 +3500,8 @@ int cmd_script(int argc, const char **argv)
                    "Show lost events (if recorded)"),
        OPT_BOOLEAN('\0', "show-round-events", &script.show_round_events,
                    "Show round events (if recorded)"),
+       OPT_BOOLEAN('\0', "show-bpf-events", &script.show_bpf_events,
+                   "Show bpf related events (if recorded)"),
        OPT_BOOLEAN('\0', "per-event-dump", &script.per_event_dump,
                    "Dump trace output to files named by the monitored events"),
        OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),