]> git.itanic.dy.fi Git - linux-stable/commitdiff
perf report: Fix hierarchy mode on pipe input
authorNamhyung Kim <namhyung@kernel.org>
Wed, 25 Oct 2023 00:31:21 +0000 (17:31 -0700)
committerNamhyung Kim <namhyung@kernel.org>
Wed, 25 Oct 2023 17:04:19 +0000 (10:04 -0700)
The hierarchy mode needs to setup output formats for each evsel.
Normally setup_sorting() handles this at the beginning, but it cannot
do that if data comes from a pipe since there's no evsel info before
reading the data.  And then perf report cannot process the samples
in hierarchy mode and think as if there's no sample.

Let's check the condition and setup the output formats after reading
data so that it can find evsels.

Before:

  $ ./perf record -o- true | ./perf report -i- --hierarchy -q
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.000 MB - ]
  Error:
  The - data has no samples!

After:

  $ ./perf record -o- true | ./perf report -i- --hierarchy -q
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.000 MB - ]
      94.76%        true
         94.76%        [kernel.kallsyms]
            94.76%        [k] filemap_fault
       5.24%        perf-ex
          5.24%        [kernel.kallsyms]
             5.06%        [k] __memset
             0.18%        [k] native_write_msr

Acked-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20231025003121.2811738-1-namhyung@kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/builtin-report.c

index dcedfe00f04dbd7d5bfb4a3f36529b2d4f7c986e..ca8f2331795c6cd4dc4681a3b90e43d61ee8d3b4 100644 (file)
@@ -691,10 +691,25 @@ static int report__browse_hists(struct report *rep)
 
 static int report__collapse_hists(struct report *rep)
 {
+       struct perf_session *session = rep->session;
+       struct evlist *evlist = session->evlist;
        struct ui_progress prog;
        struct evsel *pos;
        int ret = 0;
 
+       /*
+        * The pipe data needs to setup hierarchy hpp formats now, because it
+        * cannot know about evsels in the data before reading the data.  The
+        * normal file data saves the event (attribute) info in the header
+        * section, but pipe does not have the luxury.
+        */
+       if (perf_data__is_pipe(session->data)) {
+               if (perf_hpp__setup_hists_formats(&perf_hpp_list, evlist) < 0) {
+                       ui__error("Failed to setup hierachy output formats\n");
+                       return -1;
+               }
+       }
+
        ui_progress__init(&prog, rep->nr_entries, "Merging related events...");
 
        evlist__for_each_entry(rep->session->evlist, pos) {