Merge tag 'kvm-s390-master-6.8-1' of https://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / tools / perf / builtin-report.c
index 9cb1da2..f2ed2b7 100644 (file)
@@ -96,9 +96,9 @@ struct report {
        bool                    stitch_lbr;
        bool                    disable_order;
        bool                    skip_empty;
+       bool                    data_type;
        int                     max_stack;
        struct perf_read_values show_threads_values;
-       struct annotation_options annotation_opts;
        const char              *pretty_printing_style;
        const char              *cpu_list;
        const char              *symbol_filter_str;
@@ -171,7 +171,7 @@ static int hist_iter__report_callback(struct hist_entry_iter *iter,
        struct mem_info *mi;
        struct branch_info *bi;
 
-       if (!ui__has_annotation() && !rep->symbol_ipc)
+       if (!ui__has_annotation() && !rep->symbol_ipc && !rep->data_type)
                return 0;
 
        if (sort__mode == SORT_MODE__BRANCH) {
@@ -541,8 +541,7 @@ static int evlist__tui_block_hists_browse(struct evlist *evlist, struct report *
        evlist__for_each_entry(evlist, pos) {
                ret = report__browse_block_hists(&rep->block_reports[i++].hist,
                                                 rep->min_percent, pos,
-                                                &rep->session->header.env,
-                                                &rep->annotation_opts);
+                                                &rep->session->header.env);
                if (ret != 0)
                        return ret;
        }
@@ -574,8 +573,7 @@ static int evlist__tty_browse_hists(struct evlist *evlist, struct report *rep, c
 
                if (rep->total_cycles_mode) {
                        report__browse_block_hists(&rep->block_reports[i++].hist,
-                                                  rep->min_percent, pos,
-                                                  NULL, NULL);
+                                                  rep->min_percent, pos, NULL);
                        continue;
                }
 
@@ -670,7 +668,7 @@ static int report__browse_hists(struct report *rep)
                }
 
                ret = evlist__tui_browse_hists(evlist, help, NULL, rep->min_percent,
-                                              &session->header.env, true, &rep->annotation_opts);
+                                              &session->header.env, true);
                /*
                 * Usually "ret" is the last pressed key, and we only
                 * care if the key notifies us to switch data file.
@@ -745,7 +743,7 @@ static int hists__resort_cb(struct hist_entry *he, void *arg)
        if (rep->symbol_ipc && sym && !sym->annotate2) {
                struct evsel *evsel = hists_to_evsel(he->hists);
 
-               symbol__annotate2(&he->ms, evsel, &rep->annotation_opts, NULL);
+               symbol__annotate2(&he->ms, evsel, NULL);
        }
 
        return 0;
@@ -859,27 +857,47 @@ static struct task *tasks_list(struct task *task, struct machine *machine)
        return tasks_list(parent_task, machine);
 }
 
-static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
+struct maps__fprintf_task_args {
+       int indent;
+       FILE *fp;
+       size_t printed;
+};
+
+static int maps__fprintf_task_cb(struct map *map, void *data)
 {
-       size_t printed = 0;
-       struct map_rb_node *rb_node;
+       struct maps__fprintf_task_args *args = data;
+       const struct dso *dso = map__dso(map);
+       u32 prot = map__prot(map);
+       int ret;
 
-       maps__for_each_entry(maps, rb_node) {
-               struct map *map = rb_node->map;
-               const struct dso *dso = map__dso(map);
-               u32 prot = map__prot(map);
+       ret = fprintf(args->fp,
+               "%*s  %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
+               args->indent, "", map__start(map), map__end(map),
+               prot & PROT_READ ? 'r' : '-',
+               prot & PROT_WRITE ? 'w' : '-',
+               prot & PROT_EXEC ? 'x' : '-',
+               map__flags(map) ? 's' : 'p',
+               map__pgoff(map),
+               dso->id.ino, dso->name);
 
-               printed += fprintf(fp, "%*s  %" PRIx64 "-%" PRIx64 " %c%c%c%c %08" PRIx64 " %" PRIu64 " %s\n",
-                                  indent, "", map__start(map), map__end(map),
-                                  prot & PROT_READ ? 'r' : '-',
-                                  prot & PROT_WRITE ? 'w' : '-',
-                                  prot & PROT_EXEC ? 'x' : '-',
-                                  map__flags(map) ? 's' : 'p',
-                                  map__pgoff(map),
-                                  dso->id.ino, dso->name);
-       }
+       if (ret < 0)
+               return ret;
+
+       args->printed += ret;
+       return 0;
+}
+
+static size_t maps__fprintf_task(struct maps *maps, int indent, FILE *fp)
+{
+       struct maps__fprintf_task_args args = {
+               .indent = indent,
+               .fp = fp,
+               .printed = 0,
+       };
 
-       return printed;
+       maps__for_each_map(maps, maps__fprintf_task_cb, &args);
+
+       return args.printed;
 }
 
 static void task__print_level(struct task *task, FILE *fp, int level)
@@ -1341,15 +1359,15 @@ int cmd_report(int argc, const char **argv)
                   "list of cpus to profile"),
        OPT_BOOLEAN('I', "show-info", &report.show_full_info,
                    "Display extended information about perf.data file"),
-       OPT_BOOLEAN(0, "source", &report.annotation_opts.annotate_src,
+       OPT_BOOLEAN(0, "source", &annotate_opts.annotate_src,
                    "Interleave source code with assembly code (default)"),
-       OPT_BOOLEAN(0, "asm-raw", &report.annotation_opts.show_asm_raw,
+       OPT_BOOLEAN(0, "asm-raw", &annotate_opts.show_asm_raw,
                    "Display raw encoding of assembly instructions (default)"),
        OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
                   "Specify disassembler style (e.g. -M intel for intel syntax)"),
-       OPT_STRING(0, "prefix", &report.annotation_opts.prefix, "prefix",
+       OPT_STRING(0, "prefix", &annotate_opts.prefix, "prefix",
                    "Add prefix to source file path names in programs (with --prefix-strip)"),
-       OPT_STRING(0, "prefix-strip", &report.annotation_opts.prefix_strip, "N",
+       OPT_STRING(0, "prefix-strip", &annotate_opts.prefix_strip, "N",
                    "Strip first N entries of source file path name in programs (with --prefix)"),
        OPT_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
                    "Show a column with the sum of periods"),
@@ -1401,7 +1419,7 @@ int cmd_report(int argc, const char **argv)
                   "Time span of interest (start,stop)"),
        OPT_BOOLEAN(0, "inline", &symbol_conf.inline_name,
                    "Show inline function"),
-       OPT_CALLBACK(0, "percent-type", &report.annotation_opts, "local-period",
+       OPT_CALLBACK(0, "percent-type", &annotate_opts, "local-period",
                     "Set percent type local/global-period/hits",
                     annotate_parse_percent_type),
        OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, "Show times in nanosecs"),
@@ -1426,7 +1444,14 @@ int cmd_report(int argc, const char **argv)
        if (ret < 0)
                goto exit;
 
-       annotation_options__init(&report.annotation_opts);
+       /*
+        * tasks_mode require access to exited threads to list those that are in
+        * the data file. Off-cpu events are synthesized after other events and
+        * reference exited threads.
+        */
+       symbol_conf.keep_exited_threads = true;
+
+       annotation_options__init();
 
        ret = perf_config(report__config, &report);
        if (ret)
@@ -1445,13 +1470,13 @@ int cmd_report(int argc, const char **argv)
        }
 
        if (disassembler_style) {
-               report.annotation_opts.disassembler_style = strdup(disassembler_style);
-               if (!report.annotation_opts.disassembler_style)
+               annotate_opts.disassembler_style = strdup(disassembler_style);
+               if (!annotate_opts.disassembler_style)
                        return -ENOMEM;
        }
        if (objdump_path) {
-               report.annotation_opts.objdump_path = strdup(objdump_path);
-               if (!report.annotation_opts.objdump_path)
+               annotate_opts.objdump_path = strdup(objdump_path);
+               if (!annotate_opts.objdump_path)
                        return -ENOMEM;
        }
        if (addr2line_path) {
@@ -1460,7 +1485,7 @@ int cmd_report(int argc, const char **argv)
                        return -ENOMEM;
        }
 
