From 6af206fd911c825b83dd4efb2534a3a34ce77072 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sat, 28 Dec 2013 15:45:08 -0300 Subject: perf stat: Don't show counter information when workload fails When starting a workload 'stat' wasn't using prepare_workload evlist method's signal based exec() error reporting mechanism. Use it so that the we don't report 'not counted' counters. Before: [acme@zoo linux]$ perf stat dfadsfa dfadsfa: No such file or directory Performance counter stats for 'dfadsfa': task-clock context-switches cpu-migrations page-faults cycles stalled-cycles-frontend stalled-cycles-backend instructions branches branch-misses 0.001831462 seconds time elapsed [acme@zoo linux]$ After: [acme@zoo linux]$ perf stat dfadsfa dfadsfa: No such file or directory [acme@zoo linux]$ Reported-by: David Ahern Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-5yui3bv7e3hitxucnjsn6z8q@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 106a5e5..1c76c7a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -509,6 +509,18 @@ static void handle_initial_delay(void) } } +static volatile bool workload_exec_failed; + +/* + * perf_evlist__prepare_workload will send a SIGUSR1 + * if the fork fails, since we asked by setting its + * want_signal to true. + */ +static void workload_exec_failed_signal(int signo __maybe_unused) +{ + workload_exec_failed = true; +} + static int __run_perf_stat(int argc, const char **argv) { char msg[512]; @@ -529,7 +541,7 @@ static int __run_perf_stat(int argc, const char **argv) if (forks) { if (perf_evlist__prepare_workload(evsel_list, &target, argv, - false, false) < 0) { + false, true) < 0) { perror("failed to prepare workload"); return -1; } @@ -584,6 +596,14 @@ static int __run_perf_stat(int argc, const char **argv) clock_gettime(CLOCK_MONOTONIC, &ref_time); if (forks) { + /* + * perf_evlist__prepare_workload will, after we call + * perf_evlist__start_Workload, send a SIGUSR1 if the exec call + * fails, that we will catch in workload_signal to flip + * workload_exec_failed. + */ + signal(SIGUSR1, workload_exec_failed_signal); + perf_evlist__start_workload(evsel_list); handle_initial_delay(); @@ -594,6 +614,10 @@ static int __run_perf_stat(int argc, const char **argv) } } wait(&status); + + if (workload_exec_failed) + return -1; + if (WIFSIGNALED(status)) psignal(WTERMSIG(status), argv[0]); } else { -- cgit v0.10.2 From f33cbe72e6166b97d6fa2400cb00a885b47999d7 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 2 Jan 2014 15:11:25 -0300 Subject: perf evlist: Send the errno in the signal when workload fails When a tool uses perf_evlist__start_workload and the supplied workload fails (e.g.: its binary wasn't found), perror was being used to print the error reason. This is undesirable, as the caller may be a GUI, when it wants to have total control of the error reporting process. So move to using sigaction(SA_SIGINFO) + siginfo_t->sa_value->sival_int to communicate to the caller the errno and let it print it using the UI of its choosing. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-epgcv7kjq8ll2udqfken92pz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6ec0cbc..f987d38 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -341,6 +341,22 @@ static void record__init_features(struct record *rec) perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); } +static volatile int workload_exec_errno; + +/* + * perf_evlist__prepare_workload will send a SIGUSR1 + * if the fork fails, since we asked by setting its + * want_signal to true. + */ +static void workload_exec_failed_signal(int signo, siginfo_t *info, + void *ucontext __maybe_unused) +{ + workload_exec_errno = info->si_value.sival_int; + done = 1; + signr = signo; + child_finished = 1; +} + static int __cmd_record(struct record *rec, int argc, const char **argv) { int err; @@ -359,7 +375,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) on_exit(record__sig_exit, rec); signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); - signal(SIGUSR1, sig_handler); signal(SIGTERM, sig_handler); session = perf_session__new(file, false, NULL); @@ -492,8 +507,20 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) /* * Let the child rip */ - if (forks) + if (forks) { + struct sigaction act = { + .sa_flags = SA_SIGINFO, + .sa_sigaction = workload_exec_failed_signal, + }; + /* + * perf_evlist__prepare_workload will, after we call + * perf_evlist__start_Workload, send a SIGUSR1 if the exec call + * fails, that we will catch in workload_signal to flip + * workload_exec_errno. + */ + sigaction(SIGUSR1, &act, NULL); perf_evlist__start_workload(evsel_list); + } for (;;) { int hits = rec->samples; @@ -521,6 +548,14 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } } + if (forks && workload_exec_errno) { + char msg[512]; + const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); + pr_err("Workload failed: %s\n", emsg); + err = -1; + goto out_delete_session; + } + if (quiet || signr == SIGUSR1) return 0; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 1c76c7a..9d0d52d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -58,6 +58,7 @@ #include "util/thread.h" #include "util/thread_map.h" +#include #include #include #include @@ -509,16 +510,17 @@ static void handle_initial_delay(void) } } -static volatile bool workload_exec_failed; +static volatile int workload_exec_errno; /* * perf_evlist__prepare_workload will send a SIGUSR1 * if the fork fails, since we asked by setting its * want_signal to true. */ -static void workload_exec_failed_signal(int signo __maybe_unused) +static void workload_exec_failed_signal(int signo __maybe_unused, siginfo_t *info, + void *ucontext __maybe_unused) { - workload_exec_failed = true; + workload_exec_errno = info->si_value.sival_int; } static int __run_perf_stat(int argc, const char **argv) @@ -596,13 +598,17 @@ static int __run_perf_stat(int argc, const char **argv) clock_gettime(CLOCK_MONOTONIC, &ref_time); if (forks) { + struct sigaction act = { + .sa_flags = SA_SIGINFO, + .sa_sigaction = workload_exec_failed_signal, + }; /* * perf_evlist__prepare_workload will, after we call * perf_evlist__start_Workload, send a SIGUSR1 if the exec call * fails, that we will catch in workload_signal to flip - * workload_exec_failed. + * workload_exec_errno. */ - signal(SIGUSR1, workload_exec_failed_signal); + sigaction(SIGUSR1, &act, NULL); perf_evlist__start_workload(evsel_list); handle_initial_delay(); @@ -615,8 +621,11 @@ static int __run_perf_stat(int argc, const char **argv) } wait(&status); - if (workload_exec_failed) + if (workload_exec_errno) { + const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); + pr_err("Workload failed: %s\n", emsg); return -1; + } if (WIFSIGNALED(status)) psignal(WTERMSIG(status), argv[0]); diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b08a7ec..4a30c87 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1073,9 +1073,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar execvp(argv[0], (char **)argv); - perror(argv[0]); - if (want_signal) - kill(getppid(), SIGUSR1); + if (want_signal) { + union sigval val; + + val.sival_int = errno; + if (sigqueue(getppid(), SIGUSR1, val)) + perror(argv[0]); + } else + perror(argv[0]); exit(-1); } -- cgit v0.10.2 From 735f7e0bbebe755d707182188c4a5e88c581fc1c Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 14:56:49 -0300 Subject: 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 Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-purbdzcphdveskh7wwmnm4t7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f987d38..ea7c306 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) if (forks) { err = perf_evlist__prepare_workload(evsel_list, &opts->target, argv, file->is_pipe, - true); + workload_exec_failed_signal); if (err < 0) { pr_err("Couldn't run the workload!\n"); goto out_delete_session; @@ -507,20 +507,8 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) /* * Let the child rip */ - if (forks) { - struct sigaction act = { - .sa_flags = SA_SIGINFO, - .sa_sigaction = workload_exec_failed_signal, - }; - /* - * perf_evlist__prepare_workload will, after we call - * perf_evlist__start_Workload, send a SIGUSR1 if the exec call - * fails, that we will catch in workload_signal to flip - * workload_exec_errno. - */ - sigaction(SIGUSR1, &act, NULL); + if (forks) perf_evlist__start_workload(evsel_list); - } for (;;) { int hits = rec->samples; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 9d0d52d..f8456ca 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -58,7 +58,6 @@ #include "util/thread.h" #include "util/thread_map.h" -#include #include #include #include @@ -542,8 +541,8 @@ static int __run_perf_stat(int argc, const char **argv) } if (forks) { - if (perf_evlist__prepare_workload(evsel_list, &target, argv, - false, true) < 0) { + if (perf_evlist__prepare_workload(evsel_list, &target, argv, false, + workload_exec_failed_signal) < 0) { perror("failed to prepare workload"); return -1; } @@ -598,18 +597,6 @@ static int __run_perf_stat(int argc, const char **argv) clock_gettime(CLOCK_MONOTONIC, &ref_time); if (forks) { - struct sigaction act = { - .sa_flags = SA_SIGINFO, - .sa_sigaction = workload_exec_failed_signal, - }; - /* - * perf_evlist__prepare_workload will, after we call - * perf_evlist__start_Workload, send a SIGUSR1 if the exec call - * fails, that we will catch in workload_signal to flip - * workload_exec_errno. - */ - sigaction(SIGUSR1, &act, NULL); - perf_evlist__start_workload(evsel_list); handle_initial_delay(); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c5b4bc5..5498eac 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) if (forks) { err = perf_evlist__prepare_workload(evlist, &trace->opts.target, - argv, false, false); + argv, false, NULL); if (err < 0) { fprintf(trace->output, "Couldn't run the workload!\n"); goto out_delete_maps; diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index eeba562..fa0ed35 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -83,8 +83,7 @@ int test__PERF_RECORD(void) * so that we have time to open the evlist (calling sys_perf_event_open * on all the fds) and then mmap them. */ - err = perf_evlist__prepare_workload(evlist, &opts.target, argv, - false, false); + err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL); if (err < 0) { pr_debug("Couldn't run the workload!\n"); goto out_delete_maps; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index d09ab57..44e339d 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -9,12 +9,21 @@ static int exited; static int nr_exit; -static void sig_handler(int sig) +static void sig_handler(int sig __maybe_unused) { exited = 1; +} - if (sig == SIGUSR1) - nr_exit = -1; +/* + * perf_evlist__prepare_workload will send a SIGUSR1 if the fork fails, since + * we asked by setting its exec_error to this handler. + */ +static void workload_exec_failed_signal(int signo __maybe_unused, + siginfo_t *info __maybe_unused, + void *ucontext __maybe_unused) +{ + exited = 1; + nr_exit = -1; } /* @@ -35,7 +44,6 @@ int test__task_exit(void) const char *argv[] = { "true", NULL }; signal(SIGCHLD, sig_handler); - signal(SIGUSR1, sig_handler); evlist = perf_evlist__new_default(); if (evlist == NULL) { @@ -57,7 +65,8 @@ int test__task_exit(void) goto out_delete_maps; } - err = perf_evlist__prepare_workload(evlist, &target, argv, false, true); + err = perf_evlist__prepare_workload(evlist, &target, argv, false, + workload_exec_failed_signal); if (err < 0) { pr_debug("Couldn't run the workload!\n"); goto out_delete_maps; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4a30c87..96b3ef5 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1029,7 +1029,7 @@ out_err: int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, const char *argv[], bool pipe_output, - bool want_signal) + void (*exec_error)(int signo, siginfo_t *info, void *ucontext)) { int child_ready_pipe[2], go_pipe[2]; char bf; @@ -1073,7 +1073,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar execvp(argv[0], (char **)argv); - if (want_signal) { + if (exec_error) { union sigval val; val.sival_int = errno; @@ -1084,6 +1084,14 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar exit(-1); } + if (exec_error) { + struct sigaction act = { + .sa_flags = SA_SIGINFO, + .sa_sigaction = exec_error, + }; + sigaction(SIGUSR1, &act, NULL); + } + if (target__none(target)) evlist->threads->map[0] = evlist->workload.pid; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 2fe5195..18d1222c 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); int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target, const char *argv[], bool pipe_output, - bool want_signal); + void (*exec_error)(int signo, siginfo_t *info, + void *ucontext)); int perf_evlist__start_workload(struct perf_evlist *evlist); int perf_evlist__parse_mmap_pages(const struct option *opt, -- cgit v0.10.2 From 3e2be2da8f76ef5b2e8e59c3dc8acd24640b4af4 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 15:03:26 -0300 Subject: perf record: Remove old evsel_list usage To be consistent with other places, use just 'evlist' for the evsel list variable, and since we have it in 'struct record', use it directly from there. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-396bnfvmlxrsj3o2tk47b8t1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ea7c306..6dcb8aa 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -324,7 +324,6 @@ out: static void record__init_features(struct record *rec) { - struct perf_evlist *evsel_list = rec->evlist; struct perf_session *session = rec->session; int feat; @@ -334,7 +333,7 @@ static void record__init_features(struct record *rec) if (rec->no_buildid) perf_header__clear_feat(&session->header, HEADER_BUILD_ID); - if (!have_tracepoints(&evsel_list->entries)) + if (!have_tracepoints(&rec->evlist->entries)) perf_header__clear_feat(&session->header, HEADER_TRACING_DATA); if (!rec->opts.branch_stack) @@ -365,7 +364,6 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) struct machine *machine; struct perf_tool *tool = &rec->tool; struct record_opts *opts = &rec->opts; - struct perf_evlist *evsel_list = rec->evlist; struct perf_data_file *file = &rec->file; struct perf_session *session; bool disabled = false; @@ -388,7 +386,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) record__init_features(rec); if (forks) { - err = perf_evlist__prepare_workload(evsel_list, &opts->target, + err = perf_evlist__prepare_workload(rec->evlist, &opts->target, argv, file->is_pipe, workload_exec_failed_signal); if (err < 0) { @@ -402,7 +400,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) goto out_delete_session; } - if (!evsel_list->nr_groups) + if (!rec->evlist->nr_groups) perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); /* @@ -415,7 +413,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (err < 0) goto out_delete_session; } else { - err = perf_session__write_header(session, evsel_list, + err = perf_session__write_header(session, rec->evlist, file->fd, false); if (err < 0) goto out_delete_session; @@ -439,7 +437,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) goto out_delete_session; } - if (have_tracepoints(&evsel_list->entries)) { + if (have_tracepoints(&rec->evlist->entries)) { /* * FIXME err <= 0 here actually means that * there were no tracepoints so its not really @@ -448,7 +446,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * return this more properly and also * propagate errors that now are calling die() */ - err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list, + err = perf_event__synthesize_tracing_data(tool, file->fd, rec->evlist, process_synthesized_event); if (err <= 0) { pr_err("Couldn't record tracing data.\n"); @@ -480,7 +478,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) perf_event__synthesize_guest_os, tool); } - err = __machine__synthesize_threads(machine, tool, &opts->target, evsel_list->threads, + err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->threads, process_synthesized_event, opts->sample_address); if (err != 0) goto out_delete_session; @@ -502,13 +500,13 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * so don't spoil it by prematurely enabling them. */ if (!target__none(&opts->target)) - perf_evlist__enable(evsel_list); + perf_evlist__enable(rec->evlist); /* * Let the child rip */ if (forks) - perf_evlist__start_workload(evsel_list); + perf_evlist__start_workload(rec->evlist); for (;;) { int hits = rec->samples; @@ -521,7 +519,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (hits == rec->samples) { if (done) break; - err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1); + err = poll(rec->evlist->pollfd, rec->evlist->nr_fds, -1); waking++; } @@ -531,7 +529,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * disable events in this case. */ if (done && !disabled && !target__none(&opts->target)) { - perf_evlist__disable(evsel_list); + perf_evlist__disable(rec->evlist); disabled = true; } } @@ -901,16 +899,13 @@ const struct option record_options[] = { int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) { int err = -ENOMEM; - struct perf_evlist *evsel_list; struct record *rec = &record; char errbuf[BUFSIZ]; - evsel_list = perf_evlist__new(); - if (evsel_list == NULL) + rec->evlist = perf_evlist__new(); + if (rec->evlist == NULL) return -ENOMEM; - rec->evlist = evsel_list; - argc = parse_options(argc, argv, record_options, record_usage, PARSE_OPT_STOP_AT_NON_OPTION); if (!argc && target__none(&rec->opts.target)) @@ -937,8 +932,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) if (rec->no_buildid_cache || rec->no_buildid) disable_buildid_cache(); - if (evsel_list->nr_entries == 0 && - perf_evlist__add_default(evsel_list) < 0) { + if (rec->evlist->nr_entries == 0 && + perf_evlist__add_default(rec->evlist) < 0) { pr_err("Not enough memory for event selector list\n"); goto out_symbol_exit; } @@ -964,7 +959,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) } err = -ENOMEM; - if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) + if (perf_evlist__create_maps(rec->evlist, &rec->opts.target) < 0) usage_with_options(record_usage, record_options); if (record_opts__config(&rec->opts)) { @@ -974,10 +969,10 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) err = __cmd_record(&record, argc, argv); - perf_evlist__munmap(evsel_list); - perf_evlist__close(evsel_list); + perf_evlist__munmap(rec->evlist); + perf_evlist__close(rec->evlist); out_free_fd: - perf_evlist__delete_maps(evsel_list); + perf_evlist__delete_maps(rec->evlist); out_symbol_exit: symbol__exit(); return err; -- cgit v0.10.2 From 03ad9747c5f2169556467101e96bc390c5aa4b83 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 15:56:06 -0300 Subject: perf evlist: Move destruction of maps to evlist destructor Instead of requiring tools to do an extra destructor call just before calling perf_evlist__delete. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-0jd2ptzyikxb5wp7inzz2ah2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index a6ec105..858b11b 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1556,10 +1556,8 @@ out: if (kvm->session) perf_session__delete(kvm->session); kvm->session = NULL; - if (kvm->evlist) { - perf_evlist__delete_maps(kvm->evlist); + if (kvm->evlist) perf_evlist__delete(kvm->evlist); - } return err; } diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 6dcb8aa..5149b41 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -964,15 +964,13 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) if (record_opts__config(&rec->opts)) { err = -EINVAL; - goto out_free_fd; + goto out_symbol_exit; } err = __cmd_record(&record, argc, argv); perf_evlist__munmap(rec->evlist); perf_evlist__close(rec->evlist); -out_free_fd: - perf_evlist__delete_maps(rec->evlist); out_symbol_exit: symbol__exit(); return err; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f8456ca..6ca0766 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1782,14 +1782,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) if (interval && interval < 100) { pr_err("print interval must be >= 100ms\n"); parse_options_usage(stat_usage, options, "I", 1); - goto out_free_maps; + goto out; } if (perf_evlist__alloc_stats(evsel_list, interval)) - goto out_free_maps; + goto out; if (perf_stat_init_aggr_mode()) - goto out_free_maps; + goto out; /* * We dont want to block the signals - that would cause @@ -1821,8 +1821,6 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) print_stat(argc, argv); perf_evlist__free_stats(evsel_list); -out_free_maps: - perf_evlist__delete_maps(evsel_list); out: perf_evlist__delete(evsel_list); return status; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 172e91a..e0fd0aa 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1171,7 +1171,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) if (!top.evlist->nr_entries && perf_evlist__add_default(top.evlist) < 0) { ui__error("Not enough memory for event selector list\n"); - goto out_delete_maps; + goto out_delete_evlist; } symbol_conf.nr_events = top.evlist->nr_entries; @@ -1181,7 +1181,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) if (record_opts__config(opts)) { status = -EINVAL; - goto out_delete_maps; + goto out_delete_evlist; } top.sym_evsel = perf_evlist__first(top.evlist); @@ -1206,8 +1206,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) status = __cmd_top(&top); -out_delete_maps: - perf_evlist__delete_maps(top.evlist); out_delete_evlist: perf_evlist__delete(top.evlist); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5498eac..f4ddd14 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1885,7 +1885,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) err = trace__symbols_init(trace, evlist); if (err < 0) { fprintf(trace->output, "Problems initializing symbol libraries!\n"); - goto out_delete_maps; + goto out_delete_evlist; } perf_evlist__config(evlist, &trace->opts); @@ -1898,7 +1898,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) argv, false, NULL); if (err < 0) { fprintf(trace->output, "Couldn't run the workload!\n"); - goto out_delete_maps; + goto out_delete_evlist; } } @@ -1996,8 +1996,6 @@ out_disable: perf_evlist__munmap(evlist); out_close_evlist: perf_evlist__close(evlist); -out_delete_maps: - perf_evlist__delete_maps(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 4248d1e..ddbc775 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -543,11 +543,10 @@ out_err: perf_evlist__munmap(evlist); perf_evlist__close(evlist); perf_evlist__delete(evlist); - } - if (cpus) + } else { cpu_map__delete(cpus); - if (threads) thread_map__delete(threads); + } machines__destroy_kernel_maps(&machines); machine__delete_threads(machine); machines__exit(&machines); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index 27eb751..f9bc1fc 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -145,11 +145,10 @@ out_err: perf_evlist__munmap(evlist); perf_evlist__close(evlist); perf_evlist__delete(evlist); - } - if (cpus) + } else { cpu_map__delete(cpus); - if (threads) thread_map__delete(threads); + } return err; } diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index d64ab79..bbb334d 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -143,6 +143,8 @@ out_close_fd: perf_evsel__close_fd(evsels[i], 1, threads->nr); out_free_evlist: perf_evlist__delete(evlist); + cpus = NULL; + threads = NULL; out_free_cpus: cpu_map__delete(cpus); out_free_threads: diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 774620a..595b577 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -48,7 +48,7 @@ int test__syscall_open_tp_fields(void) err = perf_evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", strerror(errno)); - goto out_delete_maps; + goto out_delete_evlist; } err = perf_evlist__mmap(evlist, UINT_MAX, false); @@ -114,8 +114,6 @@ out_munmap: perf_evlist__munmap(evlist); out_close_evlist: perf_evlist__close(evlist); -out_delete_maps: - perf_evlist__delete_maps(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index fa0ed35..266da9d 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -86,7 +86,7 @@ int test__PERF_RECORD(void) err = perf_evlist__prepare_workload(evlist, &opts.target, argv, false, NULL); if (err < 0) { pr_debug("Couldn't run the workload!\n"); - goto out_delete_maps; + goto out_delete_evlist; } /* @@ -101,7 +101,7 @@ int test__PERF_RECORD(void) err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); if (err < 0) { pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); - goto out_delete_maps; + goto out_delete_evlist; } cpu = err; @@ -111,7 +111,7 @@ int test__PERF_RECORD(void) */ if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { pr_debug("sched_setaffinity: %s\n", strerror(errno)); - goto out_delete_maps; + goto out_delete_evlist; } /* @@ -121,7 +121,7 @@ int test__PERF_RECORD(void) err = perf_evlist__open(evlist); if (err < 0) { pr_debug("perf_evlist__open: %s\n", strerror(errno)); - goto out_delete_maps; + goto out_delete_evlist; } /* @@ -306,8 +306,6 @@ out_err: perf_evlist__munmap(evlist); out_close_evlist: perf_evlist__close(evlist); -out_delete_maps: - perf_evlist__delete_maps(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index c6398b9..97d08ff 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -170,10 +170,6 @@ out_err: perf_evlist__close(evlist); perf_evlist__delete(evlist); } - if (cpus) - cpu_map__delete(cpus); - if (threads) - thread_map__delete(threads); return err; } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 6664a7c..266d381 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -45,7 +45,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) evsel = perf_evsel__new(&attr); if (evsel == NULL) { pr_debug("perf_evsel__new\n"); - goto out_free_evlist; + goto out_delete_evlist; } perf_evlist__add(evlist, evsel); @@ -54,7 +54,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) if (!evlist->cpus || !evlist->threads) { err = -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_maps; + goto out_delete_evlist; } if (perf_evlist__open(evlist)) { @@ -63,7 +63,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) err = -errno; pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n", strerror(errno), knob, (u64)attr.sample_freq); - goto out_delete_maps; + goto out_delete_evlist; } err = perf_evlist__mmap(evlist, 128, true); @@ -109,9 +109,7 @@ out_unmap_evlist: perf_evlist__munmap(evlist); out_close_evlist: perf_evlist__close(evlist); -out_delete_maps: - perf_evlist__delete_maps(evlist); -out_free_evlist: +out_delete_evlist: perf_evlist__delete(evlist); return err; } diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 44e339d..fdeb2aa 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -62,14 +62,14 @@ int test__task_exit(void) if (!evlist->cpus || !evlist->threads) { err = -ENOMEM; pr_debug("Not enough memory to create thread/cpu maps\n"); - goto out_delete_maps; + goto out_delete_evlist; } err = perf_evlist__prepare_workload(evlist, &target, argv, false, workload_exec_failed_signal); if (err < 0) { pr_debug("Couldn't run the workload!\n"); - goto out_delete_maps; + goto out_delete_evlist; } evsel = perf_evlist__first(evlist); @@ -83,7 +83,7 @@ int test__task_exit(void) err = perf_evlist__open(evlist); if (err < 0) { pr_debug("Couldn't open the evlist: %s\n", strerror(-err)); - goto out_delete_maps; + goto out_delete_evlist; } if (perf_evlist__mmap(evlist, 128, true) < 0) { @@ -115,8 +115,7 @@ retry: perf_evlist__munmap(evlist); out_close_evlist: perf_evlist__close(evlist); -out_delete_maps: - perf_evlist__delete_maps(evlist); +out_delete_evlist: perf_evlist__delete(evlist); return err; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 96b3ef5..143eaf0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -107,6 +107,10 @@ void perf_evlist__exit(struct perf_evlist *evlist) void perf_evlist__delete(struct perf_evlist *evlist) { + cpu_map__delete(evlist->cpus); + thread_map__delete(evlist->threads); + evlist->cpus = NULL; + evlist->threads = NULL; perf_evlist__purge(evlist); perf_evlist__exit(evlist); free(evlist); @@ -833,14 +837,6 @@ out_delete_threads: return -1; } -void perf_evlist__delete_maps(struct perf_evlist *evlist) -{ - cpu_map__delete(evlist->cpus); - thread_map__delete(evlist->threads); - evlist->cpus = NULL; - evlist->threads = NULL; -} - int perf_evlist__apply_filters(struct perf_evlist *evlist) { struct perf_evsel *evsel; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 18d1222c..518e521 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -135,7 +135,6 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist, } int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); -void perf_evlist__delete_maps(struct perf_evlist *evlist); int perf_evlist__apply_filters(struct perf_evlist *evlist); void __perf_evlist__set_leader(struct list_head *list); -- cgit v0.10.2 From f26e1c7cb279051d83e0b671f48b30fe88c2c788 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 16:54:12 -0300 Subject: perf evlist: Close fds on destructor Since it is safe to call perf_evlist__close() multiple times, autoclose it and remove the calls to the close from existing tools, reducing the tooling boilerplate. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-2kq9v7p1rude1tqxa0aue2tk@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 5149b41..b7f5e43 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -970,7 +970,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) err = __cmd_record(&record, argc, argv); perf_evlist__munmap(rec->evlist); - perf_evlist__close(rec->evlist); out_symbol_exit: symbol__exit(); return err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f4ddd14..aa8a5f4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1909,7 +1909,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); if (err < 0) { fprintf(trace->output, "Couldn't mmap the events: %s\n", strerror(errno)); - goto out_close_evlist; + goto out_delete_evlist; } perf_evlist__enable(evlist); @@ -1994,8 +1994,6 @@ out_disable: } perf_evlist__munmap(evlist); -out_close_evlist: - perf_evlist__close(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index ddbc775..2c0ce72 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -541,7 +541,6 @@ static int do_test_code_reading(bool try_kcore) out_err: if (evlist) { perf_evlist__munmap(evlist); - perf_evlist__close(evlist); perf_evlist__delete(evlist); } else { cpu_map__delete(cpus); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index f9bc1fc..dd1c677 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -143,7 +143,6 @@ out_err: if (evlist) { perf_evlist__disable(evlist); perf_evlist__munmap(evlist); - perf_evlist__close(evlist); perf_evlist__delete(evlist); } else { cpu_map__delete(cpus); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index bbb334d..111dd4a 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -68,7 +68,7 @@ int test__basic_mmap(void) evsels[i] = perf_evsel__newtp("syscalls", name); if (evsels[i] == NULL) { pr_debug("perf_evsel__new\n"); - goto out_free_evlist; + goto out_delete_evlist; } evsels[i]->attr.wakeup_events = 1; @@ -80,7 +80,7 @@ int test__basic_mmap(void) pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", strerror(errno)); - goto out_close_fd; + goto out_delete_evlist; } nr_events[i] = 0; @@ -90,7 +90,7 @@ int test__basic_mmap(void) if (perf_evlist__mmap(evlist, 128, true) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, strerror(errno)); - goto out_close_fd; + goto out_delete_evlist; } for (i = 0; i < nsyscalls; ++i) @@ -138,10 +138,7 @@ int test__basic_mmap(void) out_munmap: perf_evlist__munmap(evlist); -out_close_fd: - for (i = 0; i < nsyscalls; ++i) - perf_evsel__close_fd(evsels[i], 1, threads->nr); -out_free_evlist: +out_delete_evlist: perf_evlist__delete(evlist); cpus = NULL; threads = NULL; diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 595b577..0a00638 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -54,7 +54,7 @@ int test__syscall_open_tp_fields(void) err = perf_evlist__mmap(evlist, UINT_MAX, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); - goto out_close_evlist; + goto out_delete_evlist; } perf_evlist__enable(evlist); @@ -112,8 +112,6 @@ out_ok: err = 0; out_munmap: perf_evlist__munmap(evlist); -out_close_evlist: - perf_evlist__close(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 266da9d..682978e 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -132,7 +132,7 @@ int test__PERF_RECORD(void) err = perf_evlist__mmap(evlist, opts.mmap_pages, false); if (err < 0) { pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); - goto out_close_evlist; + goto out_delete_evlist; } /* @@ -304,8 +304,6 @@ found_exit: } out_err: perf_evlist__munmap(evlist); -out_close_evlist: - perf_evlist__close(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index 97d08ff..3d50f2d 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -167,7 +167,6 @@ out_err: if (evlist) { perf_evlist__disable(evlist); perf_evlist__munmap(evlist); - perf_evlist__close(evlist); perf_evlist__delete(evlist); } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 266d381..b366f0e 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -70,7 +70,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, strerror(errno)); - goto out_close_evlist; + goto out_delete_evlist; } perf_evlist__enable(evlist); @@ -107,8 +107,6 @@ next_event: out_unmap_evlist: perf_evlist__munmap(evlist); -out_close_evlist: - perf_evlist__close(evlist); out_delete_evlist: perf_evlist__delete(evlist); return err; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index fdeb2aa..5511a0a 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -89,7 +89,7 @@ int test__task_exit(void) if (perf_evlist__mmap(evlist, 128, true) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, strerror(errno)); - goto out_close_evlist; + goto out_delete_evlist; } perf_evlist__start_workload(evlist); @@ -113,8 +113,6 @@ retry: } perf_evlist__munmap(evlist); -out_close_evlist: - perf_evlist__close(evlist); out_delete_evlist: perf_evlist__delete(evlist); return err; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 143eaf0..a083bdc 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -107,6 +107,7 @@ void perf_evlist__exit(struct perf_evlist *evlist) void perf_evlist__delete(struct perf_evlist *evlist) { + perf_evlist__close(evlist); cpu_map__delete(evlist->cpus); thread_map__delete(evlist->threads); evlist->cpus = NULL; -- cgit v0.10.2 From 983874d173568f584a5988888645725496c09f24 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 17:25:49 -0300 Subject: perf evlist: Auto unmap on destructor Removing further boilerplate after making sure perf_evlist__munmap can be called multiple times for the same evlist. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-o0luenuld4abupm4nmrgzm6f@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b7f5e43..cb00b53 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -968,8 +968,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) } err = __cmd_record(&record, argc, argv); - - perf_evlist__munmap(rec->evlist); out_symbol_exit: symbol__exit(); return err; diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index aa8a5f4..399b4b9 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1993,7 +1993,6 @@ out_disable: } } - perf_evlist__munmap(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 2c0ce72..653a8fe 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -540,7 +540,6 @@ static int do_test_code_reading(bool try_kcore) err = TEST_CODE_READING_OK; out_err: if (evlist) { - perf_evlist__munmap(evlist); perf_evlist__delete(evlist); } else { cpu_map__delete(cpus); diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c index dd1c677..497957f 100644 --- a/tools/perf/tests/keep-tracking.c +++ b/tools/perf/tests/keep-tracking.c @@ -142,7 +142,6 @@ int test__keep_tracking(void) out_err: if (evlist) { perf_evlist__disable(evlist); - perf_evlist__munmap(evlist); perf_evlist__delete(evlist); } else { cpu_map__delete(cpus); diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 111dd4a..aef25f0 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -105,13 +105,13 @@ int test__basic_mmap(void) if (event->header.type != PERF_RECORD_SAMPLE) { pr_debug("unexpected %s event\n", perf_event__name(event->header.type)); - goto out_munmap; + goto out_delete_evlist; } err = perf_evlist__parse_sample(evlist, event, &sample); if (err) { pr_err("Can't parse sample, err = %d\n", err); - goto out_munmap; + goto out_delete_evlist; } err = -1; @@ -119,7 +119,7 @@ int test__basic_mmap(void) if (evsel == NULL) { pr_debug("event with id %" PRIu64 " doesn't map to an evsel\n", sample.id); - goto out_munmap; + goto out_delete_evlist; } nr_events[evsel->idx]++; perf_evlist__mmap_consume(evlist, 0); @@ -132,12 +132,10 @@ int test__basic_mmap(void) expected_nr_events[evsel->idx], perf_evsel__name(evsel), nr_events[evsel->idx]); err = -1; - goto out_munmap; + goto out_delete_evlist; } } -out_munmap: - perf_evlist__munmap(evlist); out_delete_evlist: perf_evlist__delete(evlist); cpus = NULL; diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 0a00638..5a016f6 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -85,7 +85,7 @@ int test__syscall_open_tp_fields(void) err = perf_evsel__parse_sample(evsel, event, &sample); if (err) { pr_err("Can't parse sample, err = %d\n", err); - goto out_munmap; + goto out_delete_evlist; } tp_flags = perf_evsel__intval(evsel, &sample, "flags"); @@ -93,7 +93,7 @@ int test__syscall_open_tp_fields(void) if (flags != tp_flags) { pr_debug("%s: Expected flags=%#x, got %#x\n", __func__, flags, tp_flags); - goto out_munmap; + goto out_delete_evlist; } goto out_ok; @@ -105,13 +105,11 @@ int test__syscall_open_tp_fields(void) if (++nr_polls > 5) { pr_debug("%s: no events!\n", __func__); - goto out_munmap; + goto out_delete_evlist; } } out_ok: err = 0; -out_munmap: - perf_evlist__munmap(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index 682978e..39cc7c3 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -165,7 +165,7 @@ int test__PERF_RECORD(void) if (verbose) perf_event__fprintf(event, stderr); pr_debug("Couldn't parse sample\n"); - goto out_err; + goto out_delete_evlist; } if (verbose) { @@ -302,8 +302,6 @@ found_exit: pr_debug("PERF_RECORD_MMAP for %s missing!\n", "[vdso]"); ++errs; } -out_err: - perf_evlist__munmap(evlist); out_delete_evlist: perf_evlist__delete(evlist); out: diff --git a/tools/perf/tests/perf-time-to-tsc.c b/tools/perf/tests/perf-time-to-tsc.c index 3d50f2d..47146d3 100644 --- a/tools/perf/tests/perf-time-to-tsc.c +++ b/tools/perf/tests/perf-time-to-tsc.c @@ -166,7 +166,6 @@ next_event: out_err: if (evlist) { perf_evlist__disable(evlist); - perf_evlist__munmap(evlist); perf_evlist__delete(evlist); } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index b366f0e..983d6b8 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -90,7 +90,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) err = perf_evlist__parse_sample(evlist, event, &sample); if (err < 0) { pr_debug("Error during parse sample\n"); - goto out_unmap_evlist; + goto out_delete_evlist; } total_periods += sample.period; @@ -105,8 +105,6 @@ next_event: err = -1; } -out_unmap_evlist: - perf_evlist__munmap(evlist); out_delete_evlist: perf_evlist__delete(evlist); return err; diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 5511a0a..5ff3db3 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -112,7 +112,6 @@ retry: err = -1; } - perf_evlist__munmap(evlist); out_delete_evlist: perf_evlist__delete(evlist); return err; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index a083bdc..0810f5c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -107,6 +107,7 @@ void perf_evlist__exit(struct perf_evlist *evlist) void perf_evlist__delete(struct perf_evlist *evlist) { + perf_evlist__munmap(evlist); perf_evlist__close(evlist); cpu_map__delete(evlist->cpus); thread_map__delete(evlist->threads); @@ -587,6 +588,9 @@ void perf_evlist__munmap(struct perf_evlist *evlist) { int i; + if (evlist->mmap == NULL) + return; + for (i = 0; i < evlist->nr_mmaps; i++) __perf_evlist__munmap(evlist, i); -- cgit v0.10.2 From 2d4352c077b98215771cc081626c7a69289c4fac Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 17:30:04 -0300 Subject: perf tests: Fixup leak on error path in parse events test We need to call the evlist destructor when failing to parse events. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ilslu69s7v7bpvdgqtrlp8f5@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index e4ce8ae..41dee5e 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1385,10 +1385,10 @@ static int test_event(struct evlist_test *e) if (ret) { pr_debug("failed to parse event '%s', err %d\n", e->name, ret); - return ret; + } else { + ret = e->check(evlist); } - - ret = e->check(evlist); + perf_evlist__delete(evlist); return ret; -- cgit v0.10.2 From 41cde47675de62ee0f3877c00ab44373b2b2f4ca Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 3 Jan 2014 17:34:42 -0300 Subject: perf stat: Remove misplaced __maybe_unused That 'argc' argument _is_ being used. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-t2gsxc15zulkorieg8zq996o@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 6ca0766..b27b264 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -645,7 +645,7 @@ static int __run_perf_stat(int argc, const char **argv) return WEXITSTATUS(status); } -static int run_perf_stat(int argc __maybe_unused, const char **argv) +static int run_perf_stat(int argc, const char **argv) { int ret; -- cgit v0.10.2 From a6cf5f39236c2ea6008a2f5cb908c3181c123096 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 3 Jan 2014 15:32:32 +0100 Subject: perf tools: Move arch setup into seprate Makefile I need to use arch related setup in the tests/make, so moving arch setup into Makefile.arch. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1388759553-12974-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 14faeeb..f2bc659 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -1,28 +1,26 @@ -uname_M := $(shell uname -m 2>/dev/null || echo not) -ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ - -e s/arm.*/arm/ -e s/sa110/arm/ \ - -e s/s390x/s390/ -e s/parisc64/parisc/ \ - -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ - -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) -NO_PERF_REGS := 1 -CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) +ifeq ($(src-perf),) +src-perf := $(srctree)/tools/perf +endif -# Additional ARCH settings for x86 -ifeq ($(ARCH),i386) - override ARCH := x86 - NO_PERF_REGS := 0 - LIBUNWIND_LIBS = -lunwind -lunwind-x86 +ifeq ($(obj-perf),) +obj-perf := $(OUTPUT) endif -ifeq ($(ARCH),x86_64) - override ARCH := x86 - IS_X86_64 := 0 - ifeq (, $(findstring m32,$(CFLAGS))) - IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1) - endif +ifneq ($(obj-perf),) +obj-perf := $(abspath $(obj-perf))/ +endif + +LIB_INCLUDE := $(srctree)/tools/lib/ +CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS) + +include $(src-perf)/config/Makefile.arch + +NO_PERF_REGS := 1 + +# Additional ARCH settings for x86 +ifeq ($(ARCH),x86) ifeq (${IS_X86_64}, 1) - RAW_ARCH := x86_64 CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S LIBUNWIND_LIBS = -lunwind -lunwind-x86_64 @@ -64,20 +62,6 @@ ifeq ($(NO_PERF_REGS),0) CFLAGS += -DHAVE_PERF_REGS_SUPPORT endif -ifeq ($(src-perf),) -src-perf := $(srctree)/tools/perf -endif - -ifeq ($(obj-perf),) -obj-perf := $(OUTPUT) -endif - -ifneq ($(obj-perf),) -obj-perf := $(abspath $(obj-perf))/ -endif - -LIB_INCLUDE := $(srctree)/tools/lib/ - # include ARCH specific config -include $(src-perf)/arch/$(ARCH)/Makefile diff --git a/tools/perf/config/Makefile.arch b/tools/perf/config/Makefile.arch new file mode 100644 index 0000000..fef8ae9 --- /dev/null +++ b/tools/perf/config/Makefile.arch @@ -0,0 +1,22 @@ + +uname_M := $(shell uname -m 2>/dev/null || echo not) + +ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ + -e s/arm.*/arm/ -e s/sa110/arm/ \ + -e s/s390x/s390/ -e s/parisc64/parisc/ \ + -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ + -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) + +# Additional ARCH settings for x86 +ifeq ($(ARCH),i386) + override ARCH := x86 +endif + +ifeq ($(ARCH),x86_64) + override ARCH := x86 + IS_X86_64 := 0 + ifeq (, $(findstring m32,$(CFLAGS))) + IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1) + RAW_ARCH := x86_64 + endif +endif -- cgit v0.10.2 From f7c64474242701eb24f6fe96f8df0389a2b800f7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 3 Jan 2014 15:32:33 +0100 Subject: perf tests: Fix installation tests path setup Currently installation tests work only over x86_64, adding arch check to make it work over i386 as well. NOTE looks like x86 is the only arch running tests, we need some IS_(32/64) flag to make this generic. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1388759553-12974-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/tests/make b/tools/perf/tests/make index f641c35..e341088 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -1,6 +1,16 @@ PERF := . MK := Makefile +include config/Makefile.arch + +# FIXME looks like x86 is the only arch running tests ;-) +# we need some IS_(32/64) flag to make this generic +ifeq ($(IS_X86_64),1) +lib = lib64 +else +lib = lib +endif + has = $(shell which $1 2>/dev/null) # standard single make variable specified @@ -118,16 +128,16 @@ installed_files_bin := bin/perf installed_files_bin += etc/bash_completion.d/perf installed_files_bin += libexec/perf-core/perf-archive -installed_files_plugins := lib64/traceevent/plugins/plugin_cfg80211.so -installed_files_plugins += lib64/traceevent/plugins/plugin_scsi.so -installed_files_plugins += lib64/traceevent/plugins/plugin_xen.so -installed_files_plugins += lib64/traceevent/plugins/plugin_function.so -installed_files_plugins += lib64/traceevent/plugins/plugin_sched_switch.so -installed_files_plugins += lib64/traceevent/plugins/plugin_mac80211.so -installed_files_plugins += lib64/traceevent/plugins/plugin_kvm.so -installed_files_plugins += lib64/traceevent/plugins/plugin_kmem.so -installed_files_plugins += lib64/traceevent/plugins/plugin_hrtimer.so -installed_files_plugins += lib64/traceevent/plugins/plugin_jbd2.so +installed_files_plugins := $(lib)/traceevent/plugins/plugin_cfg80211.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_scsi.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_xen.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_function.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_sched_switch.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_mac80211.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_kvm.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_kmem.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_hrtimer.so +installed_files_plugins += $(lib)/traceevent/plugins/plugin_jbd2.so installed_files_all := $(installed_files_bin) installed_files_all += $(installed_files_plugins) -- cgit v0.10.2 From 198430b56d4ab49d77381ef7cd3daf418a2c00c0 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 2 Jan 2014 10:53:04 +0100 Subject: tools lib traceevent: Replace tabs with spaces for all non-commands statements The tabbed indentation in non-commands statements could be sometimes considered as follow up for the rule command in the Makefile. This error is hard to find, so as a precaution replacing tabs with spaces for all non-commands statements. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://marc.info/?t=136484403900003&r=1&w=2 Link: http://lkml.kernel.org/r/20140102095304.GA1196@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index ca4ab78..76fe0ae 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -86,8 +86,8 @@ ifeq ($(BUILD_SRC),) ifneq ($(OUTPUT),) define build_output - $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \ - BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1 + $(if $(VERBOSE:1=),@)+$(MAKE) -C $(OUTPUT) \ + BUILD_SRC=$(CURDIR)/ -f $(CURDIR)/Makefile $1 endef all: sub-make @@ -221,23 +221,23 @@ $(PLUGINS): %.so: %.o $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $< define make_version.h - (echo '/* This file is automatically generated. Do not modify. */'; \ - echo \#define VERSION_CODE $(shell \ - expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ - echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ - echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ - echo '#define FILE_VERSION '$(FILE_VERSION); \ - ) > $1 + (echo '/* This file is automatically generated. Do not modify. */'; \ + echo \#define VERSION_CODE $(shell \ + expr $(VERSION) \* 256 + $(PATCHLEVEL)); \ + echo '#define EXTRAVERSION ' $(EXTRAVERSION); \ + echo '#define VERSION_STRING "'$(VERSION).$(PATCHLEVEL).$(EXTRAVERSION)'"'; \ + echo '#define FILE_VERSION '$(FILE_VERSION); \ + ) > $1 endef define update_version.h - ($(call make_version.h, $@.tmp); \ - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ - rm -f $@.tmp; \ - else \ - echo ' UPDATE $@'; \ - mv -f $@.tmp $@; \ - fi); + ($(call make_version.h, $@.tmp); \ + if [ -r $@ ] && cmp -s $@ $@.tmp; then \ + rm -f $@.tmp; \ + else \ + echo ' UPDATE $@'; \ + mv -f $@.tmp $@; \ + fi); endef ep_version.h: force @@ -246,13 +246,13 @@ ep_version.h: force VERSION_FILES = ep_version.h define update_dir - (echo $1 > $@.tmp; \ - if [ -r $@ ] && cmp -s $@ $@.tmp; then \ - rm -f $@.tmp; \ - else \ - echo ' UPDATE $@'; \ - mv -f $@.tmp $@; \ - fi); + (echo $1 > $@.tmp; \ + if [ -r $@ ] && cmp -s $@ $@.tmp; then \ + rm -f $@.tmp; \ + else \ + echo ' UPDATE $@'; \ + mv -f $@.tmp $@; \ + fi); endef ## make deps @@ -262,10 +262,10 @@ all_deps := $(all_objs:%.o=.%.d) # let .d file also depends on the source and header files define check_deps - @set -e; $(RM) $@; \ - $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ - sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ - $(RM) $@.$$$$ + @set -e; $(RM) $@; \ + $(CC) -MM $(CFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + $(RM) $@.$$$$ endef $(all_deps): .%.d: $(src)/%.c -- cgit v0.10.2 From 9bb8e5edcf37182d0c97e98131cc3c5c03014b0e Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 1 Jan 2014 17:50:50 +0100 Subject: tools lib traceevent: Shut up plugins make message Getting rid of following build output: $ make O=/tmp/build/perf -C tools/perf/ install-bin ... make[3]: Nothing to be done for `plugins'. make[2]: Nothing to be done for `plugins'. ... which triggers when traceevent library needs to be rebuilt, but we have plugins built already. Adding extra 'plugins' target with nop which is visible and triggers in both Makefile parts (for detached output directory (O=...) the traceevent Makefile spawns sub make for the build itself). Reported-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1388595050-23005-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index 76fe0ae..f778d48 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -329,9 +329,12 @@ clean: endif # skip-makefile -PHONY += force +PHONY += force plugins force: +plugins: + @echo > /dev/null + # Declare the contents of the .PHONY variable as phony. We keep that # information in a variable so we can use it in if_changed and friends. .PHONY: $(PHONY) -- cgit v0.10.2 From 3ba4d2e1a8235d862657ded9f20b3170b477768b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 6 Jan 2014 15:28:35 -0300 Subject: perf header: Pack 'struct perf_session_env' Initial struct: [acme@ssdandy linux]$ pahole -C perf_session_env ~/bin/perf struct perf_session_env { char * hostname; /* 0 8 */ char * os_release; /* 8 8 */ char * version; /* 16 8 */ char * arch; /* 24 8 */ int nr_cpus_online; /* 32 4 */ int nr_cpus_avail; /* 36 4 */ char * cpu_desc; /* 40 8 */ char * cpuid; /* 48 8 */ long long unsigned int total_mem; /* 56 8 */ /* --- cacheline 1 boundary (64 bytes) --- */ int nr_cmdline; /* 64 4 */ /* XXX 4 bytes hole, try to pack */ char * cmdline; /* 72 8 */ int nr_sibling_cores; /* 80 4 */ /* XXX 4 bytes hole, try to pack */ char * sibling_cores; /* 88 8 */ int nr_sibling_threads; /* 96 4 */ /* XXX 4 bytes hole, try to pack */ char * sibling_threads; /* 104 8 */ int nr_numa_nodes; /* 112 4 */ /* XXX 4 bytes hole, try to pack */ char * numa_nodes; /* 120 8 */ /* --- cacheline 2 boundary (128 bytes) --- */ int nr_pmu_mappings; /* 128 4 */ /* XXX 4 bytes hole, try to pack */ char * pmu_mappings; /* 136 8 */ int nr_groups; /* 144 4 */ /* size: 152, cachelines: 3, members: 20 */ /* sum members: 128, holes: 5, sum holes: 20 */ /* padding: 4 */ /* last cacheline: 24 bytes */ }; [acme@ssdandy linux]$ [acme@ssdandy linux]$ pahole -C perf_session_env --reorganize --show_reorg_steps ~/bin/perf | grep ^/ | grep -v Final /* Moving 'nr_sibling_cores' from after 'cmdline' to after 'nr_cmdline' */ /* Moving 'nr_numa_nodes' from after 'sibling_threads' to after 'nr_sibling_threads' */ /* Moving 'nr_groups' from after 'pmu_mappings' to after 'nr_pmu_mappings' */ [acme@ssdandy linux]$ Final struct stats: [acme@ssdandy linux]$ pahole -C perf_session_env --reorganize --show_reorg_steps ~/bin/perf | tail -4 /* --- cacheline 2 boundary (128 bytes) --- */ /* size: 128, cachelines: 2, members: 20 */ }; /* saved 24 bytes and 1 cacheline! */ [acme@ssdandy linux]$ Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-3d9tshamloinzxcqeb7mtd1n@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 307c9ae..a2d047b 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -77,16 +77,16 @@ struct perf_session_env { unsigned long long total_mem; int nr_cmdline; - char *cmdline; int nr_sibling_cores; - char *sibling_cores; int nr_sibling_threads; - char *sibling_threads; int nr_numa_nodes; - char *numa_nodes; int nr_pmu_mappings; - char *pmu_mappings; int nr_groups; + char *cmdline; + char *sibling_cores; + char *sibling_threads; + char *numa_nodes; + char *pmu_mappings; }; struct perf_header { -- cgit v0.10.2 From 98eafce6bda705529e90d33b7f23706b346a6c8a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 6 Jan 2014 15:43:02 -0300 Subject: perf trace: Pack 'struct trace' Initial struct stats: /* size: 368, cachelines: 6, members: 24 */ /* sum members: 353, holes: 3, sum holes: 15 */ /* last cacheline: 48 bytes */ After reorg: [acme@ssdandy linux]$ pahole -C trace ~/bin/trace | tail -4 /* size: 360, cachelines: 6, members: 24 */ /* padding: 7 */ /* last cacheline: 40 bytes */ }; [acme@ssdandy linux]$ Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-6jimc80yu89qkx6zb8465s6t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 399b4b9..4bd44ab 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1160,26 +1160,27 @@ struct trace { struct record_opts opts; struct machine *host; u64 base_time; - bool full_time; FILE *output; unsigned long nr_events; struct strlist *ev_qualifier; - bool not_ev_qualifier; - bool live; const char *last_vfs_getname; struct intlist *tid_list; struct intlist *pid_list; + double duration_filter; + double runtime_ms; + struct { + u64 vfs_getname, + proc_getname; + } stats; + bool not_ev_qualifier; + bool live; + bool full_time; bool sched; bool multiple_threads; bool summary; bool summary_only; bool show_comm; bool show_tool_stats; - double duration_filter; - double runtime_ms; - struct { - u64 vfs_getname, proc_getname; - } stats; }; static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) -- cgit v0.10.2 From c4eb6c0e7aa3a5106a3382880bc41c696e72adb4 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 7 Jan 2014 13:47:18 +0100 Subject: perf tools: Automate setup of FEATURE_CHECK_(C|LD)FLAGS-all variables Instead of explicitly adding same value into FEATURE_CHECK_(C|LD)FLAGS-all variables we can do that automatically. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1389098853-14466-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index f2bc659..5d15b43 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -53,9 +53,6 @@ else FEATURE_CHECK_LDFLAGS-libunwind = $(LIBUNWIND_LDFLAGS) FEATURE_CHECK_CFLAGS-libunwind-debug-frame = $(LIBUNWIND_CFLAGS) FEATURE_CHECK_LDFLAGS-libunwind-debug-frame = $(LIBUNWIND_LDFLAGS) - # and the flags for the test-all case - FEATURE_CHECK_CFLAGS-all += $(LIBUNWIND_CFLAGS) - FEATURE_CHECK_LDFLAGS-all += $(LIBUNWIND_LDFLAGS) endif ifeq ($(NO_PERF_REGS),0) @@ -152,6 +149,17 @@ CORE_FEATURE_TESTS = \ stackprotector-all \ timerfd +# Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features. +# If in the future we need per-feature checks/flags for features not +# mentioned in this list we need to refactor this ;-). +set_test_all_flags = $(eval $(set_test_all_flags_code)) +define set_test_all_flags_code + FEATURE_CHECK_CFLAGS-all += $(FEATURE_CHECK_CFLAGS-$(1)) + FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1)) +endef + +$(foreach feat,$(CORE_FEATURE_TESTS),$(call set_test_all_flags,$(feat))) + # # So here we detect whether test-all was rebuilt, to be able # to skip the print-out of the long features list if the file -- cgit v0.10.2 From 14bd6d20fef603060474701967085442b716b6a9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 7 Jan 2014 13:47:19 +0100 Subject: perf machine: Fix id_hdr_size initialization The id_hdr_size field was not properly initialized, set it to zero, as the machine struct may have come from some non zeroing allocation routine or from the stack without any field being initialized. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1389098853-14466-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index a98538d..0130279 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -27,6 +27,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) machine->pid = pid; machine->symbol_filter = NULL; + machine->id_hdr_size = 0; machine->root_dir = strdup(root_dir); if (machine->root_dir == NULL) -- cgit v0.10.2 From a18382b68f8bf1a8d43e3cb08b3479cb768913ea Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 7 Jan 2014 13:47:20 +0100 Subject: perf tools: Make perf_event__synthesize_mmap_events global Making perf_event__synthesize_mmap_events global, it will be used in following patch from test code. Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1389098853-14466-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 45a76c6..1fc1c2f 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -175,12 +175,12 @@ out: return tgid; } -static int perf_event__synthesize_mmap_events(struct perf_tool *tool, - union perf_event *event, - pid_t pid, pid_t tgid, - perf_event__handler_t process, - struct machine *machine, - bool mmap_data) +int perf_event__synthesize_mmap_events(struct perf_tool *tool, + union perf_event *event, + pid_t pid, pid_t tgid, + perf_event__handler_t process, + struct machine *machine, + bool mmap_data) { char filename[PATH_MAX]; FILE *fp; diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 30fec99..faf6e21 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -266,6 +266,13 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, const struct perf_sample *sample, bool swapped); +int perf_event__synthesize_mmap_events(struct perf_tool *tool, + union perf_event *event, + pid_t pid, pid_t tgid, + perf_event__handler_t process, + struct machine *machine, + bool mmap_data); + size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp); size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp); -- cgit v0.10.2 From 8f3dd2b096c348033e55d4a4fb8c0f672559657e Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 7 Jan 2014 14:14:06 -0800 Subject: perf stat: Fix --delay option in man page The --delay option was documented as --initial-delay in the manpage. Fix this. Signed-off-by: Andi Kleen Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/r/1389132847-31982-1-git-send-email-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 80c7da6..29ee857 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -133,7 +133,7 @@ use --per-core in addition to -a. (system-wide). The output includes the core number and the number of online logical processors on that physical processor. -D msecs:: ---initial-delay msecs:: +--delay msecs:: After starting the program, wait msecs before measuring. This is useful to filter out the startup phase of the program, which is often very different. -- cgit v0.10.2 From 88aca8d966a1349631a0946ed77c7ed360519ed4 Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Wed, 8 Jan 2014 08:43:51 -0800 Subject: tools perf: Comment typo fix s/temr/term/ Signed-off-by: Cody P Schafer Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Sukadev Bhattiprolu Link: http://lkml.kernel.org/r/1389199434-21761-1-git-send-email-cody@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 0934d64..d9cab4d 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -505,7 +505,7 @@ static __u64 pmu_format_value(unsigned long *format, __u64 value) /* * Setup one of config[12] attr members based on the - * user input data - temr parameter. + * user input data - term parameter. */ static int pmu_config_term(struct list_head *formats, struct perf_event_attr *attr, -- cgit v0.10.2 From fad2918ed5171e6299a9b4b885d0459f35ee7377 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 8 Jan 2014 10:10:00 -0300 Subject: perf report: Move logic to warn about kptr_restrict'ed kernels to separate function Its too big, better have a separate function for it so that the main logic gets shorter/clearer. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-ahh6vfzyh8fsygjwrsbroeu0@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index bf8dd2e..f2ff860 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -412,14 +412,41 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, return 0; } +static void report__warn_kptr_restrict(const struct report *rep) +{ + struct map *kernel_map = rep->session->machines.host.vmlinux_maps[MAP__FUNCTION]; + struct kmap *kernel_kmap = map__kmap(kernel_map); + + if (kernel_map == NULL || + (kernel_map->dso->hit && + (kernel_kmap->ref_reloc_sym == NULL || + kernel_kmap->ref_reloc_sym->addr == 0))) { + const char *desc = + "As no suitable kallsyms nor vmlinux was found, kernel samples\n" + "can't be resolved."; + + if (kernel_map) { + const struct dso *kdso = kernel_map->dso; + if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) { + desc = "If some relocation was applied (e.g. " + "kexec) symbols may be misresolved."; + } + } + + ui__warning( +"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" +"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" +"Samples in kernel modules can't be resolved as well.\n\n", + desc); + } +} + static int __cmd_report(struct report *rep) { int ret = -EINVAL; u64 nr_samples; struct perf_session *session = rep->session; struct perf_evsel *pos; - struct map *kernel_map; - struct kmap *kernel_kmap; const char *help = "For a higher level overview, try: perf report --sort comm,dso"; struct ui_progress prog; struct perf_data_file *file = session->file; @@ -444,30 +471,7 @@ static int __cmd_report(struct report *rep) if (ret) return ret; - kernel_map = session->machines.host.vmlinux_maps[MAP__FUNCTION]; - kernel_kmap = map__kmap(kernel_map); - if (kernel_map == NULL || - (kernel_map->dso->hit && - (kernel_kmap->ref_reloc_sym == NULL || - kernel_kmap->ref_reloc_sym->addr == 0))) { - const char *desc = - "As no suitable kallsyms nor vmlinux was found, kernel samples\n" - "can't be resolved."; - - if (kernel_map) { - const struct dso *kdso = kernel_map->dso; - if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) { - desc = "If some relocation was applied (e.g. " - "kexec) symbols may be misresolved."; - } - } - - ui__warning( -"Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" -"Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" -"Samples in kernel modules can't be resolved as well.\n\n", - desc); - } + report__warn_kptr_restrict(rep); if (use_browser == 0) { if (verbose > 3) -- cgit v0.10.2 From 8362951b7b0618687beddac90aeee43940d20659 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 8 Jan 2014 12:22:07 -0300 Subject: perf report: Move hist browser selection code to separate function To unclutter the main function. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-agvxwpazlucy6h5sejuttw9t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index f2ff860..03941ad 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -441,13 +441,57 @@ static void report__warn_kptr_restrict(const struct report *rep) } } +static int report__gtk_browse_hists(struct report *rep, const char *help) +{ + int (*hist_browser)(struct perf_evlist *evlist, const char *help, + struct hist_browser_timer *timer, float min_pcnt); + + hist_browser = dlsym(perf_gtk_handle, "perf_evlist__gtk_browse_hists"); + + if (hist_browser == NULL) { + ui__error("GTK browser not found!\n"); + return -1; + } + + return hist_browser(rep->session->evlist, help, NULL, rep->min_percent); +} + +static int report__browse_hists(struct report *rep) +{ + int ret; + struct perf_session *session = rep->session; + struct perf_evlist *evlist = session->evlist; + const char *help = "For a higher level overview, try: perf report --sort comm,dso"; + + switch (use_browser) { + case 1: + ret = perf_evlist__tui_browse_hists(evlist, help, NULL, + rep->min_percent, + &session->header.env); + /* + * Usually "ret" is the last pressed key, and we only + * care if the key notifies us to switch data file. + */ + if (ret != K_SWITCH_INPUT_DATA) + ret = 0; + break; + case 2: + ret = report__gtk_browse_hists(rep, help); + break; + default: + ret = perf_evlist__tty_browse_hists(evlist, rep, help); + break; + } + + return ret; +} + static int __cmd_report(struct report *rep) { int ret = -EINVAL; u64 nr_samples; struct perf_session *session = rep->session; struct perf_evsel *pos; - const char *help = "For a higher level overview, try: perf report --sort comm,dso"; struct ui_progress prog; struct perf_data_file *file = session->file; @@ -524,38 +568,7 @@ static int __cmd_report(struct report *rep) list_for_each_entry(pos, &session->evlist->entries, node) hists__output_resort(&pos->hists); - if (use_browser > 0) { - if (use_browser == 1) { - ret = perf_evlist__tui_browse_hists(session->evlist, - help, NULL, - rep->min_percent, - &session->header.env); - /* - * Usually "ret" is the last pressed key, and we only - * care if the key notifies us to switch data file. - */ - if (ret != K_SWITCH_INPUT_DATA) - ret = 0; - - } else if (use_browser == 2) { - int (*hist_browser)(struct perf_evlist *, - const char *, - struct hist_browser_timer *, - float min_pcnt); - - hist_browser = dlsym(perf_gtk_handle, - "perf_evlist__gtk_browse_hists"); - if (hist_browser == NULL) { - ui__error("GTK browser not found!\n"); - return ret; - } - hist_browser(session->evlist, help, NULL, - rep->min_percent); - } - } else - perf_evlist__tty_browse_hists(session->evlist, rep, help); - - return ret; + return report__browse_hists(rep); } static int -- cgit v0.10.2 From f6d8b0571c9ac8f273d18c112c2fc3c9533c9f0a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 8 Jan 2014 14:45:24 -0300 Subject: perf report: Move histogram entries collapsing to separate function Further uncluttering the main 'report' function by group related code in separate function. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-b594zsbwke8khir13kudwqmj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 03941ad..cff9465 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -486,13 +486,55 @@ static int report__browse_hists(struct report *rep) return ret; } +static u64 report__collapse_hists(struct report *rep) +{ + struct ui_progress prog; + struct perf_evsel *pos; + u64 nr_samples = 0; + /* + * Count number of histogram entries to use when showing progress, + * reusing nr_samples variable. + */ + list_for_each_entry(pos, &rep->session->evlist->entries, node) + nr_samples += pos->hists.nr_entries; + + ui_progress__init(&prog, nr_samples, "Merging related events..."); + /* + * Count total number of samples, will be used to check if this + * session had any. + */ + nr_samples = 0; + + list_for_each_entry(pos, &rep->session->evlist->entries, node) { + struct hists *hists = &pos->hists; + + if (pos->idx == 0) + hists->symbol_filter_str = rep->symbol_filter_str; + + hists__collapse_resort(hists, &prog); + nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; + + /* Non-group events are considered as leader */ + if (symbol_conf.event_group && + !perf_evsel__is_group_leader(pos)) { + struct hists *leader_hists = &pos->leader->hists; + + hists__match(leader_hists, hists); + hists__link(leader_hists, hists); + } + } + + ui_progress__finish(); + + return nr_samples; +} + static int __cmd_report(struct report *rep) { - int ret = -EINVAL; + int ret; u64 nr_samples; struct perf_session *session = rep->session; struct perf_evsel *pos; - struct ui_progress prog; struct perf_data_file *file = session->file; signal(SIGINT, sig_handler); @@ -530,32 +572,7 @@ static int __cmd_report(struct report *rep) } } - nr_samples = 0; - list_for_each_entry(pos, &session->evlist->entries, node) - nr_samples += pos->hists.nr_entries; - - ui_progress__init(&prog, nr_samples, "Merging related events..."); - - nr_samples = 0; - list_for_each_entry(pos, &session->evlist->entries, node) { - struct hists *hists = &pos->hists; - - if (pos->idx == 0) - hists->symbol_filter_str = rep->symbol_filter_str; - - hists__collapse_resort(hists, &prog); - nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; - - /* Non-group events are considered as leader */ - if (symbol_conf.event_group && - !perf_evsel__is_group_leader(pos)) { - struct hists *leader_hists = &pos->leader->hists; - - hists__match(leader_hists, hists); - hists__link(leader_hists, hists); - } - } - ui_progress__finish(); + nr_samples = report__collapse_hists(rep); if (session_done()) return 0; -- cgit v0.10.2 From 0050f7aa182e3e8ed34dd6cc4318e52b3df6347a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 10 Jan 2014 10:37:27 -0300 Subject: perf evlist: Introduce evlist__for_each() & friends For the common evsel list traversal, so that it becomes more compact. Use the opportunity to start ditching the 'perf_' from 'perf_evlist__', as discussed, as the whole conversion touches a lot of places, lets do it piecemeal when we have the chance due to other work, like in this case. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-qnkx7dzm2h6m6uptkfk03ni6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index ab65057..0da603b 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -232,7 +232,7 @@ static int __cmd_annotate(struct perf_annotate *ann) perf_session__fprintf_dsos(session, stdout); total_nr_samples = 0; - list_for_each_entry(pos, &session->evlist->entries, node) { + evlist__for_each(session->evlist, pos) { struct hists *hists = &pos->hists; u32 nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE]; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index e6a0844..987cac3 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -356,9 +356,10 @@ static struct perf_evsel *evsel_match(struct perf_evsel *evsel, { struct perf_evsel *e; - list_for_each_entry(e, &evlist->entries, node) + evlist__for_each(evlist, e) { if (perf_evsel__match2(evsel, e)) return e; + } return NULL; } @@ -367,7 +368,7 @@ static void perf_evlist__collapse_resort(struct perf_evlist *evlist) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { struct hists *hists = &evsel->hists; hists__collapse_resort(hists, NULL); @@ -614,7 +615,7 @@ static void data_process(void) struct perf_evsel *evsel_base; bool first = true; - list_for_each_entry(evsel_base, &evlist_base->entries, node) { + evlist__for_each(evlist_base, evsel_base) { struct data__file *d; int i; diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c index 20b0f12..c99e0de 100644 --- a/tools/perf/builtin-evlist.c +++ b/tools/perf/builtin-evlist.c @@ -29,7 +29,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details if (session == NULL) return -ENOMEM; - list_for_each_entry(pos, &session->evlist->entries, node) + evlist__for_each(session->evlist, pos) perf_evsel__fprintf(pos, details, stdout); perf_session__delete(session); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index c9f6d74..b346601 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -369,7 +369,7 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.ordered_samples = true; - list_for_each_entry(evsel, &session->evlist->entries, node) { + evlist__for_each(session->evlist, evsel) { const char *name = perf_evsel__name(evsel); if (!strcmp(name, "sched:sched_switch")) { diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 858b11b..a735051 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1174,7 +1174,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) * Note: exclude_{guest,host} do not apply here. * This command processes KVM tracepoints from host only */ - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { struct perf_event_attr *attr = &pos->attr; /* make sure these *are* set */ diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index cb00b53..8860015 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -183,7 +183,7 @@ static int record__open(struct record *rec) perf_evlist__config(evlist, opts); - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { try_again: if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) { if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) { diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index cff9465..46864dd 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -384,7 +384,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, { struct perf_evsel *pos; - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { struct hists *hists = &pos->hists; const char *evname = perf_evsel__name(pos); @@ -495,7 +495,7 @@ static u64 report__collapse_hists(struct report *rep) * Count number of histogram entries to use when showing progress, * reusing nr_samples variable. */ - list_for_each_entry(pos, &rep->session->evlist->entries, node) + evlist__for_each(rep->session->evlist, pos) nr_samples += pos->hists.nr_entries; ui_progress__init(&prog, nr_samples, "Merging related events..."); @@ -505,7 +505,7 @@ static u64 report__collapse_hists(struct report *rep) */ nr_samples = 0; - list_for_each_entry(pos, &rep->session->evlist->entries, node) { + evlist__for_each(rep->session->evlist, pos) { struct hists *hists = &pos->hists; if (pos->idx == 0) @@ -582,7 +582,7 @@ static int __cmd_report(struct report *rep) return 0; } - list_for_each_entry(pos, &session->evlist->entries, node) + evlist__for_each(session->evlist, pos) hists__output_resort(&pos->hists); return report__browse_hists(rep); diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 6040000..9e9c91f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -603,7 +603,7 @@ static int process_attr(struct perf_tool *tool, union perf_event *event, if (evsel->attr.type >= PERF_TYPE_MAX) return 0; - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { if (pos->attr.type == evsel->attr.type && pos != evsel) return 0; } @@ -1309,8 +1309,7 @@ static int check_ev_match(char *dir_name, char *scriptname, snprintf(evname, len + 1, "%s", p); match = 0; - list_for_each_entry(pos, - &session->evlist->entries, node) { + evlist__for_each(session->evlist, pos) { if (!strcmp(perf_evsel__name(pos), evname)) { match = 1; break; diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index b27b264..8b0e1c9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -214,7 +214,7 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { perf_evsel__free_stat_priv(evsel); perf_evsel__free_counts(evsel); perf_evsel__free_prev_raw_counts(evsel); @@ -225,7 +225,7 @@ static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (perf_evsel__alloc_stat_priv(evsel) < 0 || perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 || (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0)) @@ -259,7 +259,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { perf_evsel__reset_stat_priv(evsel); perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel)); } @@ -326,13 +326,13 @@ static struct perf_evsel *nth_evsel(int n) /* Assumes this only called when evsel_list does not change anymore. */ if (!array) { - list_for_each_entry(ev, &evsel_list->entries, node) + evlist__for_each(evsel_list, ev) array_len++; array = malloc(array_len * sizeof(void *)); if (!array) exit(ENOMEM); j = 0; - list_for_each_entry(ev, &evsel_list->entries, node) + evlist__for_each(evsel_list, ev) array[j++] = ev; } if (n < array_len) @@ -440,13 +440,13 @@ static void print_interval(void) char prefix[64]; if (aggr_mode == AGGR_GLOBAL) { - list_for_each_entry(counter, &evsel_list->entries, node) { + evlist__for_each(evsel_list, counter) { ps = counter->priv; memset(ps->res_stats, 0, sizeof(ps->res_stats)); read_counter_aggr(counter); } } else { - list_for_each_entry(counter, &evsel_list->entries, node) { + evlist__for_each(evsel_list, counter) { ps = counter->priv; memset(ps->res_stats, 0, sizeof(ps->res_stats)); read_counter(counter); @@ -483,12 +483,12 @@ static void print_interval(void) print_aggr(prefix); break; case AGGR_NONE: - list_for_each_entry(counter, &evsel_list->entries, node) + evlist__for_each(evsel_list, counter) print_counter(counter, prefix); break; case AGGR_GLOBAL: default: - list_for_each_entry(counter, &evsel_list->entries, node) + evlist__for_each(evsel_list, counter) print_counter_aggr(counter, prefix); } @@ -504,7 +504,7 @@ static void handle_initial_delay(void) nthreads = thread_map__nr(evsel_list->threads); usleep(initial_delay * 1000); - list_for_each_entry(counter, &evsel_list->entries, node) + evlist__for_each(evsel_list, counter) perf_evsel__enable(counter, ncpus, nthreads); } } @@ -552,7 +552,7 @@ static int __run_perf_stat(int argc, const char **argv) if (group) perf_evlist__set_leader(evsel_list); - list_for_each_entry(counter, &evsel_list->entries, node) { + evlist__for_each(evsel_list, counter) { if (create_perf_stat_counter(counter) < 0) { /* * PPC returns ENXIO for HW counters until 2.6.37 @@ -630,13 +630,13 @@ static int __run_perf_stat(int argc, const char **argv) update_stats(&walltime_nsecs_stats, t1 - t0); if (aggr_mode == AGGR_GLOBAL) { - list_for_each_entry(counter, &evsel_list->entries, node) { + evlist__for_each(evsel_list, counter) { read_counter_aggr(counter); perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), thread_map__nr(evsel_list->threads)); } } else { - list_for_each_entry(counter, &evsel_list->entries, node) { + evlist__for_each(evsel_list, counter) { read_counter(counter); perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1); } @@ -1117,7 +1117,7 @@ static void print_aggr(char *prefix) for (s = 0; s < aggr_map->nr; s++) { id = aggr_map->map[s]; - list_for_each_entry(counter, &evsel_list->entries, node) { + evlist__for_each(evsel_list, counter) { val = ena = run = 0; nr = 0; for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { @@ -1328,11 +1328,11 @@ static void print_stat(int argc, const char **argv) print_aggr(NULL); break; case AGGR_GLOBAL: - list_for_each_entry(counter, &evsel_list->entries, node) + evlist__for_each(evsel_list, counter) print_counter_aggr(counter, NULL); break; case AGGR_NONE: - list_for_each_entry(counter, &evsel_list->entries, node) + evlist__for_each(evsel_list, counter) print_counter(counter, NULL); break; default: diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e0fd0aa..569dd87 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -482,7 +482,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) fprintf(stderr, "\nAvailable events:"); - list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) + evlist__for_each(top->evlist, top->sym_evsel) fprintf(stderr, "\n\t%d %s", top->sym_evsel->idx, perf_evsel__name(top->sym_evsel)); prompt_integer(&counter, "Enter details event counter"); @@ -493,7 +493,7 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) sleep(1); break; } - list_for_each_entry(top->sym_evsel, &top->evlist->entries, node) + evlist__for_each(top->evlist, top->sym_evsel) if (top->sym_evsel->idx == counter) break; } else @@ -575,7 +575,7 @@ static void *display_thread_tui(void *arg) * Zooming in/out UIDs. For now juse use whatever the user passed * via --uid. */ - list_for_each_entry(pos, &top->evlist->entries, node) + evlist__for_each(top->evlist, pos) pos->hists.uid_filter_str = top->record_opts.target.uid_str; perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent, @@ -858,7 +858,7 @@ static int perf_top__start_counters(struct perf_top *top) perf_evlist__config(evlist, opts); - list_for_each_entry(counter, &evlist->entries, node) { + evlist__for_each(evlist, counter) { try_again: if (perf_evsel__open(counter, top->evlist->cpus, top->evlist->threads) < 0) { diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c index 0197bda..465cdbc 100644 --- a/tools/perf/tests/evsel-roundtrip-name.c +++ b/tools/perf/tests/evsel-roundtrip-name.c @@ -79,7 +79,7 @@ static int __perf_evsel__name_array_test(const char *names[], int nr_names) } err = 0; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { --err; pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c index 173bf42..2b6519e 100644 --- a/tools/perf/tests/hists_link.c +++ b/tools/perf/tests/hists_link.c @@ -208,7 +208,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine) * However the second evsel also has a collapsed entry for * "bash [libc] malloc" so total 9 entries will be in the tree. */ - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { const union perf_event event = { .header = { @@ -466,7 +466,7 @@ int test__hists_link(void) if (err < 0) goto out; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { hists__collapse_resort(&evsel->hists, NULL); if (verbose > 2) diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index aef25f0..1422634 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -126,7 +126,7 @@ int test__basic_mmap(void) } err = 0; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (nr_events[evsel->idx] != expected_nr_events[evsel->idx]) { pr_debug("expected %d %s events, got %d\n", expected_nr_events[evsel->idx], diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 41dee5e..4db0ae6 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -30,7 +30,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); TEST_ASSERT_VAL("wrong number of groups", 0 == evlist->nr_groups); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); TEST_ASSERT_VAL("wrong sample_type", @@ -201,7 +201,7 @@ test__checkevent_tracepoint_multi_modifier(struct perf_evlist *evlist) TEST_ASSERT_VAL("wrong number of entries", evlist->nr_entries > 1); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user); TEST_ASSERT_VAL("wrong exclude_kernel", diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a7045ea..b720b92 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1938,7 +1938,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, ui_helpline__push("Press ESC to exit"); - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { const char *ev_name = perf_evsel__name(pos); size_t line_len = strlen(ev_name) + 7; @@ -1970,9 +1970,10 @@ single_entry: struct perf_evsel *pos; nr_entries = 0; - list_for_each_entry(pos, &evlist->entries, node) + evlist__for_each(evlist, pos) { if (perf_evsel__is_group_leader(pos)) nr_entries++; + } if (nr_entries == 1) goto single_entry; diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 2ca66cc..5b95c44 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -375,7 +375,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, gtk_container_add(GTK_CONTAINER(window), vbox); - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { struct hists *hists = &pos->hists; const char *evname = perf_evsel__name(pos); GtkWidget *scrolled_window; diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 0922aa4..88f7be3 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -81,7 +81,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) /* * check if cgrp is already defined, if so we reuse it */ - list_for_each_entry(counter, &evlist->entries, node) { + evlist__for_each(evlist, counter) { cgrp = counter->cgrp; if (!cgrp) continue; @@ -110,7 +110,7 @@ static int add_cgroup(struct perf_evlist *evlist, char *str) * if add cgroup N, then need to find event N */ n = 0; - list_for_each_entry(counter, &evlist->entries, node) { + evlist__for_each(evlist, counter) { if (n == nr_cgroups) goto found; n++; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 0810f5c..40bd2c0 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -81,7 +81,7 @@ static void perf_evlist__update_id_pos(struct perf_evlist *evlist) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) + evlist__for_each(evlist, evsel) perf_evsel__calc_id_pos(evsel); perf_evlist__set_id_pos(evlist); @@ -91,7 +91,7 @@ static void perf_evlist__purge(struct perf_evlist *evlist) { struct perf_evsel *pos, *n; - list_for_each_entry_safe(pos, n, &evlist->entries, node) { + evlist__for_each_safe(evlist, n, pos) { list_del_init(&pos->node); perf_evsel__delete(pos); } @@ -148,7 +148,7 @@ void __perf_evlist__set_leader(struct list_head *list) leader->nr_members = evsel->idx - leader->idx + 1; - list_for_each_entry(evsel, list, node) { + __evlist__for_each(list, evsel) { evsel->leader = leader; } } @@ -207,7 +207,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist, return 0; out_delete_partial_list: - list_for_each_entry_safe(evsel, n, &head, node) + __evlist__for_each_safe(&head, n, evsel) perf_evsel__delete(evsel); return -1; } @@ -228,7 +228,7 @@ perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (evsel->attr.type == PERF_TYPE_TRACEPOINT && (int)evsel->attr.config == id) return evsel; @@ -243,7 +243,7 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist, { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if ((evsel->attr.type == PERF_TYPE_TRACEPOINT) && (strcmp(evsel->name, name) == 0)) return evsel; @@ -273,7 +273,7 @@ void perf_evlist__disable(struct perf_evlist *evlist) int nr_threads = thread_map__nr(evlist->threads); for (cpu = 0; cpu < nr_cpus; cpu++) { - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { if (!perf_evsel__is_group_leader(pos) || !pos->fd) continue; for (thread = 0; thread < nr_threads; thread++) @@ -291,7 +291,7 @@ void perf_evlist__enable(struct perf_evlist *evlist) int nr_threads = thread_map__nr(evlist->threads); for (cpu = 0; cpu < nr_cpus; cpu++) { - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { if (!perf_evsel__is_group_leader(pos) || !pos->fd) continue; for (thread = 0; thread < nr_threads; thread++) @@ -630,7 +630,7 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { int fd = FD(evsel, cpu, thread); if (*output == -1) { @@ -806,7 +806,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, pr_debug("mmap size %zuB\n", evlist->mmap_len); mask = evlist->mmap_len - page_size - 1; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if ((evsel->attr.read_format & PERF_FORMAT_ID) && evsel->sample_id == NULL && perf_evsel__alloc_id(evsel, cpu_map__nr(cpus), threads->nr) < 0) @@ -849,7 +849,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist) const int ncpus = cpu_map__nr(evlist->cpus), nthreads = thread_map__nr(evlist->threads); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (evsel->filter == NULL) continue; @@ -868,7 +868,7 @@ int perf_evlist__set_filter(struct perf_evlist *evlist, const char *filter) const int ncpus = cpu_map__nr(evlist->cpus), nthreads = thread_map__nr(evlist->threads); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { err = perf_evsel__set_filter(evsel, ncpus, nthreads, filter); if (err) break; @@ -887,7 +887,7 @@ bool perf_evlist__valid_sample_type(struct perf_evlist *evlist) if (evlist->id_pos < 0 || evlist->is_pos < 0) return false; - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { if (pos->id_pos != evlist->id_pos || pos->is_pos != evlist->is_pos) return false; @@ -903,7 +903,7 @@ u64 __perf_evlist__combined_sample_type(struct perf_evlist *evlist) if (evlist->combined_sample_type) return evlist->combined_sample_type; - list_for_each_entry(evsel, &evlist->entries, node) + evlist__for_each(evlist, evsel) evlist->combined_sample_type |= evsel->attr.sample_type; return evlist->combined_sample_type; @@ -921,7 +921,7 @@ bool perf_evlist__valid_read_format(struct perf_evlist *evlist) u64 read_format = first->attr.read_format; u64 sample_type = first->attr.sample_type; - list_for_each_entry_continue(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { if (read_format != pos->attr.read_format) return false; } @@ -978,7 +978,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist) { struct perf_evsel *first = perf_evlist__first(evlist), *pos = first; - list_for_each_entry_continue(pos, &evlist->entries, node) { + evlist__for_each_continue(evlist, pos) { if (first->attr.sample_id_all != pos->attr.sample_id_all) return false; } @@ -1004,7 +1004,7 @@ void perf_evlist__close(struct perf_evlist *evlist) int ncpus = cpu_map__nr(evlist->cpus); int nthreads = thread_map__nr(evlist->threads); - list_for_each_entry_reverse(evsel, &evlist->entries, node) + evlist__for_each_reverse(evlist, evsel) perf_evsel__close(evsel, ncpus, nthreads); } @@ -1015,7 +1015,7 @@ int perf_evlist__open(struct perf_evlist *evlist) perf_evlist__update_id_pos(evlist); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { err = perf_evsel__open(evsel, evlist->cpus, evlist->threads); if (err < 0) goto out_err; @@ -1154,7 +1154,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp) struct perf_evsel *evsel; size_t printed = 0; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", perf_evsel__name(evsel)); } @@ -1233,7 +1233,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist, if (move_evsel == perf_evlist__first(evlist)) return; - list_for_each_entry_safe(evsel, n, &evlist->entries, node) { + evlist__for_each_safe(evlist, n, evsel) { if (evsel->leader == move_evsel->leader) list_move_tail(&evsel->node, &move); } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 518e521..f5173cd 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -196,5 +196,70 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str); void perf_evlist__to_front(struct perf_evlist *evlist, struct perf_evsel *move_evsel); +/** + * __evlist__for_each - iterate thru all the evsels + * @list: list_head instance to iterate + * @evsel: struct evsel iterator + */ +#define __evlist__for_each(list, evsel) \ + list_for_each_entry(evsel, list, node) + +/** + * evlist__for_each - iterate thru all the evsels + * @evlist: evlist instance to iterate + * @evsel: struct evsel iterator + */ +#define evlist__for_each(evlist, evsel) \ + __evlist__for_each(&(evlist)->entries, evsel) + +/** + * __evlist__for_each_continue - continue iteration thru all the evsels + * @list: list_head instance to iterate + * @evsel: struct evsel iterator + */ +#define __evlist__for_each_continue(list, evsel) \ + list_for_each_entry_continue(evsel, list, node) + +/** + * evlist__for_each_continue - continue iteration thru all the evsels + * @evlist: evlist instance to iterate + * @evsel: struct evsel iterator + */ +#define evlist__for_each_continue(evlist, evsel) \ + __evlist__for_each_continue(&(evlist)->entries, evsel) + +/** + * __evlist__for_each_reverse - iterate thru all the evsels in reverse order + * @list: list_head instance to iterate + * @evsel: struct evsel iterator + */ +#define __evlist__for_each_reverse(list, evsel) \ + list_for_each_entry_reverse(evsel, list, node) + +/** + * evlist__for_each_reverse - iterate thru all the evsels in reverse order + * @evlist: evlist instance to iterate + * @evsel: struct evsel iterator + */ +#define evlist__for_each_reverse(evlist, evsel) \ + __evlist__for_each_reverse(&(evlist)->entries, evsel) + +/** + * __evlist__for_each_safe - safely iterate thru all the evsels + * @list: list_head instance to iterate + * @tmp: struct evsel temp iterator + * @evsel: struct evsel iterator + */ +#define __evlist__for_each_safe(list, tmp, evsel) \ + list_for_each_entry_safe(evsel, tmp, list, node) + +/** + * evlist__for_each_safe - safely iterate thru all the evsels + * @evlist: evlist instance to iterate + * @evsel: struct evsel iterator + * @tmp: struct evsel temp iterator + */ +#define evlist__for_each_safe(evlist, tmp, evsel) \ + __evlist__for_each_safe(&(evlist)->entries, tmp, evsel) #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index a4a60b7..bb3e0ed 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -643,8 +643,7 @@ static int write_event_desc(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return ret; - list_for_each_entry(evsel, &evlist->entries, node) { - + evlist__for_each(evlist, evsel) { ret = do_write(fd, &evsel->attr, sz); if (ret < 0) return ret; @@ -1092,7 +1091,7 @@ static int write_group_desc(int fd, struct perf_header *h __maybe_unused, if (ret < 0) return ret; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (perf_evsel__is_group_leader(evsel) && evsel->nr_members > 1) { const char *name = evsel->group_name ?: "{anon_group}"; @@ -1487,7 +1486,7 @@ static void print_group_desc(struct perf_header *ph, int fd __maybe_unused, session = container_of(ph, struct perf_session, header); - list_for_each_entry(evsel, &session->evlist->entries, node) { + evlist__for_each(session->evlist, evsel) { if (perf_evsel__is_group_leader(evsel) && evsel->nr_members > 1) { fprintf(fp, "# group: %s{%s", evsel->group_name ?: "", @@ -1768,7 +1767,7 @@ perf_evlist__find_by_index(struct perf_evlist *evlist, int idx) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (evsel->idx == idx) return evsel; } @@ -2071,7 +2070,7 @@ static int process_group_desc(struct perf_file_section *section __maybe_unused, session->evlist->nr_groups = nr_groups; i = nr = 0; - list_for_each_entry(evsel, &session->evlist->entries, node) { + evlist__for_each(session->evlist, evsel) { if (evsel->idx == (int) desc[i].leader_idx) { evsel->leader = evsel; /* {anon_group} is a dummy name */ @@ -2298,7 +2297,7 @@ int perf_session__write_header(struct perf_session *session, lseek(fd, sizeof(f_header), SEEK_SET); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(session->evlist, evsel) { evsel->id_offset = lseek(fd, 0, SEEK_CUR); err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); if (err < 0) { @@ -2309,7 +2308,7 @@ int perf_session__write_header(struct perf_session *session, attr_offset = lseek(fd, 0, SEEK_CUR); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { f_attr = (struct perf_file_attr){ .attr = evsel->attr, .ids = { @@ -2742,7 +2741,7 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist, { struct perf_evsel *pos; - list_for_each_entry(pos, &evlist->entries, node) { + evlist__for_each(evlist, pos) { if (pos->attr.type == PERF_TYPE_TRACEPOINT && perf_evsel__prepare_tracepoint_event(pos, pevent)) return -1; @@ -2890,7 +2889,7 @@ int perf_event__synthesize_attrs(struct perf_tool *tool, struct perf_evsel *evsel; int err = 0; - list_for_each_entry(evsel, &session->evlist->entries, node) { + evlist__for_each(session->evlist, evsel) { err = perf_event__synthesize_attr(tool, &evsel->attr, evsel->ids, evsel->id, process); if (err) { diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 0153435..a7f1b6a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -820,8 +820,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add) if (!add && get_event_modifier(&mod, str, NULL)) return -EINVAL; - list_for_each_entry(evsel, list, node) { - + __evlist__for_each(list, evsel) { if (add && get_event_modifier(&mod, str, evsel)) return -EINVAL; @@ -845,7 +844,7 @@ int parse_events_name(struct list_head *list, char *name) { struct perf_evsel *evsel; - list_for_each_entry(evsel, list, node) { + __evlist__for_each(list, evsel) { if (!evsel->name) evsel->name = strdup(name); } diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 4bf8ace..122669c 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -908,9 +908,10 @@ static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) if (i >= pevlist->evlist.nr_entries) return NULL; - list_for_each_entry(pos, &pevlist->evlist.entries, node) + evlist__for_each(&pevlist->evlist, pos) { if (i-- == 0) break; + } return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel)); } diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 104a475..3737625 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -89,19 +89,19 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) if (evlist->cpus->map[0] < 0) opts->no_inherit = true; - list_for_each_entry(evsel, &evlist->entries, node) + evlist__for_each(evlist, evsel) perf_evsel__config(evsel, opts); if (evlist->nr_entries > 1) { struct perf_evsel *first = perf_evlist__first(evlist); - list_for_each_entry(evsel, &evlist->entries, node) { + evlist__for_each(evlist, evsel) { if (evsel->attr.sample_type == first->attr.sample_type) continue; use_sample_identifier = perf_can_sample_identifier(); break; } - list_for_each_entry(evsel, &evlist->entries, node) + evlist__for_each(evlist, evsel) perf_evsel__set_sample_id(evsel, use_sample_identifier); } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8ffe29c..7acc03e 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1384,7 +1384,7 @@ bool perf_session__has_traces(struct perf_session *session, const char *msg) { struct perf_evsel *evsel; - list_for_each_entry(evsel, &session->evlist->entries, node) { + evlist__for_each(session->evlist, evsel) { if (evsel->attr.type == PERF_TYPE_TRACEPOINT) return true; } @@ -1442,7 +1442,7 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) ret += events_stats__fprintf(&session->stats, fp); - list_for_each_entry(pos, &session->evlist->entries, node) { + evlist__for_each(session->evlist, pos) { ret += fprintf(fp, "%s stats:\n", perf_evsel__name(pos)); ret += events_stats__fprintf(&pos->hists.stats, fp); } @@ -1464,7 +1464,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, { struct perf_evsel *pos; - list_for_each_entry(pos, &session->evlist->entries, node) { + evlist__for_each(session->evlist, pos) { if (pos->attr.type == type) return pos; } -- cgit v0.10.2 From 8a625c1f61f3dd5e4ea4b5b642650416aa101ce5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 9 Jan 2014 23:00:52 +0900 Subject: tools include: Move perf's linux/compiler.h to a generic place So that it can be shared with others like libtraceevent. Signed-off-by: Namhyung Kim Acked-by: Borislav Petkov Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1389276059-8829-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h new file mode 100644 index 0000000..0135ccf --- /dev/null +++ b/tools/include/linux/compiler.h @@ -0,0 +1,30 @@ +#ifndef _TOOLS_LINUX_COMPILER_H_ +#define _TOOLS_LINUX_COMPILER_H_ + +#ifndef __always_inline +# define __always_inline inline __attribute__((always_inline)) +#endif + +#define __user + +#ifndef __attribute_const__ +# define __attribute_const__ +#endif + +#ifndef __maybe_unused +# define __maybe_unused __attribute__((unused)) +#endif + +#ifndef __packed +# define __packed __attribute__((__packed__)) +#endif + +#ifndef __force +# define __force +#endif + +#ifndef __weak +# define __weak __attribute__((weak)) +#endif + +#endif /* _TOOLS_LINUX_COMPILER_H */ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 3638b0b..6be0676 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -211,7 +211,7 @@ LIB_H += ../../include/linux/hash.h LIB_H += ../../include/linux/stringify.h LIB_H += util/include/linux/bitmap.h LIB_H += util/include/linux/bitops.h -LIB_H += util/include/linux/compiler.h +LIB_H += ../include/linux/compiler.h LIB_H += util/include/linux/const.h LIB_H += util/include/linux/ctype.h LIB_H += util/include/linux/kernel.h diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5d15b43..01dd43d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -232,6 +232,7 @@ endif CFLAGS += -I$(src-perf)/util/include CFLAGS += -I$(src-perf)/arch/$(ARCH)/include +CFLAGS += -I$(srctree)/tools/include/ CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi CFLAGS += -I$(srctree)/arch/$(ARCH)/include CFLAGS += -I$(srctree)/include/uapi diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h deleted file mode 100644 index b003ad7..0000000 --- a/tools/perf/util/include/linux/compiler.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _PERF_LINUX_COMPILER_H_ -#define _PERF_LINUX_COMPILER_H_ - -#ifndef __always_inline -# define __always_inline inline __attribute__((always_inline)) -#endif - -#define __user - -#ifndef __attribute_const__ -# define __attribute_const__ -#endif - -#ifndef __maybe_unused -# define __maybe_unused __attribute__((unused)) -#endif - -#ifndef __packed -# define __packed __attribute__((__packed__)) -#endif - -#ifndef __force -# define __force -#endif - -#ifndef __weak -# define __weak __attribute__((weak)) -#endif - -#endif -- cgit v0.10.2 From 835d44b9041e578e3e553a57dfffc7003605c93b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 9 Jan 2014 23:00:53 +0900 Subject: tools include: Define likely/unlikely in linux/compiler.h Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1389276059-8829-3-git-send-email-namhyung@kernel.org [ Added the new header to tools/perf/MANIFEST ] Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index 0135ccf..fbc6665 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -27,4 +27,12 @@ # define __weak __attribute__((weak)) #endif +#ifndef likely +# define likely(x) __builtin_expect(!!(x), 1) +#endif + +#ifndef unlikely +# define unlikely(x) __builtin_expect(!!(x), 0) +#endif + #endif /* _TOOLS_LINUX_COMPILER_H */ diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 3170a7f..285f28f 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -4,6 +4,7 @@ tools/lib/traceevent tools/lib/lk tools/lib/symbol/kallsyms.c tools/lib/symbol/kallsyms.h +tools/include/linux/compiler.h include/linux/const.h include/linux/perf_event.h include/linux/rbtree.h -- cgit v0.10.2 From 02dfc8d775f0709ab494d4b2cce12c8429ff7530 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 9 Jan 2014 23:00:54 +0900 Subject: tools include: Move perf's bug.h to a generic place So that it can be shared with others like libtraceevent. Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1389276059-8829-4-git-send-email-namhyung@kernel.org [ Added the new header to tools/perf/MANIFEST ] Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h new file mode 100644 index 0000000..eca78df --- /dev/null +++ b/tools/include/asm/bug.h @@ -0,0 +1,23 @@ +#ifndef _TOOLS_ASM_BUG_H +#define _TOOLS_ASM_BUG_H + +#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0) + +#define WARN(condition, format...) ({ \ + int __ret_warn_on = !!(condition); \ + if (unlikely(__ret_warn_on)) \ + __WARN_printf(format); \ + unlikely(__ret_warn_on); \ +}) + +#define WARN_ONCE(condition, format...) ({ \ + static int __warned; \ + int __ret_warn_once = !!(condition); \ + \ + if (unlikely(__ret_warn_once)) \ + if (WARN(!__warned, format)) \ + __warned = 1; \ + unlikely(__ret_warn_once); \ +}) + +#endif /* _TOOLS_ASM_BUG_H */ diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 285f28f..4e53535 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -4,6 +4,7 @@ tools/lib/traceevent tools/lib/lk tools/lib/symbol/kallsyms.c tools/lib/symbol/kallsyms.h +tools/include/asm/bug.h tools/include/linux/compiler.h include/linux/const.h include/linux/perf_event.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 6be0676..87d7726 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -226,7 +226,7 @@ LIB_H += util/include/linux/string.h LIB_H += util/include/linux/types.h LIB_H += util/include/linux/linkage.h LIB_H += util/include/asm/asm-offsets.h -LIB_H += util/include/asm/bug.h +LIB_H += ../include/asm/bug.h LIB_H += util/include/asm/byteorder.h LIB_H += util/include/asm/hweight.h LIB_H += util/include/asm/swab.h diff --git a/tools/perf/util/include/asm/bug.h b/tools/perf/util/include/asm/bug.h deleted file mode 100644 index 7fcc681..0000000 --- a/tools/perf/util/include/asm/bug.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _PERF_ASM_GENERIC_BUG_H -#define _PERF_ASM_GENERIC_BUG_H - -#define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0) - -#define WARN(condition, format...) ({ \ - int __ret_warn_on = !!(condition); \ - if (unlikely(__ret_warn_on)) \ - __WARN_printf(format); \ - unlikely(__ret_warn_on); \ -}) - -#define WARN_ONCE(condition, format...) ({ \ - static int __warned; \ - int __ret_warn_once = !!(condition); \ - \ - if (unlikely(__ret_warn_once)) \ - if (WARN(!__warned, format)) \ - __warned = 1; \ - unlikely(__ret_warn_once); \ -}) -#endif -- cgit v0.10.2 From c023f534c31f69a658fc21d619116ad12c7be464 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 10 Jan 2014 16:25:05 -0300 Subject: perf tools: Include tools/lib/api/ in MANIFEST When 553873e1df63 renamed tools/lib/lk to tools/lib/api we forgot to do the switch in tools/perf/MANIFEST, breaking tarball building: [acme@ssdandy linux]$ make perf-targz-src-pkg TAR [acme@ssdandy linux]$ tar xf perf-3.13.0-rc4.tar.gz -C /tmp/tmp.OgdYyvp77p/ [acme@ssdandy linux]$ make -C /tmp/tmp.OgdYyvp77p/perf-3.13.0-rc4/tools/perf make: Entering directory `/tmp/tmp.OgdYyvp77p/perf-3.13.0-rc4/tools/perf' BUILD: Doing 'make -j8' parallel build FLEX util/pmu-flex.c CC util/evlist.o CC util/evsel.o util/evsel.c:12:28: fatal error: api/fs/debugfs.h: No such file or directory compilation terminated. In file included from util/cache.h:5:0, Fix it. Cc: Adrian Hunter Cc: Borislav Petkov Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-1wwjs01rt3xbyhn6kjl2gfs9@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 4e53535..f41572d 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -1,7 +1,7 @@ tools/perf tools/scripts tools/lib/traceevent -tools/lib/lk +tools/lib/api tools/lib/symbol/kallsyms.c tools/lib/symbol/kallsyms.h tools/include/asm/bug.h -- cgit v0.10.2 From 4887805384751717ef62a8f41439d1d3e4268b39 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 10 Jan 2014 16:46:45 -0300 Subject: perf tools: Add test for building detached source tarballs Test one of the main kernel Makefile targets to generate a perf sources tarball suitable for build outside the full kernel sources. This is to test that the tools/perf/MANIFEST file lists all the files needed to be in such tarball, which sometimes gets broken when we move files around, like when we made some files that were in tools/perf/ available to other tools/ codebases by moving it to tools/include/, etc. Now everytime we use 'make -C tools/perf -f tests/make' this test will be performed, helping detect such problems earlier in the devel cycle. Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-gyivwbbu2j7c4j4pwpmttg2p@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/tests/make b/tools/perf/tests/make index e341088..00544b8 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -216,10 +216,16 @@ $(run_O): rm -rf $$TMP_O \ rm -rf $$TMP_DEST -all: $(run) $(run_O) +tarpkg: + @cmd="$(PERF)/tests/perf-targz-src-pkg $(PERF)"; \ + echo "- $@: $$cmd" && echo $$cmd > $@ && \ + ( eval $$cmd ) >> $@ 2>&1 + + +all: $(run) $(run_O) tarpkg @echo OK out: $(run_O) @echo OK -.PHONY: all $(run) $(run_O) clean +.PHONY: all $(run) $(run_O) tarpkg clean diff --git a/tools/perf/tests/perf-targz-src-pkg b/tools/perf/tests/perf-targz-src-pkg new file mode 100755 index 0000000..238aa39 --- /dev/null +++ b/tools/perf/tests/perf-targz-src-pkg @@ -0,0 +1,21 @@ +#!/bin/sh +# Test one of the main kernel Makefile targets to generate a perf sources tarball +# suitable for build outside the full kernel sources. +# +# This is to test that the tools/perf/MANIFEST file lists all the files needed to +# be in such tarball, which sometimes gets broken when we move files around, +# like when we made some files that were in tools/perf/ available to other tools/ +# codebases by moving it to tools/include/, etc. + +PERF=$1 +cd ${PERF}/../.. +make perf-targz-src-pkg > /dev/null +TARBALL=$(ls -rt perf-*.tar.gz) +TMP_DEST=$(mktemp -d) +tar xf ${TARBALL} -C $TMP_DEST +rm -f ${TARBALL} +cd - > /dev/null +make -C $TMP_DEST/perf*/tools/perf > /dev/null 2>&1 +RC=$? +rm -rf ${TMP_DEST} +exit $RC -- cgit v0.10.2 From d11416e76b3e2f60ed6cfa7c532d3b6777f66527 Mon Sep 17 00:00:00 2001 From: Jean Pihet Date: Mon, 16 Dec 2013 17:43:14 +0100 Subject: perf tools: Use the DWARF unwind info only if loaded Use the info only if it has been found in the .debug_frame section of the ELF binary. Signed-off-by: Jean Pihet Acked-by: Jiri Olsa Cc: Ingo Molnar Cc: Jiri Olsa Cc: Will Deacon Cc: linaro-kernel@lists.linaro.org Cc: patches@linaro.org Link: http://lkml.kernel.org/r/1387212194-8028-1-git-send-email-jean.pihet@linaro.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c index 0efd539..416f22b 100644 --- a/tools/perf/util/unwind.c +++ b/tools/perf/util/unwind.c @@ -340,10 +340,10 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi, /* Check the .debug_frame section for unwinding info */ if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) { memset(&di, 0, sizeof(di)); - dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name, - map->start, map->end); - return dwarf_search_unwind_table(as, ip, &di, pi, - need_unwind_info, arg); + if (dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name, + map->start, map->end)) + return dwarf_search_unwind_table(as, ip, &di, pi, + need_unwind_info, arg); } #endif -- cgit v0.10.2 From 6619a53ef7572b9eaf7aa71ff7f74c0d06b3817b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 11 Jan 2014 13:38:27 -0800 Subject: perf record: Add --initial-delay option perf stat has a --delay option to delay measuring the workload. This is useful to skip measuring the startup phase of the program, which is often very different from the main workload. The same is useful for perf record when sampling. --no-delay was already taken, so add a --initial-delay to perf record too. -D was already taken for record, so there is only a long option. v2: Don't disable group members (Namhyung Kim) v3: port to latest perf/core rename to --initial-delay to avoid conflict with --no-delay Signed-off-by: Andi Kleen Acked-by: Namhyung Kim Cc: Jiri Olsa Cc: Namhyung Kim Link: http://lkml.kernel.org/r/1389476307-2124-1-git-send-email-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index c407897..82bffac 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -209,6 +209,10 @@ overrides that and uses per-thread mmaps. A side-effect of that is that inheritance is automatically disabled. --per-thread is ignored with a warning if combined with -a or -C options. +--initial-delay msecs:: +After starting the program, wait msecs before measuring. This is useful to +filter out the startup phase of the program, which is often very different. + SEE ALSO -------- linkperf:perf-stat[1], linkperf:perf-list[1] diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 8860015..07d4cf8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -499,7 +499,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) * (apart from group members) have enable_on_exec=1 set, * so don't spoil it by prematurely enabling them. */ - if (!target__none(&opts->target)) + if (!target__none(&opts->target) && !opts->initial_delay) perf_evlist__enable(rec->evlist); /* @@ -508,6 +508,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (forks) perf_evlist__start_workload(rec->evlist); + if (opts->initial_delay) { + usleep(opts->initial_delay * 1000); + perf_evlist__enable(rec->evlist); + } + for (;;) { int hits = rec->samples; @@ -877,6 +882,8 @@ const struct option record_options[] = { OPT_CALLBACK('G', "cgroup", &record.evlist, "name", "monitor event in cgroup name only", parse_cgroups), + OPT_UINTEGER(0, "initial-delay", &record.opts.initial_delay, + "ms to wait before starting measurement after program start"), OPT_STRING('u', "uid", &record.opts.target.uid_str, "user", "user to profile"), diff --git a/tools/perf/perf.h b/tools/perf/perf.h index b1cc84b..af1ce6e 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -269,6 +269,7 @@ struct record_opts { u64 user_interval; u16 stack_dump_size; bool sample_transaction; + unsigned initial_delay; }; #endif diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ade8d9c..cd4630a 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -658,7 +658,8 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) * Setting enable_on_exec for independent events and * group leaders for traced executed by perf. */ - if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel)) + if (target__none(&opts->target) && perf_evsel__is_group_leader(evsel) && + !opts->initial_delay) attr->enable_on_exec = 1; } -- cgit v0.10.2 From 741a0c59032faeddac80a6237f3d7846231a3740 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 9 Jan 2014 23:00:55 +0900 Subject: tools include: Include from asm/bug.h Since it uses unlikely() macro inside WARN() Signed-off-by: Namhyung Kim Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1389276059-8829-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/include/asm/bug.h b/tools/include/asm/bug.h index eca78df..9e5f484 100644 --- a/tools/include/asm/bug.h +++ b/tools/include/asm/bug.h @@ -1,6 +1,8 @@ #ifndef _TOOLS_ASM_BUG_H #define _TOOLS_ASM_BUG_H +#include + #define __WARN_printf(arg...) do { fprintf(stderr, arg); } while (0) #define WARN(condition, format...) ({ \ -- cgit v0.10.2 From f77c6e9c8f9c444cd44423df0c2708e86a06a696 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 30 Dec 2013 13:04:18 +0530 Subject: perf tools: Generalize percent_color_snprintf() Make percent_color_snprintf() handle negative values correctly. Signed-off-by: Ramkumar Ramachandra Acked-by: Jiri Olsa Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1388388861-7931-2-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 66e44a5..8cda46c 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -1,6 +1,7 @@ #include #include "cache.h" #include "color.h" +#include int perf_use_color_default = -1; @@ -298,10 +299,10 @@ const char *get_percent_color(double percent) * entries in green - and keep the low overhead places * normal: */ - if (percent >= MIN_RED) + if (fabs(percent) >= MIN_RED) color = PERF_COLOR_RED; else { - if (percent > MIN_GREEN) + if (fabs(percent) > MIN_GREEN) color = PERF_COLOR_GREEN; } return color; -- cgit v0.10.2 From 01f10bc85f538cd681d0a3338b97a33f308d944b Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 30 Dec 2013 13:04:19 +0530 Subject: perf diff: Color the Delta column Color the numbers in the Delta column using percent_color_snprintf(). Generalize the coloring function so that we can accommodate all three comparison methods in future patches: delta, ratio, and wdiff. Signed-off-by: Ramkumar Ramachandra Acked-by: Jiri Olsa Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1388388861-7931-3-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 987cac3..6c3f220 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -770,6 +770,45 @@ static int hpp__entry_baseline(struct hist_entry *he, char *buf, size_t size) return ret; } +static int __hpp__color_compare(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp, struct hist_entry *he, + int comparison_method) +{ + struct diff_hpp_fmt *dfmt = + container_of(fmt, struct diff_hpp_fmt, fmt); + struct hist_entry *pair = get_pair_fmt(he, dfmt); + double diff; + char pfmt[20] = " "; + + if (!pair) + goto dummy_print; + + switch (comparison_method) { + case COMPUTE_DELTA: + if (pair->diff.computed) + diff = pair->diff.period_ratio_delta; + else + diff = compute_delta(he, pair); + + if (fabs(diff) < 0.01) + goto dummy_print; + scnprintf(pfmt, 20, "%%%+d.2f%%%%", dfmt->header_width - 1); + return percent_color_snprintf(hpp->buf, hpp->size, + pfmt, diff); + default: + BUG_ON(1); + } +dummy_print: + return scnprintf(hpp->buf, hpp->size, "%*s", + dfmt->header_width, pfmt); +} + +static int hpp__color_delta(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp, struct hist_entry *he) +{ + return __hpp__color_compare(fmt, hpp, he, COMPUTE_DELTA); +} + static void hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size) { @@ -941,8 +980,16 @@ static void data__hpp_register(struct data__file *d, int idx) fmt->entry = hpp__entry_global; /* TODO more colors */ - if (idx == PERF_HPP_DIFF__BASELINE) + switch (idx) { + case PERF_HPP_DIFF__BASELINE: fmt->color = hpp__color_baseline; + break; + case PERF_HPP_DIFF__DELTA: + fmt->color = hpp__color_delta; + break; + default: + break; + } init_header(d, dfmt); perf_hpp__column_register(fmt); -- cgit v0.10.2 From 1f513b2c1e8a2008b8ab767fdb6fa6c154591ed3 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 30 Dec 2013 13:04:20 +0530 Subject: perf diff: Color the Ratio column In $ perf diff -c ratio color the Ratio column using value_color_snprintf(), a new function that operates exactly like percent_color_snprintf(). At first glance, it looks like percent_color_snprintf() can be turned into a non-variadic function simplifying things; however, 53805ec (perf tools: Remove cast of non-variadic function to variadic, 2013-10-31) explains why it needs to be a variadic function. Signed-off-by: Ramkumar Ramachandra Acked-by: Jiri Olsa Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1388388861-7931-4-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 6c3f220..73d8bff 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -795,6 +795,17 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt, scnprintf(pfmt, 20, "%%%+d.2f%%%%", dfmt->header_width - 1); return percent_color_snprintf(hpp->buf, hpp->size, pfmt, diff); + case COMPUTE_RATIO: + if (he->dummy) + goto dummy_print; + if (pair->diff.computed) + diff = pair->diff.period_ratio; + else + diff = compute_ratio(he, pair); + + scnprintf(pfmt, 20, "%%%d.6f", dfmt->header_width); + return value_color_snprintf(hpp->buf, hpp->size, + pfmt, diff); default: BUG_ON(1); } @@ -809,6 +820,12 @@ static int hpp__color_delta(struct perf_hpp_fmt *fmt, return __hpp__color_compare(fmt, hpp, he, COMPUTE_DELTA); } +static int hpp__color_ratio(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp, struct hist_entry *he) +{ + return __hpp__color_compare(fmt, hpp, he, COMPUTE_RATIO); +} + static void hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size) { @@ -987,6 +1004,9 @@ static void data__hpp_register(struct data__file *d, int idx) case PERF_HPP_DIFF__DELTA: fmt->color = hpp__color_delta; break; + case PERF_HPP_DIFF__RATIO: + fmt->color = hpp__color_ratio; + break; default: break; } diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 8cda46c..87b8672 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -319,15 +319,19 @@ int percent_color_fprintf(FILE *fp, const char *fmt, double percent) return r; } +int value_color_snprintf(char *bf, size_t size, const char *fmt, double value) +{ + const char *color = get_percent_color(value); + return color_snprintf(bf, size, color, fmt, value); +} + int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...) { va_list args; double percent; - const char *color; va_start(args, fmt); percent = va_arg(args, double); va_end(args); - color = get_percent_color(percent); - return color_snprintf(bf, size, color, fmt, percent); + return value_color_snprintf(bf, size, fmt, percent); } diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h index fced384..7ff30a6 100644 --- a/tools/perf/util/color.h +++ b/tools/perf/util/color.h @@ -39,6 +39,7 @@ int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); int color_snprintf(char *bf, size_t size, const char *color, const char *fmt, ...); int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); +int value_color_snprintf(char *bf, size_t size, const char *fmt, double value); int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...); int percent_color_fprintf(FILE *fp, const char *fmt, double percent); const char *get_percent_color(double percent); -- cgit v0.10.2 From a5846e215bd47f61133383822422c683600efa7a Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Mon, 30 Dec 2013 13:32:35 +0530 Subject: perf diff: Color the Weighted Diff column In $ perf diff -c wdiff:M,N color the numbers in the Weighted Diff column using color_snprintf(), picking the colors using get_percent_color(). Signed-off-by: Ramkumar Ramachandra Acked-by: Jiri Olsa Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1388390555-10808-1-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 73d8bff..a77e312 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -778,6 +778,7 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt, container_of(fmt, struct diff_hpp_fmt, fmt); struct hist_entry *pair = get_pair_fmt(he, dfmt); double diff; + s64 wdiff; char pfmt[20] = " "; if (!pair) @@ -806,6 +807,18 @@ static int __hpp__color_compare(struct perf_hpp_fmt *fmt, scnprintf(pfmt, 20, "%%%d.6f", dfmt->header_width); return value_color_snprintf(hpp->buf, hpp->size, pfmt, diff); + case COMPUTE_WEIGHTED_DIFF: + if (he->dummy) + goto dummy_print; + if (pair->diff.computed) + wdiff = pair->diff.wdiff; + else + wdiff = compute_wdiff(he, pair); + + scnprintf(pfmt, 20, "%%14ld", dfmt->header_width); + return color_snprintf(hpp->buf, hpp->size, + get_percent_color(wdiff), + pfmt, wdiff); default: BUG_ON(1); } @@ -826,6 +839,12 @@ static int hpp__color_ratio(struct perf_hpp_fmt *fmt, return __hpp__color_compare(fmt, hpp, he, COMPUTE_RATIO); } +static int hpp__color_wdiff(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp, struct hist_entry *he) +{ + return __hpp__color_compare(fmt, hpp, he, COMPUTE_WEIGHTED_DIFF); +} + static void hpp__entry_unpair(struct hist_entry *he, int idx, char *buf, size_t size) { @@ -1007,6 +1026,9 @@ static void data__hpp_register(struct data__file *d, int idx) case PERF_HPP_DIFF__RATIO: fmt->color = hpp__color_ratio; break; + case PERF_HPP_DIFF__WEIGHTED_DIFF: + fmt->color = hpp__color_wdiff; + break; default: break; } -- cgit v0.10.2 From 1d027ee9b80c30e83769ef306ccfafe483dd1672 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 13 Jan 2014 15:15:25 -0300 Subject: perf probe: Fix build when DWARF support libraries not present MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On a freshly installed system, after libelf-dev is installed we get: CC /tmp/build/perf/util/probe-event.o util/probe-event.c: In function ‘try_to_find_probe_trace_events’: util/probe-event.c:753:46: error: unused parameter ‘target’ [-Werror=unused-parameter] int max_tevs __maybe_unused, const char *target) ^ CC /tmp/build/perf/util/cgroup.o util/probe-event.c: At top level: util/probe-event.c:193:12: error: ‘get_text_start_address’ defined but not used [-Werror=unused-function] static int get_text_start_address(const char *exec, unsigned long *address) ^ cc1: all warnings being treated as errors make[1]: *** [/tmp/build/perf/util/probe-event.o] Error 1 make[1]: *** Waiting for unfinished jobs.... make: *** [install] Error 2 Fix it by enclosing functions only used when those libraries are installed under the suitable preprocessor define and using __maybe_unused to a function that is only built when DWARF support is disabled. Problem introduced in this changeset: commit fb7345bbf7fad9bf72ef63a19c707970b9685812 Author: Masami Hiramatsu Date: Thu Dec 26 05:41:53 2013 +0000 perf probe: Support basic dwarf-based operations on uprobe events Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-73kc2fopt81517hrdgdra18o@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 86ed858..a4ee6b4 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -172,6 +172,7 @@ const char *kernel_get_module_path(const char *module) return (dso) ? dso->long_name : NULL; } +#ifdef HAVE_DWARF_SUPPORT /* Copied from unwind.c */ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp, const char *name) @@ -217,6 +218,7 @@ out: elf_end(elf); return ret; } +#endif static int init_user_exec(void) { @@ -750,7 +752,8 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct probe_trace_event **tevs __maybe_unused, - int max_tevs __maybe_unused, const char *target) + int max_tevs __maybe_unused, + const char *target __maybe_unused) { if (perf_probe_event_need_dwarf(pev)) { pr_warning("Debuginfo-analysis is not supported.\n"); -- cgit v0.10.2 From 26f7f9877234e6b9ed87eff4ca450631bafe0182 Mon Sep 17 00:00:00 2001 From: Yann Droneaud Date: Sat, 11 Jan 2014 18:48:15 +0100 Subject: perf tools: Remove unused test-volatile-register-var.c Since commit 01287e2cb7ad, test-volatile-register-var.c is no more built as part of the automatic feature check. This patch remove the unneeded file. Signed-off-by: Yann Droneaud Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/339d86ad76741ed929defd18541f774b404003b4.1389461371.git.ydroneaud@opteya.com Signed-off-by: Arnaldo Carvalho de Melo diff --git a/tools/perf/config/feature-checks/test-volatile-register-var.c b/tools/perf/config/feature-checks/test-volatile-register-var.c deleted file mode 100644 index c9f398d..0000000 --- a/tools/perf/config/feature-checks/test-volatile-register-var.c +++ /dev/null @@ -1,6 +0,0 @@ -#include - -int main(void) -{ - return puts("hi"); -} -- cgit v0.10.2