perf ftrace: Detect workload failure
authorChangbin Du <changbin.du@gmail.com>
Sun, 10 May 2020 15:06:11 +0000 (23:06 +0800)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 28 May 2020 13:03:27 +0000 (10:03 -0300)
Currently there's no error message prompted if we failed to start
workload.  And we still get some trace which is confusing. Let's tell
users what happened.

Committer testing:

Before:

    # perf ftrace nonsense |& head
     5)               |  switch_mm_irqs_off() {
     5)   0.400 us    |    load_new_mm_cr3();
     5)   3.261 us    |  }
     ------------------------------------------
     5)    <idle>-0    =>   <...>-3494
     ------------------------------------------

     5)               |  finish_task_switch() {
     5)   ==========> |
     5)               |    smp_irq_work_interrupt() {
    # type nonsense
    -bash: type: nonsense: not found
    #

After:

  # perf ftrace nonsense |& head
  workload failed: No such file or directory
  # type nonsense
  -bash: type: nonsense: not found
  #

Signed-off-by: Changbin Du <changbin.du@gmail.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
Link: http://lore.kernel.org/lkml/20200510150628.16610-3-changbin.du@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-ftrace.c

index b7d3fb5..2bfc1b0 100644 (file)
@@ -45,6 +45,7 @@ struct filter_entry {
        char                    name[];
 };
 
+static volatile int workload_exec_errno;
 static bool done;
 
 static void sig_handler(int sig __maybe_unused)
@@ -63,7 +64,7 @@ static void ftrace__workload_exec_failed_signal(int signo __maybe_unused,
                                                siginfo_t *info __maybe_unused,
                                                void *ucontext __maybe_unused)
 {
-       /* workload_exec_errno = info->si_value.sival_int; */
+       workload_exec_errno = info->si_value.sival_int;
        done = true;
 }
 
@@ -383,6 +384,14 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
 
        write_tracing_file("tracing_on", "0");
 
+       if (workload_exec_errno) {
+               const char *emsg = str_error_r(workload_exec_errno, buf, sizeof(buf));
+               /* flush stdout first so below error msg appears at the end. */
+               fflush(stdout);
+               pr_err("workload failed: %s\n", emsg);
+               goto out_close_fd;
+       }
+
        /* read remaining buffer contents */
        while (true) {
                int n = read(trace_fd, buf, sizeof(buf));
@@ -397,7 +406,7 @@ out_close_fd:
 out_reset:
        reset_tracing_files(ftrace);
 out:
-       return done ? 0 : -1;
+       return (done && !workload_exec_errno) ? 0 : -1;
 }
 
 static int perf_ftrace_config(const char *var, const char *value, void *cb)