-       if (annotate_check_args(&report.annotation_opts) < 0) {
+       if (annotate_check_args() < 0) {
                ret = -EINVAL;
                goto exit;
        }
@@ -1615,6 +1640,16 @@ repeat:
                        sort_order = NULL;
        }
 
+       if (sort_order && strstr(sort_order, "type")) {
+               report.data_type = true;
+               annotate_opts.annotate_src = false;
+
+#ifndef HAVE_DWARF_GETLOCATIONS_SUPPORT
+               pr_err("Error: Data type profiling is disabled due to missing DWARF support\n");
+               goto error;
+#endif
+       }
+
        if (strcmp(input_name, "-") != 0)
                setup_browser(true);
        else
@@ -1673,7 +1708,7 @@ repeat:
         * so don't allocate extra space that won't be used in the stdio
         * implementation.
         */
-       if (ui__has_annotation() || report.symbol_ipc ||
+       if (ui__has_annotation() || report.symbol_ipc || report.data_type ||
            report.total_cycles_mode) {
                ret = symbol__annotation_init();
                if (ret < 0)
@@ -1692,7 +1727,7 @@ repeat:
                         */
                        symbol_conf.priv_size += sizeof(u32);
                }
-               annotation_config__init(&report.annotation_opts);
+               annotation_config__init();
        }
 
        if (symbol__init(&session->header.env) < 0)
@@ -1746,7 +1781,7 @@ error:
        zstd_fini(&(session->zstd_data));
        perf_session__delete(session);
 exit:
-       annotation_options__exit(&report.annotation_opts);
+       annotation_options__exit();
        free(sort_order_help);
        free(field_order_help);
        return ret;