diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-03 12:56:49 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-13 08:06:21 -0500 |
commit | 735f7e0bbebe755d707182188c4a5e88c581fc1c (patch) | |
tree | f77574a5093cc1966004dd6ec81d9606d67631f2 /tools | |
parent | f33cbe72e6166b97d6fa2400cb00a885b47999d7 (diff) |
perf evlist: Move the SIGUSR1 error reporting logic to prepare_workload
So that we have the boilerplate in the preparation method, instead of
open coded in tools wanting the reporting when the exec fails.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-purbdzcphdveskh7wwmnm4t7@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-record.c | 16 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 17 | ||||
-rw-r--r-- | tools/perf/builtin-trace.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/perf-record.c | 3 | ||||
-rw-r--r-- | tools/perf/tests/task-exit.c | 19 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 12 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 3 |
7 files changed, 32 insertions, 40 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f987d385c6f0..ea7c3060e8e7 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -390,7 +390,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
390 | if (forks) { | 390 | if (forks) { |
391 | err = perf_evlist__prepare_workload(evsel_list, &opts->target, | 391 | err = perf_evlist__prepare_workload(evsel_list, &opts->target, |
392 | argv, file->is_pipe, | 392 | argv, file->is_pipe, |
393 | true); | 393 | workload_exec_failed_signal); |
394 | if (err < 0) { | 394 | if (err < 0) { |
395 | pr_err("Couldn't run the workload!\n"); | 395 | pr_err("Couldn't run the workload!\n"); |
396 | goto out_delete_session; | 396 | goto out_delete_session; |
@@ -507,20 +507,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) | |||
507 | /* | 507 | /* |
508 | * Let the child rip | 508 | * Let the child rip |
509 | */ | 509 | */ |
510 | if (forks) { | 510 | if (forks) |
511 | struct sigaction act = { | ||
512 | .sa_flags = SA_SIGINFO, | ||
513 | .sa_sigaction = workload_exec_failed_signal, | ||
514 | }; | ||
515 | /* | ||
516 | * perf_evlist__prepare_workload will, after we call | ||
517 | * perf_evlist__start_Workload, send a SIGUSR1 if the exec call | ||
518 | * fails, that we will catch in workload_signal to flip | ||
519 | * workload_exec_errno. | ||
520 | */ | ||
521 | sigaction(SIGUSR1, &act, NULL); | ||
522 | perf_evlist__start_workload(evsel_list); | 511 | perf_evlist__start_workload(evsel_list); |
523 | } | ||
524 | 512 | ||
525 | for (;;) { | 513 | for (;;) { |
526 | int hits = rec->samples; | 514 | int hits = rec->samples; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 9d0d52d55ee6..f8456cad656d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -58,7 +58,6 @@ | |||
58 | #include "util/thread.h" | 58 | #include "util/thread.h" |
59 | #include "util/thread_map.h" | 59 | #include "util/thread_map.h" |
60 | 60 | ||
61 | #include <signal.h> | ||
62 | #include <stdlib.h> | 61 | #include <stdlib.h> |
63 | #include <sys/prctl.h> | 62 | #include <sys/prctl.h> |
64 | #include <locale.h> | 63 | #include <locale.h> |
@@ -542,8 +541,8 @@ static int __run_perf_stat(int argc, const char **argv) | |||
542 | } | 541 | } |
543 | 542 | ||
544 | if (forks) { | 543 | if (forks) { |
545 | if (perf_evlist__prepare_workload(evsel_list, &target, argv, | 544 | if (perf_evlist__prepare_workload(evsel_list, &target, argv, false, |
546 | false, true) < 0) { | 545 | workload_exec_failed_signal) < 0) { |
547 | perror("failed to prepare workload"); | 546 | perror("failed to prepare workload"); |
548 | return -1; | 547 | return -1; |
549 | } | 548 | } |
@@ -598,18 +597,6 @@ static int __run_perf_stat(int argc, const char **argv) | |||
598 | clock_gettime(CLOCK_MONOTONIC, &ref_time); | 597 | clock_gettime(CLOCK_MONOTONIC, &ref_time); |
599 | 598 | ||
600 | if (forks) { | 599 | if (forks) { |
601 | struct sigaction act = { | ||
602 | .sa_flags = SA_SIGINFO, | ||
603 | .sa_sigaction = workload_exec_failed_signal, | ||
604 | }; | ||
605 | /* | ||
606 | * perf_evlist__prepare_workload will, after we call | ||
607 | * perf_evlist__start_Workload, send a SIGUSR1 if the exec call | ||
608 | * fails, that we will catch in workload_signal to flip | ||
609 | * workload_exec_errno. | ||
610 | */ | ||
611 | sigaction(SIGUSR1, &act, NULL); | ||
612 | |||
613 | perf_evlist__start_workload(evsel_list); | 600 | perf_evlist__start_workload(evsel_list); |
614 | handle_initial_delay(); | 601 | handle_initial_delay(); |
615 | 602 | ||
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c5b4bc51175c..5498eacf8fc6 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -1895,7 +1895,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) | |||
1895 | 1895 | ||
1896 | if (forks) { | 1896 | if (forks) { |
1897 | err = perf_evlist__prepare_workload(evlist, &trace->opts.target, | 1897 | err = perf_evlist__prepare_workload(evlist, &trace->opts.target, |
1898 | argv, false, false); | 1898 | argv, false, NULL); |
1899 | if (err < 0) { | 1899 | if (err < 0) { |
1900 | fprintf(trace->output, "Couldn't run the workload!\n"); | 1900 | fprintf(trace->output, "Couldn't run the workload!\n"); |
1901 | goto out_delete_maps; | 1901 | goto out_delete_maps; |
diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index eeba562920e9..fa0ed35afb9a 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c | |||
@@ -83,8 +83,7 @@ int test__PERF_RECORD(void) | |||
83 | * so that we have time to open the evlist (calling sys_perf_event_open | 83 | * so that we have time to open the evlist (calling sys_perf_event_open |
84 | * on all the fds) and then mmap them. | 84 | * on all the fds) and then mmap them. |
85 | */ | 85 | */ |
86 | err = perf_evlist__prepare_workload(evlist, &opts.target, argv, | 86 | err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL); |
87 | false, false); | ||
88 | if (err < 0) { | 87 | if (err < 0) { |
89 | pr_debug("Couldn't run the workload!\n"); | 88 | pr_debug("Couldn't run the workload!\n"); |
90 | goto out_delete_maps; | 89 | goto out_delete_maps; |
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index d09ab579119e..44e339d4e297 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c | |||
@@ -9,12 +9,21 @@ | |||
9 | static int exited; | 9 | static int exited; |
10 | static int nr_exit; | 10 | static int nr_exit; |
11 | 11 | ||
12 | static void sig_handler(int sig) | 12 | static void sig_handler(int sig __maybe_unused) |
13 | { | 13 | { |
14 | exited = 1; | 14 | exited = 1; |
15 | } | ||
15 | 16 | ||
16 | if (sig == SIGUSR1) | 17 | /* |
17 | nr_exit = -1; | 18 | * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since |
19 | * we asked by setting its exec_error to this handler. | ||
20 | */ | ||
21 | static void workload_exec_failed_signal(int signo __maybe_unused, | ||
22 | siginfo_t *info __maybe_unused, | ||
23 | void *ucontext __maybe_unused) | ||
24 | { | ||
25 | exited = 1; | ||
26 | nr_exit = -1; | ||
18 | } | 27 | } |
19 | 28 | ||
20 | /* | 29 | /* |
@@ -35,7 +44,6 @@ int test__task_exit(void) | |||
35 | const char *argv[] = { "true", NULL }; | 44 | const char *argv[] = { "true", NULL }; |
36 | 45 | ||
37 | signal(SIGCHLD, sig_handler); | 46 | signal(SIGCHLD, sig_handler); |
38 | signal(SIGUSR1, sig_handler); | ||
39 | 47 | ||
40 | evlist = perf_evlist__new_default(); | 48 | evlist = perf_evlist__new_default(); |
41 | if (evlist == NULL) { | 49 | if (evlist == NULL) { |
@@ -57,7 +65,8 @@ int test__task_exit(void) | |||
57 | goto out_delete_maps; | 65 | goto out_delete_maps; |
58 | } | 66 | } |
59 | 67 | ||
60 | err = perf_evlist__prepare_workload(evlist, &target, argv, false, true); | 68 | err = perf_evlist__prepare_workload(evlist, &target, argv, false, |
69 | workload_exec_failed_signal); | ||
61 | if (err < 0) { | 70 | if (err < 0) { |
62 | pr_debug("Couldn't run the workload!\n"); | 71 | pr_debug("Couldn't run the workload!\n"); |
63 | goto out_delete_maps; | 72 | goto out_delete_maps; |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4a30c87d24ec..96b3ef547db4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -1029,7 +1029,7 @@ out_err: | |||
1029 | 1029 | ||
1030 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, | 1030 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, |
1031 | const char *argv[], bool pipe_output, | 1031 | const char *argv[], bool pipe_output, |
1032 | bool want_signal) | 1032 | void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) |
1033 | { | 1033 | { |
1034 | int child_ready_pipe[2], go_pipe[2]; | 1034 | int child_ready_pipe[2], go_pipe[2]; |
1035 | char bf; | 1035 | char bf; |
@@ -1073,7 +1073,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar | |||
1073 | 1073 | ||
1074 | execvp(argv[0], (char **)argv); | 1074 | execvp(argv[0], (char **)argv); |
1075 | 1075 | ||
1076 | if (want_signal) { | 1076 | if (exec_error) { |
1077 | union sigval val; | 1077 | union sigval val; |
1078 | 1078 | ||
1079 | val.sival_int = errno; | 1079 | val.sival_int = errno; |
@@ -1084,6 +1084,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar | |||
1084 | exit(-1); | 1084 | exit(-1); |
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | if (exec_error) { | ||
1088 | struct sigaction act = { | ||
1089 | .sa_flags = SA_SIGINFO, | ||
1090 | .sa_sigaction = exec_error, | ||
1091 | }; | ||
1092 | sigaction(SIGUSR1, &act, NULL); | ||
1093 | } | ||
1094 | |||
1087 | if (target__none(target)) | 1095 | if (target__none(target)) |
1088 | evlist->threads->map[0] = evlist->workload.pid; | 1096 | evlist->threads->map[0] = evlist->workload.pid; |
1089 | 1097 | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 2fe51958ed85..18d1222c0762 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -103,7 +103,8 @@ int record_opts__config(struct record_opts *opts); | |||
103 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, | 103 | int perf_evlist__prepare_workload(struct perf_evlist *evlist, |
104 | struct target *target, | 104 | struct target *target, |
105 | const char *argv[], bool pipe_output, | 105 | const char *argv[], bool pipe_output, |
106 | bool want_signal); | 106 | void (*exec_error)(int signo, siginfo_t *info, |
107 | void *ucontext)); | ||
107 | int perf_evlist__start_workload(struct perf_evlist *evlist); | 108 | int perf_evlist__start_workload(struct perf_evlist *evlist); |
108 | 109 | ||
109 | int perf_evlist__parse_mmap_pages(const struct option *opt, | 110 | int perf_evlist__parse_mmap_pages(const struct option *opt, |