diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 8 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 60 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 12 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 65 | ||||
-rw-r--r-- | tools/perf/builtin-test.c | 12 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 51 | ||||
-rw-r--r-- | tools/perf/perf.h | 8 | ||||
-rw-r--r-- | tools/perf/ui/browsers/annotate.c | 6 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 4 | ||||
-rw-r--r-- | tools/perf/ui/gtk/browser.c | 31 | ||||
-rw-r--r-- | tools/perf/ui/gtk/setup.c | 12 | ||||
-rw-r--r-- | tools/perf/ui/setup.c | 168 | ||||
-rw-r--r-- | tools/perf/ui/tui/setup.c | 140 | ||||
-rw-r--r-- | tools/perf/util/cache.h | 24 | ||||
-rw-r--r-- | tools/perf/util/debug.c | 1 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 16 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 4 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 9 | ||||
-rw-r--r-- | tools/perf/util/header.c | 17 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 2 | ||||
-rw-r--r-- | tools/perf/util/session.c | 30 | ||||
-rw-r--r-- | tools/perf/util/target.c | 142 | ||||
-rw-r--r-- | tools/perf/util/target.h | 64 | ||||
-rw-r--r-- | tools/perf/util/top.c | 19 | ||||
-rw-r--r-- | tools/perf/util/top.h | 6 | ||||
-rw-r--r-- | tools/perf/util/usage.c | 38 | ||||
-rw-r--r-- | tools/perf/util/util.h | 3 |
27 files changed, 583 insertions, 369 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index e98e14c88532..4734f41f801d 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -300,6 +300,7 @@ LIB_H += util/cpumap.h | |||
300 | LIB_H += util/top.h | 300 | LIB_H += util/top.h |
301 | LIB_H += $(ARCH_INCLUDE) | 301 | LIB_H += $(ARCH_INCLUDE) |
302 | LIB_H += util/cgroup.h | 302 | LIB_H += util/cgroup.h |
303 | LIB_H += util/target.h | ||
303 | 304 | ||
304 | LIB_OBJS += $(OUTPUT)util/abspath.o | 305 | LIB_OBJS += $(OUTPUT)util/abspath.o |
305 | LIB_OBJS += $(OUTPUT)util/alias.o | 306 | LIB_OBJS += $(OUTPUT)util/alias.o |
@@ -361,6 +362,7 @@ LIB_OBJS += $(OUTPUT)util/util.o | |||
361 | LIB_OBJS += $(OUTPUT)util/xyarray.o | 362 | LIB_OBJS += $(OUTPUT)util/xyarray.o |
362 | LIB_OBJS += $(OUTPUT)util/cpumap.o | 363 | LIB_OBJS += $(OUTPUT)util/cpumap.o |
363 | LIB_OBJS += $(OUTPUT)util/cgroup.o | 364 | LIB_OBJS += $(OUTPUT)util/cgroup.o |
365 | LIB_OBJS += $(OUTPUT)util/target.o | ||
364 | 366 | ||
365 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o | 367 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o |
366 | 368 | ||
@@ -481,6 +483,7 @@ else | |||
481 | LIB_OBJS += $(OUTPUT)ui/helpline.o | 483 | LIB_OBJS += $(OUTPUT)ui/helpline.o |
482 | LIB_OBJS += $(OUTPUT)ui/progress.o | 484 | LIB_OBJS += $(OUTPUT)ui/progress.o |
483 | LIB_OBJS += $(OUTPUT)ui/util.o | 485 | LIB_OBJS += $(OUTPUT)ui/util.o |
486 | LIB_OBJS += $(OUTPUT)ui/tui/setup.o | ||
484 | LIB_H += ui/browser.h | 487 | LIB_H += ui/browser.h |
485 | LIB_H += ui/browsers/map.h | 488 | LIB_H += ui/browsers/map.h |
486 | LIB_H += ui/helpline.h | 489 | LIB_H += ui/helpline.h |
@@ -503,6 +506,11 @@ else | |||
503 | BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) | 506 | BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0) |
504 | EXTLIBS += $(shell pkg-config --libs gtk+-2.0) | 507 | EXTLIBS += $(shell pkg-config --libs gtk+-2.0) |
505 | LIB_OBJS += $(OUTPUT)ui/gtk/browser.o | 508 | LIB_OBJS += $(OUTPUT)ui/gtk/browser.o |
509 | LIB_OBJS += $(OUTPUT)ui/gtk/setup.o | ||
510 | # Make sure that it'd be included only once. | ||
511 | ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),) | ||
512 | LIB_OBJS += $(OUTPUT)ui/setup.o | ||
513 | endif | ||
506 | endif | 514 | endif |
507 | endif | 515 | endif |
508 | 516 | ||
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 10b1f1f25ed7..d19058a7b84c 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -44,7 +44,6 @@ struct perf_record { | |||
44 | struct perf_evlist *evlist; | 44 | struct perf_evlist *evlist; |
45 | struct perf_session *session; | 45 | struct perf_session *session; |
46 | const char *progname; | 46 | const char *progname; |
47 | const char *uid_str; | ||
48 | int output; | 47 | int output; |
49 | unsigned int page_size; | 48 | unsigned int page_size; |
50 | int realtime_prio; | 49 | int realtime_prio; |
@@ -218,7 +217,7 @@ try_again: | |||
218 | if (err == EPERM || err == EACCES) { | 217 | if (err == EPERM || err == EACCES) { |
219 | ui__error_paranoid(); | 218 | ui__error_paranoid(); |
220 | exit(EXIT_FAILURE); | 219 | exit(EXIT_FAILURE); |
221 | } else if (err == ENODEV && opts->cpu_list) { | 220 | } else if (err == ENODEV && opts->target.cpu_list) { |
222 | die("No such device - did you specify" | 221 | die("No such device - did you specify" |
223 | " an out-of-range profile CPU?\n"); | 222 | " an out-of-range profile CPU?\n"); |
224 | } else if (err == EINVAL) { | 223 | } else if (err == EINVAL) { |
@@ -243,9 +242,13 @@ try_again: | |||
243 | /* | 242 | /* |
244 | * If it's cycles then fall back to hrtimer | 243 | * If it's cycles then fall back to hrtimer |
245 | * based cpu-clock-tick sw counter, which | 244 | * based cpu-clock-tick sw counter, which |
246 | * is always available even if no PMU support: | 245 | * is always available even if no PMU support. |
246 | * | ||
247 | * PPC returns ENXIO until 2.6.37 (behavior changed | ||
248 | * with commit b0a873e). | ||
247 | */ | 249 | */ |
248 | if (err == ENOENT && attr->type == PERF_TYPE_HARDWARE | 250 | if ((err == ENOENT || err == ENXIO) |
251 | && attr->type == PERF_TYPE_HARDWARE | ||
249 | && attr->config == PERF_COUNT_HW_CPU_CYCLES) { | 252 | && attr->config == PERF_COUNT_HW_CPU_CYCLES) { |
250 | 253 | ||
251 | if (verbose) | 254 | if (verbose) |
@@ -253,6 +256,10 @@ try_again: | |||
253 | "trying to fall back to cpu-clock-ticks\n"); | 256 | "trying to fall back to cpu-clock-ticks\n"); |
254 | attr->type = PERF_TYPE_SOFTWARE; | 257 | attr->type = PERF_TYPE_SOFTWARE; |
255 | attr->config = PERF_COUNT_SW_CPU_CLOCK; | 258 | attr->config = PERF_COUNT_SW_CPU_CLOCK; |
259 | if (pos->name) { | ||
260 | free(pos->name); | ||
261 | pos->name = NULL; | ||
262 | } | ||
256 | goto try_again; | 263 | goto try_again; |
257 | } | 264 | } |
258 | 265 | ||
@@ -578,7 +585,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
578 | perf_session__process_machines(session, tool, | 585 | perf_session__process_machines(session, tool, |
579 | perf_event__synthesize_guest_os); | 586 | perf_event__synthesize_guest_os); |
580 | 587 | ||
581 | if (!opts->system_wide) | 588 | if (!opts->target.system_wide) |
582 | perf_event__synthesize_thread_map(tool, evsel_list->threads, | 589 | perf_event__synthesize_thread_map(tool, evsel_list->threads, |
583 | process_synthesized_event, | 590 | process_synthesized_event, |
584 | machine); | 591 | machine); |
@@ -765,9 +772,9 @@ const struct option record_options[] = { | |||
765 | parse_events_option), | 772 | parse_events_option), |
766 | OPT_CALLBACK(0, "filter", &record.evlist, "filter", | 773 | OPT_CALLBACK(0, "filter", &record.evlist, "filter", |
767 | "event filter", parse_filter), | 774 | "event filter", parse_filter), |
768 | OPT_STRING('p', "pid", &record.opts.target_pid, "pid", | 775 | OPT_STRING('p', "pid", &record.opts.target.pid, "pid", |
769 | "record events on existing process id"), | 776 | "record events on existing process id"), |
770 | OPT_STRING('t', "tid", &record.opts.target_tid, "tid", | 777 | OPT_STRING('t', "tid", &record.opts.target.tid, "tid", |
771 | "record events on existing thread id"), | 778 | "record events on existing thread id"), |
772 | OPT_INTEGER('r', "realtime", &record.realtime_prio, | 779 | OPT_INTEGER('r', "realtime", &record.realtime_prio, |
773 | "collect data with this RT SCHED_FIFO priority"), | 780 | "collect data with this RT SCHED_FIFO priority"), |
@@ -775,11 +782,11 @@ const struct option record_options[] = { | |||
775 | "collect data without buffering"), | 782 | "collect data without buffering"), |
776 | OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples, | 783 | OPT_BOOLEAN('R', "raw-samples", &record.opts.raw_samples, |
777 | "collect raw sample records from all opened counters"), | 784 | "collect raw sample records from all opened counters"), |
778 | OPT_BOOLEAN('a', "all-cpus", &record.opts.system_wide, | 785 | OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, |
779 | "system-wide collection from all CPUs"), | 786 | "system-wide collection from all CPUs"), |
780 | OPT_BOOLEAN('A', "append", &record.append_file, | 787 | OPT_BOOLEAN('A', "append", &record.append_file, |
781 | "append to the output file to do incremental profiling"), | 788 | "append to the output file to do incremental profiling"), |
782 | OPT_STRING('C', "cpu", &record.opts.cpu_list, "cpu", | 789 | OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", |
783 | "list of cpus to monitor"), | 790 | "list of cpus to monitor"), |
784 | OPT_BOOLEAN('f', "force", &record.force, | 791 | OPT_BOOLEAN('f', "force", &record.force, |
785 | "overwrite existing data file (deprecated)"), | 792 | "overwrite existing data file (deprecated)"), |
@@ -813,7 +820,8 @@ const struct option record_options[] = { | |||
813 | OPT_CALLBACK('G', "cgroup", &record.evlist, "name", | 820 | OPT_CALLBACK('G', "cgroup", &record.evlist, "name", |
814 | "monitor event in cgroup name only", | 821 | "monitor event in cgroup name only", |
815 | parse_cgroups), | 822 | parse_cgroups), |
816 | OPT_STRING('u', "uid", &record.uid_str, "user", "user to profile"), | 823 | OPT_STRING('u', "uid", &record.opts.target.uid_str, "user", |
824 | "user to profile"), | ||
817 | 825 | ||
818 | OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, | 826 | OPT_CALLBACK_NOOPT('b', "branch-any", &record.opts.branch_stack, |
819 | "branch any", "sample any taken branches", | 827 | "branch any", "sample any taken branches", |
@@ -831,6 +839,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
831 | struct perf_evsel *pos; | 839 | struct perf_evsel *pos; |
832 | struct perf_evlist *evsel_list; | 840 | struct perf_evlist *evsel_list; |
833 | struct perf_record *rec = &record; | 841 | struct perf_record *rec = &record; |
842 | char errbuf[BUFSIZ]; | ||
834 | 843 | ||
835 | perf_header__set_cmdline(argc, argv); | 844 | perf_header__set_cmdline(argc, argv); |
836 | 845 | ||
@@ -842,8 +851,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
842 | 851 | ||
843 | argc = parse_options(argc, argv, record_options, record_usage, | 852 | argc = parse_options(argc, argv, record_options, record_usage, |
844 | PARSE_OPT_STOP_AT_NON_OPTION); | 853 | PARSE_OPT_STOP_AT_NON_OPTION); |
845 | if (!argc && !rec->opts.target_pid && !rec->opts.target_tid && | 854 | if (!argc && perf_target__none(&rec->opts.target)) |
846 | !rec->opts.system_wide && !rec->opts.cpu_list && !rec->uid_str) | ||
847 | usage_with_options(record_usage, record_options); | 855 | usage_with_options(record_usage, record_options); |
848 | 856 | ||
849 | if (rec->force && rec->append_file) { | 857 | if (rec->force && rec->append_file) { |
@@ -856,7 +864,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
856 | rec->write_mode = WRITE_FORCE; | 864 | rec->write_mode = WRITE_FORCE; |
857 | } | 865 | } |
858 | 866 | ||
859 | if (nr_cgroups && !rec->opts.system_wide) { | 867 | if (nr_cgroups && !rec->opts.target.system_wide) { |
860 | fprintf(stderr, "cgroup monitoring only available in" | 868 | fprintf(stderr, "cgroup monitoring only available in" |
861 | " system-wide mode\n"); | 869 | " system-wide mode\n"); |
862 | usage_with_options(record_usage, record_options); | 870 | usage_with_options(record_usage, record_options); |
@@ -883,17 +891,25 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
883 | goto out_symbol_exit; | 891 | goto out_symbol_exit; |
884 | } | 892 | } |
885 | 893 | ||
886 | rec->opts.uid = parse_target_uid(rec->uid_str, rec->opts.target_tid, | 894 | err = perf_target__validate(&rec->opts.target); |
887 | rec->opts.target_pid); | 895 | if (err) { |
888 | if (rec->uid_str != NULL && rec->opts.uid == UINT_MAX - 1) | 896 | perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); |
889 | goto out_free_fd; | 897 | ui__warning("%s", errbuf); |
898 | } | ||
899 | |||
900 | err = perf_target__parse_uid(&rec->opts.target); | ||
901 | if (err) { | ||
902 | int saved_errno = errno; | ||
890 | 903 | ||
891 | if (rec->opts.target_pid) | 904 | perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); |
892 | rec->opts.target_tid = rec->opts.target_pid; | 905 | ui__warning("%s", errbuf); |
906 | |||
907 | err = -saved_errno; | ||
908 | goto out_free_fd; | ||
909 | } | ||
893 | 910 | ||
894 | if (perf_evlist__create_maps(evsel_list, rec->opts.target_pid, | 911 | err = -ENOMEM; |
895 | rec->opts.target_tid, rec->opts.uid, | 912 | if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) |
896 | rec->opts.cpu_list) < 0) | ||
897 | usage_with_options(record_usage, record_options); | 913 | usage_with_options(record_usage, record_options); |
898 | 914 | ||
899 | list_for_each_entry(pos, &evsel_list->entries, node) { | 915 | list_for_each_entry(pos, &evsel_list->entries, node) { |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index cec2b8cee80c..74776558ddfb 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -304,7 +304,7 @@ static size_t hists__fprintf_nr_sample_events(struct hists *self, | |||
304 | if (evname != NULL) | 304 | if (evname != NULL) |
305 | ret += fprintf(fp, " of event '%s'", evname); | 305 | ret += fprintf(fp, " of event '%s'", evname); |
306 | 306 | ||
307 | ret += fprintf(fp, "\n# Event count (approx.): %lu", nr_events); | 307 | ret += fprintf(fp, "\n# Event count (approx.): %" PRIu64, nr_events); |
308 | return ret + fprintf(fp, "\n#\n"); | 308 | return ret + fprintf(fp, "\n#\n"); |
309 | } | 309 | } |
310 | 310 | ||
@@ -676,14 +676,10 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
676 | 676 | ||
677 | } | 677 | } |
678 | 678 | ||
679 | if (strcmp(report.input_name, "-") != 0) { | 679 | if (strcmp(report.input_name, "-") != 0) |
680 | if (report.use_gtk) | 680 | setup_browser(true); |
681 | perf_gtk_setup_browser(argc, argv, true); | 681 | else |
682 | else | ||
683 | setup_browser(true); | ||
684 | } else { | ||
685 | use_browser = 0; | 682 | use_browser = 0; |
686 | } | ||
687 | 683 | ||
688 | /* | 684 | /* |
689 | * Only in the newt browser we are doing integrated annotation, | 685 | * Only in the newt browser we are doing integrated annotation, |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index dde9e17c018b..d0605689bad9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -175,22 +175,21 @@ static struct perf_event_attr very_very_detailed_attrs[] = { | |||
175 | 175 | ||
176 | static struct perf_evlist *evsel_list; | 176 | static struct perf_evlist *evsel_list; |
177 | 177 | ||
178 | static bool system_wide = false; | 178 | static struct perf_target target = { |
179 | static int run_idx = 0; | 179 | .uid = UINT_MAX, |
180 | }; | ||
180 | 181 | ||
182 | static int run_idx = 0; | ||
181 | static int run_count = 1; | 183 | static int run_count = 1; |
182 | static bool no_inherit = false; | 184 | static bool no_inherit = false; |
183 | static bool scale = true; | 185 | static bool scale = true; |
184 | static bool no_aggr = false; | 186 | static bool no_aggr = false; |
185 | static const char *target_pid; | ||
186 | static const char *target_tid; | ||
187 | static pid_t child_pid = -1; | 187 | static pid_t child_pid = -1; |
188 | static bool null_run = false; | 188 | static bool null_run = false; |
189 | static int detailed_run = 0; | 189 | static int detailed_run = 0; |
190 | static bool sync_run = false; | 190 | static bool sync_run = false; |
191 | static bool big_num = true; | 191 | static bool big_num = true; |
192 | static int big_num_opt = -1; | 192 | static int big_num_opt = -1; |
193 | static const char *cpu_list; | ||
194 | static const char *csv_sep = NULL; | 193 | static const char *csv_sep = NULL; |
195 | static bool csv_output = false; | 194 | static bool csv_output = false; |
196 | static bool group = false; | 195 | static bool group = false; |
@@ -293,10 +292,10 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, | |||
293 | 292 | ||
294 | attr->inherit = !no_inherit; | 293 | attr->inherit = !no_inherit; |
295 | 294 | ||
296 | if (system_wide) | 295 | if (!perf_target__no_cpu(&target)) |
297 | return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, | 296 | return perf_evsel__open_per_cpu(evsel, evsel_list->cpus, |
298 | group, group_fd); | 297 | group, group_fd); |
299 | if (!target_pid && !target_tid && (!group || evsel == first)) { | 298 | if (perf_target__no_task(&target) && (!group || evsel == first)) { |
300 | attr->disabled = 1; | 299 | attr->disabled = 1; |
301 | attr->enable_on_exec = 1; | 300 | attr->enable_on_exec = 1; |
302 | } | 301 | } |
@@ -446,7 +445,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
446 | exit(-1); | 445 | exit(-1); |
447 | } | 446 | } |
448 | 447 | ||
449 | if (!target_tid && !target_pid && !system_wide) | 448 | if (perf_target__none(&target)) |
450 | evsel_list->threads->map[0] = child_pid; | 449 | evsel_list->threads->map[0] = child_pid; |
451 | 450 | ||
452 | /* | 451 | /* |
@@ -463,8 +462,13 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
463 | 462 | ||
464 | list_for_each_entry(counter, &evsel_list->entries, node) { | 463 | list_for_each_entry(counter, &evsel_list->entries, node) { |
465 | if (create_perf_stat_counter(counter, first) < 0) { | 464 | if (create_perf_stat_counter(counter, first) < 0) { |
465 | /* | ||
466 | * PPC returns ENXIO for HW counters until 2.6.37 | ||
467 | * (behavior changed with commit b0a873e). | ||
468 | */ | ||
466 | if (errno == EINVAL || errno == ENOSYS || | 469 | if (errno == EINVAL || errno == ENOSYS || |
467 | errno == ENOENT || errno == EOPNOTSUPP) { | 470 | errno == ENOENT || errno == EOPNOTSUPP || |
471 | errno == ENXIO) { | ||
468 | if (verbose) | 472 | if (verbose) |
469 | ui__warning("%s event is not supported by the kernel.\n", | 473 | ui__warning("%s event is not supported by the kernel.\n", |
470 | event_name(counter)); | 474 | event_name(counter)); |
@@ -476,7 +480,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
476 | error("You may not have permission to collect %sstats.\n" | 480 | error("You may not have permission to collect %sstats.\n" |
477 | "\t Consider tweaking" | 481 | "\t Consider tweaking" |
478 | " /proc/sys/kernel/perf_event_paranoid or running as root.", | 482 | " /proc/sys/kernel/perf_event_paranoid or running as root.", |
479 | system_wide ? "system-wide " : ""); | 483 | target.system_wide ? "system-wide " : ""); |
480 | } else { | 484 | } else { |
481 | error("open_counter returned with %d (%s). " | 485 | error("open_counter returned with %d (%s). " |
482 | "/bin/dmesg may provide additional information.\n", | 486 | "/bin/dmesg may provide additional information.\n", |
@@ -968,14 +972,14 @@ static void print_stat(int argc, const char **argv) | |||
968 | if (!csv_output) { | 972 | if (!csv_output) { |
969 | fprintf(output, "\n"); | 973 | fprintf(output, "\n"); |
970 | fprintf(output, " Performance counter stats for "); | 974 | fprintf(output, " Performance counter stats for "); |
971 | if (!target_pid && !target_tid) { | 975 | if (perf_target__no_task(&target)) { |
972 | fprintf(output, "\'%s", argv[0]); | 976 | fprintf(output, "\'%s", argv[0]); |
973 | for (i = 1; i < argc; i++) | 977 | for (i = 1; i < argc; i++) |
974 | fprintf(output, " %s", argv[i]); | 978 | fprintf(output, " %s", argv[i]); |
975 | } else if (target_pid) | 979 | } else if (target.pid) |
976 | fprintf(output, "process id \'%s", target_pid); | 980 | fprintf(output, "process id \'%s", target.pid); |
977 | else | 981 | else |
978 | fprintf(output, "thread id \'%s", target_tid); | 982 | fprintf(output, "thread id \'%s", target.tid); |
979 | 983 | ||
980 | fprintf(output, "\'"); | 984 | fprintf(output, "\'"); |
981 | if (run_count > 1) | 985 | if (run_count > 1) |
@@ -1049,11 +1053,11 @@ static const struct option options[] = { | |||
1049 | "event filter", parse_filter), | 1053 | "event filter", parse_filter), |
1050 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, | 1054 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, |
1051 | "child tasks do not inherit counters"), | 1055 | "child tasks do not inherit counters"), |
1052 | OPT_STRING('p', "pid", &target_pid, "pid", | 1056 | OPT_STRING('p', "pid", &target.pid, "pid", |
1053 | "stat events on existing process id"), | 1057 | "stat events on existing process id"), |
1054 | OPT_STRING('t', "tid", &target_tid, "tid", | 1058 | OPT_STRING('t', "tid", &target.tid, "tid", |
1055 | "stat events on existing thread id"), | 1059 | "stat events on existing thread id"), |
1056 | OPT_BOOLEAN('a', "all-cpus", &system_wide, | 1060 | OPT_BOOLEAN('a', "all-cpus", &target.system_wide, |
1057 | "system-wide collection from all CPUs"), | 1061 | "system-wide collection from all CPUs"), |
1058 | OPT_BOOLEAN('g', "group", &group, | 1062 | OPT_BOOLEAN('g', "group", &group, |
1059 | "put the counters into a counter group"), | 1063 | "put the counters into a counter group"), |
@@ -1072,7 +1076,7 @@ static const struct option options[] = { | |||
1072 | OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, | 1076 | OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL, |
1073 | "print large numbers with thousands\' separators", | 1077 | "print large numbers with thousands\' separators", |
1074 | stat__set_big_num), | 1078 | stat__set_big_num), |
1075 | OPT_STRING('C', "cpu", &cpu_list, "cpu", | 1079 | OPT_STRING('C', "cpu", &target.cpu_list, "cpu", |
1076 | "list of cpus to monitor in system-wide"), | 1080 | "list of cpus to monitor in system-wide"), |
1077 | OPT_BOOLEAN('A', "no-aggr", &no_aggr, | 1081 | OPT_BOOLEAN('A', "no-aggr", &no_aggr, |
1078 | "disable CPU count aggregation"), | 1082 | "disable CPU count aggregation"), |
@@ -1190,13 +1194,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
1190 | } else if (big_num_opt == 0) /* User passed --no-big-num */ | 1194 | } else if (big_num_opt == 0) /* User passed --no-big-num */ |
1191 | big_num = false; | 1195 | big_num = false; |
1192 | 1196 | ||
1193 | if (!argc && !target_pid && !target_tid) | 1197 | if (!argc && perf_target__no_task(&target)) |
1194 | usage_with_options(stat_usage, options); | 1198 | usage_with_options(stat_usage, options); |
1195 | if (run_count <= 0) | 1199 | if (run_count <= 0) |
1196 | usage_with_options(stat_usage, options); | 1200 | usage_with_options(stat_usage, options); |
1197 | 1201 | ||
1198 | /* no_aggr, cgroup are for system-wide only */ | 1202 | /* no_aggr, cgroup are for system-wide only */ |
1199 | if ((no_aggr || nr_cgroups) && !system_wide) { | 1203 | if ((no_aggr || nr_cgroups) && perf_target__no_cpu(&target)) { |
1200 | fprintf(stderr, "both cgroup and no-aggregation " | 1204 | fprintf(stderr, "both cgroup and no-aggregation " |
1201 | "modes only available in system-wide mode\n"); | 1205 | "modes only available in system-wide mode\n"); |
1202 | 1206 | ||
@@ -1206,23 +1210,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
1206 | if (add_default_attributes()) | 1210 | if (add_default_attributes()) |
1207 | goto out; | 1211 | goto out; |
1208 | 1212 | ||
1209 | if (target_pid) | 1213 | perf_target__validate(&target); |
1210 | target_tid = target_pid; | ||
1211 | 1214 | ||
1212 | evsel_list->threads = thread_map__new_str(target_pid, | 1215 | if (perf_evlist__create_maps(evsel_list, &target) < 0) { |
1213 | target_tid, UINT_MAX); | 1216 | if (!perf_target__no_task(&target)) |
1214 | if (evsel_list->threads == NULL) { | 1217 | pr_err("Problems finding threads of monitor\n"); |
1215 | pr_err("Problems finding threads of monitor\n"); | 1218 | if (!perf_target__no_cpu(&target)) |
1216 | usage_with_options(stat_usage, options); | 1219 | perror("failed to parse CPUs map"); |
1217 | } | ||
1218 | |||
1219 | if (system_wide) | ||
1220 | evsel_list->cpus = cpu_map__new(cpu_list); | ||
1221 | else | ||
1222 | evsel_list->cpus = cpu_map__dummy_new(); | ||
1223 | 1220 | ||
1224 | if (evsel_list->cpus == NULL) { | ||
1225 | perror("failed to parse CPUs map"); | ||
1226 | usage_with_options(stat_usage, options); | 1221 | usage_with_options(stat_usage, options); |
1227 | return -1; | 1222 | return -1; |
1228 | } | 1223 | } |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 1c5b9801ac61..9d9abbbe23be 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -1165,6 +1165,9 @@ realloc: | |||
1165 | static int test__PERF_RECORD(void) | 1165 | static int test__PERF_RECORD(void) |
1166 | { | 1166 | { |
1167 | struct perf_record_opts opts = { | 1167 | struct perf_record_opts opts = { |
1168 | .target = { | ||
1169 | .uid = UINT_MAX, | ||
1170 | }, | ||
1168 | .no_delay = true, | 1171 | .no_delay = true, |
1169 | .freq = 10, | 1172 | .freq = 10, |
1170 | .mmap_pages = 256, | 1173 | .mmap_pages = 256, |
@@ -1207,8 +1210,7 @@ static int test__PERF_RECORD(void) | |||
1207 | * perf_evlist__prepare_workload we'll fill in the only thread | 1210 | * perf_evlist__prepare_workload we'll fill in the only thread |
1208 | * we're monitoring, the one forked there. | 1211 | * we're monitoring, the one forked there. |
1209 | */ | 1212 | */ |
1210 | err = perf_evlist__create_maps(evlist, opts.target_pid, | 1213 | err = perf_evlist__create_maps(evlist, &opts.target); |
1211 | opts.target_tid, UINT_MAX, opts.cpu_list); | ||
1212 | if (err < 0) { | 1214 | if (err < 0) { |
1213 | pr_debug("Not enough memory to create thread/cpu maps\n"); | 1215 | pr_debug("Not enough memory to create thread/cpu maps\n"); |
1214 | goto out_delete_evlist; | 1216 | goto out_delete_evlist; |
@@ -1549,8 +1551,6 @@ static int __test__rdpmc(void) | |||
1549 | sa.sa_sigaction = segfault_handler; | 1551 | sa.sa_sigaction = segfault_handler; |
1550 | sigaction(SIGSEGV, &sa, NULL); | 1552 | sigaction(SIGSEGV, &sa, NULL); |
1551 | 1553 | ||
1552 | fprintf(stderr, "\n\n"); | ||
1553 | |||
1554 | fd = sys_perf_event_open(&attr, 0, -1, -1, 0); | 1554 | fd = sys_perf_event_open(&attr, 0, -1, -1, 0); |
1555 | if (fd < 0) { | 1555 | if (fd < 0) { |
1556 | die("Error: sys_perf_event_open() syscall returned " | 1556 | die("Error: sys_perf_event_open() syscall returned " |
@@ -1575,7 +1575,7 @@ static int __test__rdpmc(void) | |||
1575 | loops *= 10; | 1575 | loops *= 10; |
1576 | 1576 | ||
1577 | delta = now - stamp; | 1577 | delta = now - stamp; |
1578 | fprintf(stderr, "%14d: %14Lu\n", n, (long long)delta); | 1578 | pr_debug("%14d: %14Lu\n", n, (long long)delta); |
1579 | 1579 | ||
1580 | delta_sum += delta; | 1580 | delta_sum += delta; |
1581 | } | 1581 | } |
@@ -1583,7 +1583,7 @@ static int __test__rdpmc(void) | |||
1583 | munmap(addr, page_size); | 1583 | munmap(addr, page_size); |
1584 | close(fd); | 1584 | close(fd); |
1585 | 1585 | ||
1586 | fprintf(stderr, " "); | 1586 | pr_debug(" "); |
1587 | 1587 | ||
1588 | if (!delta_sum) | 1588 | if (!delta_sum) |
1589 | return -1; | 1589 | return -1; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 8ef59f8262bb..4eb6171e143b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -588,7 +588,7 @@ static void *display_thread_tui(void *arg) | |||
588 | * via --uid. | 588 | * via --uid. |
589 | */ | 589 | */ |
590 | list_for_each_entry(pos, &top->evlist->entries, node) | 590 | list_for_each_entry(pos, &top->evlist->entries, node) |
591 | pos->hists.uid_filter_str = top->uid_str; | 591 | pos->hists.uid_filter_str = top->target.uid_str; |
592 | 592 | ||
593 | perf_evlist__tui_browse_hists(top->evlist, help, | 593 | perf_evlist__tui_browse_hists(top->evlist, help, |
594 | perf_top__sort_new_samples, | 594 | perf_top__sort_new_samples, |
@@ -948,6 +948,10 @@ try_again: | |||
948 | 948 | ||
949 | attr->type = PERF_TYPE_SOFTWARE; | 949 | attr->type = PERF_TYPE_SOFTWARE; |
950 | attr->config = PERF_COUNT_SW_CPU_CLOCK; | 950 | attr->config = PERF_COUNT_SW_CPU_CLOCK; |
951 | if (counter->name) { | ||
952 | free(counter->name); | ||
953 | counter->name = strdup(event_name(counter)); | ||
954 | } | ||
951 | goto try_again; | 955 | goto try_again; |
952 | } | 956 | } |
953 | 957 | ||
@@ -1016,7 +1020,7 @@ static int __cmd_top(struct perf_top *top) | |||
1016 | if (ret) | 1020 | if (ret) |
1017 | goto out_delete; | 1021 | goto out_delete; |
1018 | 1022 | ||
1019 | if (top->target_tid || top->uid != UINT_MAX) | 1023 | if (!perf_target__no_task(&top->target)) |
1020 | perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, | 1024 | perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, |
1021 | perf_event__process, | 1025 | perf_event__process, |
1022 | &top->session->host_machine); | 1026 | &top->session->host_machine); |
@@ -1150,11 +1154,11 @@ static const char * const top_usage[] = { | |||
1150 | int cmd_top(int argc, const char **argv, const char *prefix __used) | 1154 | int cmd_top(int argc, const char **argv, const char *prefix __used) |
1151 | { | 1155 | { |
1152 | struct perf_evsel *pos; | 1156 | struct perf_evsel *pos; |
1153 | int status = -ENOMEM; | 1157 | int status; |
1158 | char errbuf[BUFSIZ]; | ||
1154 | struct perf_top top = { | 1159 | struct perf_top top = { |
1155 | .count_filter = 5, | 1160 | .count_filter = 5, |
1156 | .delay_secs = 2, | 1161 | .delay_secs = 2, |
1157 | .uid = UINT_MAX, | ||
1158 | .freq = 1000, /* 1 KHz */ | 1162 | .freq = 1000, /* 1 KHz */ |
1159 | .mmap_pages = 128, | 1163 | .mmap_pages = 128, |
1160 | .sym_pcnt_filter = 5, | 1164 | .sym_pcnt_filter = 5, |
@@ -1166,13 +1170,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1166 | parse_events_option), | 1170 | parse_events_option), |
1167 | OPT_INTEGER('c', "count", &top.default_interval, | 1171 | OPT_INTEGER('c', "count", &top.default_interval, |
1168 | "event period to sample"), | 1172 | "event period to sample"), |
1169 | OPT_STRING('p', "pid", &top.target_pid, "pid", | 1173 | OPT_STRING('p', "pid", &top.target.pid, "pid", |
1170 | "profile events on existing process id"), | 1174 | "profile events on existing process id"), |
1171 | OPT_STRING('t', "tid", &top.target_tid, "tid", | 1175 | OPT_STRING('t', "tid", &top.target.tid, "tid", |
1172 | "profile events on existing thread id"), | 1176 | "profile events on existing thread id"), |
1173 | OPT_BOOLEAN('a', "all-cpus", &top.system_wide, | 1177 | OPT_BOOLEAN('a', "all-cpus", &top.target.system_wide, |
1174 | "system-wide collection from all CPUs"), | 1178 | "system-wide collection from all CPUs"), |
1175 | OPT_STRING('C', "cpu", &top.cpu_list, "cpu", | 1179 | OPT_STRING('C', "cpu", &top.target.cpu_list, "cpu", |
1176 | "list of cpus to monitor"), | 1180 | "list of cpus to monitor"), |
1177 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, | 1181 | OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, |
1178 | "file", "vmlinux pathname"), | 1182 | "file", "vmlinux pathname"), |
@@ -1227,7 +1231,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1227 | "Display raw encoding of assembly instructions (default)"), | 1231 | "Display raw encoding of assembly instructions (default)"), |
1228 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", | 1232 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", |
1229 | "Specify disassembler style (e.g. -M intel for intel syntax)"), | 1233 | "Specify disassembler style (e.g. -M intel for intel syntax)"), |
1230 | OPT_STRING('u', "uid", &top.uid_str, "user", "user to profile"), | 1234 | OPT_STRING('u', "uid", &top.target.uid_str, "user", "user to profile"), |
1231 | OPT_END() | 1235 | OPT_END() |
1232 | }; | 1236 | }; |
1233 | 1237 | ||
@@ -1253,22 +1257,27 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1253 | 1257 | ||
1254 | setup_browser(false); | 1258 | setup_browser(false); |
1255 | 1259 | ||
1256 | top.uid = parse_target_uid(top.uid_str, top.target_tid, top.target_pid); | 1260 | status = perf_target__validate(&top.target); |
1257 | if (top.uid_str != NULL && top.uid == UINT_MAX - 1) | 1261 | if (status) { |
1258 | goto out_delete_evlist; | 1262 | perf_target__strerror(&top.target, status, errbuf, BUFSIZ); |
1263 | ui__warning("%s", errbuf); | ||
1264 | } | ||
1259 | 1265 | ||
1260 | /* CPU and PID are mutually exclusive */ | 1266 | status = perf_target__parse_uid(&top.target); |
1261 | if (top.target_tid && top.cpu_list) { | 1267 | if (status) { |
1262 | printf("WARNING: PID switch overriding CPU\n"); | 1268 | int saved_errno = errno; |
1263 | sleep(1); | 1269 | |
1264 | top.cpu_list = NULL; | 1270 | perf_target__strerror(&top.target, status, errbuf, BUFSIZ); |
1271 | ui__warning("%s", errbuf); | ||
1272 | |||
1273 | status = -saved_errno; | ||
1274 | goto out_delete_evlist; | ||
1265 | } | 1275 | } |
1266 | 1276 | ||
1267 | if (top.target_pid) | 1277 | if (perf_target__none(&top.target)) |
1268 | top.target_tid = top.target_pid; | 1278 | top.target.system_wide = true; |
1269 | 1279 | ||
1270 | if (perf_evlist__create_maps(top.evlist, top.target_pid, | 1280 | if (perf_evlist__create_maps(top.evlist, &top.target) < 0) |
1271 | top.target_tid, top.uid, top.cpu_list) < 0) | ||
1272 | usage_with_options(top_usage, options); | 1281 | usage_with_options(top_usage, options); |
1273 | 1282 | ||
1274 | if (!top.evlist->nr_entries && | 1283 | if (!top.evlist->nr_entries && |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 89e3355ab173..14f1034f14f9 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -207,10 +207,10 @@ extern const char perf_version_string[]; | |||
207 | 207 | ||
208 | void pthread__unblock_sigwinch(void); | 208 | void pthread__unblock_sigwinch(void); |
209 | 209 | ||
210 | #include "util/target.h" | ||
211 | |||
210 | struct perf_record_opts { | 212 | struct perf_record_opts { |
211 | const char *target_pid; | 213 | struct perf_target target; |
212 | const char *target_tid; | ||
213 | uid_t uid; | ||
214 | bool call_graph; | 214 | bool call_graph; |
215 | bool group; | 215 | bool group; |
216 | bool inherit_stat; | 216 | bool inherit_stat; |
@@ -223,7 +223,6 @@ struct perf_record_opts { | |||
223 | bool sample_time; | 223 | bool sample_time; |
224 | bool sample_id_all_missing; | 224 | bool sample_id_all_missing; |
225 | bool exclude_guest_missing; | 225 | bool exclude_guest_missing; |
226 | bool system_wide; | ||
227 | bool period; | 226 | bool period; |
228 | unsigned int freq; | 227 | unsigned int freq; |
229 | unsigned int mmap_pages; | 228 | unsigned int mmap_pages; |
@@ -231,7 +230,6 @@ struct perf_record_opts { | |||
231 | int branch_stack; | 230 | int branch_stack; |
232 | u64 default_interval; | 231 | u64 default_interval; |
233 | u64 user_interval; | 232 | u64 user_interval; |
234 | const char *cpu_list; | ||
235 | }; | 233 | }; |
236 | 234 | ||
237 | #endif | 235 | #endif |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index f171b4627cb1..06367c1df720 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
@@ -547,9 +547,9 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx, | |||
547 | struct map_symbol *ms = self->b.priv; | 547 | struct map_symbol *ms = self->b.priv; |
548 | struct symbol *sym = ms->sym; | 548 | struct symbol *sym = ms->sym; |
549 | const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, " | 549 | const char *help = "<-/ESC: Exit, TAB/shift+TAB: Cycle hot lines, " |
550 | "H: Go to hottest line, ->/ENTER: Line action, " | 550 | "H: Hottest line, ->/ENTER: Line action, " |
551 | "O: Toggle offset view, " | 551 | "O: Offset view, " |
552 | "S: Toggle source code view"; | 552 | "S: Source view"; |
553 | int key; | 553 | int key; |
554 | 554 | ||
555 | if (ui_browser__show(&self->b, sym->name, help) < 0) | 555 | if (ui_browser__show(&self->b, sym->name, help) < 0) |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 466827e91b87..a372a4b02635 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -941,7 +941,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
941 | goto zoom_dso; | 941 | goto zoom_dso; |
942 | case 't': | 942 | case 't': |
943 | goto zoom_thread; | 943 | goto zoom_thread; |
944 | case 's': | 944 | case '/': |
945 | if (ui_browser__input_window("Symbol to show", | 945 | if (ui_browser__input_window("Symbol to show", |
946 | "Please enter the name of symbol you want to see", | 946 | "Please enter the name of symbol you want to see", |
947 | buf, "ENTER: OK, ESC: Cancel", | 947 | buf, "ENTER: OK, ESC: Cancel", |
@@ -969,7 +969,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, | |||
969 | "E Expand all callchains\n" | 969 | "E Expand all callchains\n" |
970 | "d Zoom into current DSO\n" | 970 | "d Zoom into current DSO\n" |
971 | "t Zoom into current Thread\n" | 971 | "t Zoom into current Thread\n" |
972 | "s Filter symbol by name"); | 972 | "/ Filter symbol by name"); |
973 | continue; | 973 | continue; |
974 | case K_ENTER: | 974 | case K_ENTER: |
975 | case K_RIGHT: | 975 | case K_RIGHT: |
diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index 258352a2356c..0656c381a89c 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c | |||
@@ -9,24 +9,13 @@ | |||
9 | 9 | ||
10 | #define MAX_COLUMNS 32 | 10 | #define MAX_COLUMNS 32 |
11 | 11 | ||
12 | void perf_gtk_setup_browser(int argc, const char *argv[], | 12 | static void perf_gtk__signal(int sig) |
13 | bool fallback_to_pager __used) | ||
14 | { | ||
15 | gtk_init(&argc, (char ***)&argv); | ||
16 | } | ||
17 | |||
18 | void perf_gtk_exit_browser(bool wait_for_ok __used) | ||
19 | { | ||
20 | gtk_main_quit(); | ||
21 | } | ||
22 | |||
23 | static void perf_gtk_signal(int sig) | ||
24 | { | 13 | { |
25 | psignal(sig, "perf"); | 14 | psignal(sig, "perf"); |
26 | gtk_main_quit(); | 15 | gtk_main_quit(); |
27 | } | 16 | } |
28 | 17 | ||
29 | static void perf_gtk_resize_window(GtkWidget *window) | 18 | static void perf_gtk__resize_window(GtkWidget *window) |
30 | { | 19 | { |
31 | GdkRectangle rect; | 20 | GdkRectangle rect; |
32 | GdkScreen *screen; | 21 | GdkScreen *screen; |
@@ -46,7 +35,7 @@ static void perf_gtk_resize_window(GtkWidget *window) | |||
46 | gtk_window_resize(GTK_WINDOW(window), width, height); | 35 | gtk_window_resize(GTK_WINDOW(window), width, height); |
47 | } | 36 | } |
48 | 37 | ||
49 | static void perf_gtk_show_hists(GtkWidget *window, struct hists *hists) | 38 | static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) |
50 | { | 39 | { |
51 | GType col_types[MAX_COLUMNS]; | 40 | GType col_types[MAX_COLUMNS]; |
52 | GtkCellRenderer *renderer; | 41 | GtkCellRenderer *renderer; |
@@ -142,11 +131,11 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
142 | GtkWidget *notebook; | 131 | GtkWidget *notebook; |
143 | GtkWidget *window; | 132 | GtkWidget *window; |
144 | 133 | ||
145 | signal(SIGSEGV, perf_gtk_signal); | 134 | signal(SIGSEGV, perf_gtk__signal); |
146 | signal(SIGFPE, perf_gtk_signal); | 135 | signal(SIGFPE, perf_gtk__signal); |
147 | signal(SIGINT, perf_gtk_signal); | 136 | signal(SIGINT, perf_gtk__signal); |
148 | signal(SIGQUIT, perf_gtk_signal); | 137 | signal(SIGQUIT, perf_gtk__signal); |
149 | signal(SIGTERM, perf_gtk_signal); | 138 | signal(SIGTERM, perf_gtk__signal); |
150 | 139 | ||
151 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | 140 | window = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
152 | 141 | ||
@@ -168,7 +157,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
168 | GTK_POLICY_AUTOMATIC, | 157 | GTK_POLICY_AUTOMATIC, |
169 | GTK_POLICY_AUTOMATIC); | 158 | GTK_POLICY_AUTOMATIC); |
170 | 159 | ||
171 | perf_gtk_show_hists(scrolled_window, hists); | 160 | perf_gtk__show_hists(scrolled_window, hists); |
172 | 161 | ||
173 | tab_label = gtk_label_new(evname); | 162 | tab_label = gtk_label_new(evname); |
174 | 163 | ||
@@ -179,7 +168,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, | |||
179 | 168 | ||
180 | gtk_widget_show_all(window); | 169 | gtk_widget_show_all(window); |
181 | 170 | ||
182 | perf_gtk_resize_window(window); | 171 | perf_gtk__resize_window(window); |
183 | 172 | ||
184 | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); | 173 | gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); |
185 | 174 | ||
diff --git a/tools/perf/ui/gtk/setup.c b/tools/perf/ui/gtk/setup.c new file mode 100644 index 000000000000..829529957766 --- /dev/null +++ b/tools/perf/ui/gtk/setup.c | |||
@@ -0,0 +1,12 @@ | |||
1 | #include "gtk.h" | ||
2 | #include "../../util/cache.h" | ||
3 | |||
4 | int perf_gtk__init(void) | ||
5 | { | ||
6 | return gtk_init_check(NULL, NULL) ? 0 : -1; | ||
7 | } | ||
8 | |||
9 | void perf_gtk__exit(bool wait_for_ok __used) | ||
10 | { | ||
11 | gtk_main_quit(); | ||
12 | } | ||
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 85a69faa09aa..9f5f888f73e3 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c | |||
@@ -1,155 +1,45 @@ | |||
1 | #include <newt.h> | ||
2 | #include <signal.h> | ||
3 | #include <stdbool.h> | ||
4 | |||
5 | #include "../cache.h" | 1 | #include "../cache.h" |
6 | #include "../debug.h" | 2 | #include "../debug.h" |
7 | #include "browser.h" | ||
8 | #include "helpline.h" | ||
9 | #include "ui.h" | ||
10 | #include "util.h" | ||
11 | #include "libslang.h" | ||
12 | #include "keysyms.h" | ||
13 | |||
14 | pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; | ||
15 | |||
16 | static volatile int ui__need_resize; | ||
17 | |||
18 | void ui__refresh_dimensions(bool force) | ||
19 | { | ||
20 | if (force || ui__need_resize) { | ||
21 | ui__need_resize = 0; | ||
22 | pthread_mutex_lock(&ui__lock); | ||
23 | SLtt_get_screen_size(); | ||
24 | SLsmg_reinit_smg(); | ||
25 | pthread_mutex_unlock(&ui__lock); | ||
26 | } | ||
27 | } | ||
28 | |||
29 | static void ui__sigwinch(int sig __used) | ||
30 | { | ||
31 | ui__need_resize = 1; | ||
32 | } | ||
33 | |||
34 | static void ui__setup_sigwinch(void) | ||
35 | { | ||
36 | static bool done; | ||
37 | 3 | ||
38 | if (done) | ||
39 | return; | ||
40 | |||
41 | done = true; | ||
42 | pthread__unblock_sigwinch(); | ||
43 | signal(SIGWINCH, ui__sigwinch); | ||
44 | } | ||
45 | |||
46 | int ui__getch(int delay_secs) | ||
47 | { | ||
48 | struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL; | ||
49 | fd_set read_set; | ||
50 | int err, key; | ||
51 | |||
52 | ui__setup_sigwinch(); | ||
53 | |||
54 | FD_ZERO(&read_set); | ||
55 | FD_SET(0, &read_set); | ||
56 | |||
57 | if (delay_secs) { | ||
58 | timeout.tv_sec = delay_secs; | ||
59 | timeout.tv_usec = 0; | ||
60 | } | ||
61 | |||
62 | err = select(1, &read_set, NULL, NULL, ptimeout); | ||
63 | |||
64 | if (err == 0) | ||
65 | return K_TIMER; | ||
66 | |||
67 | if (err == -1) { | ||
68 | if (errno == EINTR) | ||
69 | return K_RESIZE; | ||
70 | return K_ERROR; | ||
71 | } | ||
72 | |||
73 | key = SLang_getkey(); | ||
74 | if (key != K_ESC) | ||
75 | return key; | ||
76 | |||
77 | FD_ZERO(&read_set); | ||
78 | FD_SET(0, &read_set); | ||
79 | timeout.tv_sec = 0; | ||
80 | timeout.tv_usec = 20; | ||
81 | err = select(1, &read_set, NULL, NULL, &timeout); | ||
82 | if (err == 0) | ||
83 | return K_ESC; | ||
84 | |||
85 | SLang_ungetkey(key); | ||
86 | return SLkp_getkey(); | ||
87 | } | ||
88 | |||
89 | static void newt_suspend(void *d __used) | ||
90 | { | ||
91 | newtSuspend(); | ||
92 | raise(SIGTSTP); | ||
93 | newtResume(); | ||
94 | } | ||
95 | |||
96 | static int ui__init(void) | ||
97 | { | ||
98 | int err = SLkp_init(); | ||
99 | |||
100 | if (err < 0) | ||
101 | goto out; | ||
102 | |||
103 | SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB); | ||
104 | out: | ||
105 | return err; | ||
106 | } | ||
107 | |||
108 | static void ui__exit(void) | ||
109 | { | ||
110 | SLtt_set_cursor_visibility(1); | ||
111 | SLsmg_refresh(); | ||
112 | SLsmg_reset_smg(); | ||
113 | SLang_reset_tty(); | ||
114 | } | ||
115 | |||
116 | static void ui__signal(int sig) | ||
117 | { | ||
118 | ui__exit(); | ||
119 | psignal(sig, "perf"); | ||
120 | exit(0); | ||
121 | } | ||
122 | 4 | ||
123 | void setup_browser(bool fallback_to_pager) | 5 | void setup_browser(bool fallback_to_pager) |
124 | { | 6 | { |
125 | if (!isatty(1) || !use_browser || dump_trace) { | 7 | if (!isatty(1) || dump_trace) |
126 | use_browser = 0; | 8 | use_browser = 0; |
9 | |||
10 | /* default to TUI */ | ||
11 | if (use_browser < 0) | ||
12 | use_browser = 1; | ||
13 | |||
14 | switch (use_browser) { | ||
15 | case 2: | ||
16 | if (perf_gtk__init() == 0) | ||
17 | break; | ||
18 | /* fall through */ | ||
19 | case 1: | ||
20 | use_browser = 1; | ||
21 | if (ui__init() == 0) | ||
22 | break; | ||
23 | /* fall through */ | ||
24 | default: | ||
127 | if (fallback_to_pager) | 25 | if (fallback_to_pager) |
128 | setup_pager(); | 26 | setup_pager(); |
129 | return; | 27 | break; |
130 | } | 28 | } |
131 | |||
132 | use_browser = 1; | ||
133 | newtInit(); | ||
134 | ui__init(); | ||
135 | newtSetSuspendCallback(newt_suspend, NULL); | ||
136 | ui_helpline__init(); | ||
137 | ui_browser__init(); | ||
138 | |||
139 | signal(SIGSEGV, ui__signal); | ||
140 | signal(SIGFPE, ui__signal); | ||
141 | signal(SIGINT, ui__signal); | ||
142 | signal(SIGQUIT, ui__signal); | ||
143 | signal(SIGTERM, ui__signal); | ||
144 | } | 29 | } |
145 | 30 | ||
146 | void exit_browser(bool wait_for_ok) | 31 | void exit_browser(bool wait_for_ok) |
147 | { | 32 | { |
148 | if (use_browser > 0) { | 33 | switch (use_browser) { |
149 | if (wait_for_ok) | 34 | case 2: |
150 | ui__question_window("Fatal Error", | 35 | perf_gtk__exit(wait_for_ok); |
151 | ui_helpline__last_msg, | 36 | break; |
152 | "Press any key...", 0); | 37 | |
153 | ui__exit(); | 38 | case 1: |
39 | ui__exit(wait_for_ok); | ||
40 | break; | ||
41 | |||
42 | default: | ||
43 | break; | ||
154 | } | 44 | } |
155 | } | 45 | } |
diff --git a/tools/perf/ui/tui/setup.c b/tools/perf/ui/tui/setup.c new file mode 100644 index 000000000000..d33e943ac434 --- /dev/null +++ b/tools/perf/ui/tui/setup.c | |||
@@ -0,0 +1,140 @@ | |||
1 | #include <newt.h> | ||
2 | #include <signal.h> | ||
3 | #include <stdbool.h> | ||
4 | |||
5 | #include "../../util/cache.h" | ||
6 | #include "../../util/debug.h" | ||
7 | #include "../browser.h" | ||
8 | #include "../helpline.h" | ||
9 | #include "../ui.h" | ||
10 | #include "../util.h" | ||
11 | #include "../libslang.h" | ||
12 | #include "../keysyms.h" | ||
13 | |||
14 | pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; | ||
15 | |||
16 | static volatile int ui__need_resize; | ||
17 | |||
18 | void ui__refresh_dimensions(bool force) | ||
19 | { | ||
20 | if (force || ui__need_resize) { | ||
21 | ui__need_resize = 0; | ||
22 | pthread_mutex_lock(&ui__lock); | ||
23 | SLtt_get_screen_size(); | ||
24 | SLsmg_reinit_smg(); | ||
25 | pthread_mutex_unlock(&ui__lock); | ||
26 | } | ||
27 | } | ||
28 | |||
29 | static void ui__sigwinch(int sig __used) | ||
30 | { | ||
31 | ui__need_resize = 1; | ||
32 | } | ||
33 | |||
34 | static void ui__setup_sigwinch(void) | ||
35 | { | ||
36 | static bool done; | ||
37 | |||
38 | if (done) | ||
39 | return; | ||
40 | |||
41 | done = true; | ||
42 | pthread__unblock_sigwinch(); | ||
43 | signal(SIGWINCH, ui__sigwinch); | ||
44 | } | ||
45 | |||
46 | int ui__getch(int delay_secs) | ||
47 | { | ||
48 | struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL; | ||
49 | fd_set read_set; | ||
50 | int err, key; | ||
51 | |||
52 | ui__setup_sigwinch(); | ||
53 | |||
54 | FD_ZERO(&read_set); | ||
55 | FD_SET(0, &read_set); | ||
56 | |||
57 | if (delay_secs) { | ||
58 | timeout.tv_sec = delay_secs; | ||
59 | timeout.tv_usec = 0; | ||
60 | } | ||
61 | |||
62 | err = select(1, &read_set, NULL, NULL, ptimeout); | ||
63 | |||
64 | if (err == 0) | ||
65 | return K_TIMER; | ||
66 | |||
67 | if (err == -1) { | ||
68 | if (errno == EINTR) | ||
69 | return K_RESIZE; | ||
70 | return K_ERROR; | ||
71 | } | ||
72 | |||
73 | key = SLang_getkey(); | ||
74 | if (key != K_ESC) | ||
75 | return key; | ||
76 | |||
77 | FD_ZERO(&read_set); | ||
78 | FD_SET(0, &read_set); | ||
79 | timeout.tv_sec = 0; | ||
80 | timeout.tv_usec = 20; | ||
81 | err = select(1, &read_set, NULL, NULL, &timeout); | ||
82 | if (err == 0) | ||
83 | return K_ESC; | ||
84 | |||
85 | SLang_ungetkey(key); | ||
86 | return SLkp_getkey(); | ||
87 | } | ||
88 | |||
89 | static void newt_suspend(void *d __used) | ||
90 | { | ||
91 | newtSuspend(); | ||
92 | raise(SIGTSTP); | ||
93 | newtResume(); | ||
94 | } | ||
95 | |||
96 | static void ui__signal(int sig) | ||
97 | { | ||
98 | ui__exit(false); | ||
99 | psignal(sig, "perf"); | ||
100 | exit(0); | ||
101 | } | ||
102 | |||
103 | int ui__init(void) | ||
104 | { | ||
105 | int err; | ||
106 | |||
107 | newtInit(); | ||
108 | err = SLkp_init(); | ||
109 | if (err < 0) { | ||
110 | pr_err("TUI initialization failed.\n"); | ||
111 | goto out; | ||
112 | } | ||
113 | |||
114 | SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB); | ||
115 | |||
116 | newtSetSuspendCallback(newt_suspend, NULL); | ||
117 | ui_helpline__init(); | ||
118 | ui_browser__init(); | ||
119 | |||
120 | signal(SIGSEGV, ui__signal); | ||
121 | signal(SIGFPE, ui__signal); | ||
122 | signal(SIGINT, ui__signal); | ||
123 | signal(SIGQUIT, ui__signal); | ||
124 | signal(SIGTERM, ui__signal); | ||
125 | out: | ||
126 | return err; | ||
127 | } | ||
128 | |||
129 | void ui__exit(bool wait_for_ok) | ||
130 | { | ||
131 | if (wait_for_ok) | ||
132 | ui__question_window("Fatal Error", | ||
133 | ui_helpline__last_msg, | ||
134 | "Press any key...", 0); | ||
135 | |||
136 | SLtt_set_cursor_visibility(1); | ||
137 | SLsmg_refresh(); | ||
138 | SLsmg_reset_smg(); | ||
139 | SLang_reset_tty(); | ||
140 | } | ||
diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 8dd224df3e54..cff18c617d13 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h | |||
@@ -33,7 +33,7 @@ extern int pager_use_color; | |||
33 | 33 | ||
34 | extern int use_browser; | 34 | extern int use_browser; |
35 | 35 | ||
36 | #ifdef NO_NEWT_SUPPORT | 36 | #if defined(NO_NEWT_SUPPORT) && defined(NO_GTK2_SUPPORT) |
37 | static inline void setup_browser(bool fallback_to_pager) | 37 | static inline void setup_browser(bool fallback_to_pager) |
38 | { | 38 | { |
39 | if (fallback_to_pager) | 39 | if (fallback_to_pager) |
@@ -43,19 +43,29 @@ static inline void exit_browser(bool wait_for_ok __used) {} | |||
43 | #else | 43 | #else |
44 | void setup_browser(bool fallback_to_pager); | 44 | void setup_browser(bool fallback_to_pager); |
45 | void exit_browser(bool wait_for_ok); | 45 | void exit_browser(bool wait_for_ok); |
46 | |||
47 | #ifdef NO_NEWT_SUPPORT | ||
48 | static inline int ui__init(void) | ||
49 | { | ||
50 | return -1; | ||
51 | } | ||
52 | static inline void ui__exit(bool wait_for_ok __used) {} | ||
53 | #else | ||
54 | int ui__init(void); | ||
55 | void ui__exit(bool wait_for_ok); | ||
46 | #endif | 56 | #endif |
47 | 57 | ||
48 | #ifdef NO_GTK2_SUPPORT | 58 | #ifdef NO_GTK2_SUPPORT |
49 | static inline void perf_gtk_setup_browser(int argc __used, const char *argv[] __used, bool fallback_to_pager) | 59 | static inline int perf_gtk__init(void) |
50 | { | 60 | { |
51 | if (fallback_to_pager) | 61 | return -1; |
52 | setup_pager(); | ||
53 | } | 62 | } |
54 | static inline void perf_gtk_exit_browser(bool wait_for_ok __used) {} | 63 | static inline void perf_gtk__exit(bool wait_for_ok __used) {} |
55 | #else | 64 | #else |
56 | void perf_gtk_setup_browser(int argc, const char *argv[], bool fallback_to_pager); | 65 | int perf_gtk__init(void); |
57 | void perf_gtk_exit_browser(bool wait_for_ok); | 66 | void perf_gtk__exit(bool wait_for_ok); |
58 | #endif | 67 | #endif |
68 | #endif /* NO_NEWT_SUPPORT && NO_GTK2_SUPPORT */ | ||
59 | 69 | ||
60 | char *alias_lookup(const char *alias); | 70 | char *alias_lookup(const char *alias); |
61 | int split_cmdline(char *cmdline, const char ***argv); | 71 | int split_cmdline(char *cmdline, const char ***argv); |
diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 26817daa2961..efb1fce259a4 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include "event.h" | 11 | #include "event.h" |
12 | #include "debug.h" | 12 | #include "debug.h" |
13 | #include "util.h" | 13 | #include "util.h" |
14 | #include "target.h" | ||
14 | 15 | ||
15 | int verbose; | 16 | int verbose; |
16 | bool dump_trace = false, quiet = false; | 17 | bool dump_trace = false, quiet = false; |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 1986d8051bd1..1201daf71719 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <poll.h> | 11 | #include <poll.h> |
12 | #include "cpumap.h" | 12 | #include "cpumap.h" |
13 | #include "thread_map.h" | 13 | #include "thread_map.h" |
14 | #include "target.h" | ||
14 | #include "evlist.h" | 15 | #include "evlist.h" |
15 | #include "evsel.h" | 16 | #include "evsel.h" |
16 | #include <unistd.h> | 17 | #include <unistd.h> |
@@ -599,18 +600,19 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, | |||
599 | return perf_evlist__mmap_per_cpu(evlist, prot, mask); | 600 | return perf_evlist__mmap_per_cpu(evlist, prot, mask); |
600 | } | 601 | } |
601 | 602 | ||
602 | int perf_evlist__create_maps(struct perf_evlist *evlist, const char *target_pid, | 603 | int perf_evlist__create_maps(struct perf_evlist *evlist, |
603 | const char *target_tid, uid_t uid, const char *cpu_list) | 604 | struct perf_target *target) |
604 | { | 605 | { |
605 | evlist->threads = thread_map__new_str(target_pid, target_tid, uid); | 606 | evlist->threads = thread_map__new_str(target->pid, target->tid, |
607 | target->uid); | ||
606 | 608 | ||
607 | if (evlist->threads == NULL) | 609 | if (evlist->threads == NULL) |
608 | return -1; | 610 | return -1; |
609 | 611 | ||
610 | if (uid != UINT_MAX || (cpu_list == NULL && target_tid)) | 612 | if (!perf_target__no_cpu(target)) |
611 | evlist->cpus = cpu_map__dummy_new(); | 613 | evlist->cpus = cpu_map__new(target->cpu_list); |
612 | else | 614 | else |
613 | evlist->cpus = cpu_map__new(cpu_list); | 615 | evlist->cpus = cpu_map__dummy_new(); |
614 | 616 | ||
615 | if (evlist->cpus == NULL) | 617 | if (evlist->cpus == NULL) |
616 | goto out_delete_threads; | 618 | goto out_delete_threads; |
@@ -827,7 +829,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, | |||
827 | exit(-1); | 829 | exit(-1); |
828 | } | 830 | } |
829 | 831 | ||
830 | if (!opts->system_wide && !opts->target_tid && !opts->target_pid) | 832 | if (perf_target__none(&opts->target)) |
831 | evlist->threads->map[0] = evlist->workload.pid; | 833 | evlist->threads->map[0] = evlist->workload.pid; |
832 | 834 | ||
833 | close(child_ready_pipe[1]); | 835 | close(child_ready_pipe[1]); |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 21f1c9e57f13..58abb63ac13a 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -106,8 +106,8 @@ static inline void perf_evlist__set_maps(struct perf_evlist *evlist, | |||
106 | evlist->threads = threads; | 106 | evlist->threads = threads; |
107 | } | 107 | } |
108 | 108 | ||
109 | int perf_evlist__create_maps(struct perf_evlist *evlist, const char *target_pid, | 109 | int perf_evlist__create_maps(struct perf_evlist *evlist, |
110 | const char *tid, uid_t uid, const char *cpu_list); | 110 | struct perf_target *target); |
111 | void perf_evlist__delete_maps(struct perf_evlist *evlist); | 111 | void perf_evlist__delete_maps(struct perf_evlist *evlist); |
112 | int perf_evlist__set_filters(struct perf_evlist *evlist); | 112 | int perf_evlist__set_filters(struct perf_evlist *evlist); |
113 | 113 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 8c13dbcb84b9..21eaab240396 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include "util.h" | 14 | #include "util.h" |
15 | #include "cpumap.h" | 15 | #include "cpumap.h" |
16 | #include "thread_map.h" | 16 | #include "thread_map.h" |
17 | #include "target.h" | ||
17 | 18 | ||
18 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 19 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
19 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | 20 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) |
@@ -106,15 +107,15 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, | |||
106 | if (opts->call_graph) | 107 | if (opts->call_graph) |
107 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; | 108 | attr->sample_type |= PERF_SAMPLE_CALLCHAIN; |
108 | 109 | ||
109 | if (opts->system_wide) | 110 | if (opts->target.system_wide) |
110 | attr->sample_type |= PERF_SAMPLE_CPU; | 111 | attr->sample_type |= PERF_SAMPLE_CPU; |
111 | 112 | ||
112 | if (opts->period) | 113 | if (opts->period) |
113 | attr->sample_type |= PERF_SAMPLE_PERIOD; | 114 | attr->sample_type |= PERF_SAMPLE_PERIOD; |
114 | 115 | ||
115 | if (!opts->sample_id_all_missing && | 116 | if (!opts->sample_id_all_missing && |
116 | (opts->sample_time || opts->system_wide || | 117 | (opts->sample_time || !opts->no_inherit || |
117 | !opts->no_inherit || opts->cpu_list)) | 118 | !perf_target__no_cpu(&opts->target))) |
118 | attr->sample_type |= PERF_SAMPLE_TIME; | 119 | attr->sample_type |= PERF_SAMPLE_TIME; |
119 | 120 | ||
120 | if (opts->raw_samples) { | 121 | if (opts->raw_samples) { |
@@ -135,7 +136,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, | |||
135 | attr->mmap = track; | 136 | attr->mmap = track; |
136 | attr->comm = track; | 137 | attr->comm = track; |
137 | 138 | ||
138 | if (!opts->target_pid && !opts->target_tid && !opts->system_wide && | 139 | if (perf_target__none(&opts->target) && |
139 | (!opts->group || evsel == first)) { | 140 | (!opts->group || evsel == first)) { |
140 | attr->disabled = 1; | 141 | attr->disabled = 1; |
141 | attr->enable_on_exec = 1; | 142 | attr->enable_on_exec = 1; |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 4c7c2d73251f..6e618ba21382 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -31,21 +31,16 @@ static const char **header_argv; | |||
31 | 31 | ||
32 | int perf_header__push_event(u64 id, const char *name) | 32 | int perf_header__push_event(u64 id, const char *name) |
33 | { | 33 | { |
34 | struct perf_trace_event_type *nevents; | ||
35 | |||
34 | if (strlen(name) > MAX_EVENT_NAME) | 36 | if (strlen(name) > MAX_EVENT_NAME) |
35 | pr_warning("Event %s will be truncated\n", name); | 37 | pr_warning("Event %s will be truncated\n", name); |
36 | 38 | ||
37 | if (!events) { | 39 | nevents = realloc(events, (event_count + 1) * sizeof(*events)); |
38 | events = malloc(sizeof(struct perf_trace_event_type)); | 40 | if (nevents == NULL) |
39 | if (events == NULL) | 41 | return -ENOMEM; |
40 | return -ENOMEM; | 42 | events = nevents; |
41 | } else { | ||
42 | struct perf_trace_event_type *nevents; | ||
43 | 43 | ||
44 | nevents = realloc(events, (event_count + 1) * sizeof(*events)); | ||
45 | if (nevents == NULL) | ||
46 | return -ENOMEM; | ||
47 | events = nevents; | ||
48 | } | ||
49 | memset(&events[event_count], 0, sizeof(struct perf_trace_event_type)); | 44 | memset(&events[event_count], 0, sizeof(struct perf_trace_event_type)); |
50 | events[event_count].event_id = id; | 45 | events[event_count].event_id = id; |
51 | strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1); | 46 | strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1); |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index ca069f893381..5cb002894a17 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -4,7 +4,9 @@ | |||
4 | * Parse symbolic events/counts passed in as options: | 4 | * Parse symbolic events/counts passed in as options: |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <stdbool.h> | ||
7 | #include "../../../include/linux/perf_event.h" | 8 | #include "../../../include/linux/perf_event.h" |
9 | #include "types.h" | ||
8 | 10 | ||
9 | struct list_head; | 11 | struct list_head; |
10 | struct perf_evsel; | 12 | struct perf_evsel; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1efd3bee6336..4dcc8f3190cf 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1108,16 +1108,10 @@ more: | |||
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | if ((skip = perf_session__process_event(self, &event, tool, head)) < 0) { | 1110 | if ((skip = perf_session__process_event(self, &event, tool, head)) < 0) { |
1111 | dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n", | 1111 | pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", |
1112 | head, event.header.size, event.header.type); | 1112 | head, event.header.size, event.header.type); |
1113 | /* | 1113 | err = -EINVAL; |
1114 | * assume we lost track of the stream, check alignment, and | 1114 | goto out_err; |
1115 | * increment a single u64 in the hope to catch on again 'soon'. | ||
1116 | */ | ||
1117 | if (unlikely(head & 7)) | ||
1118 | head &= ~7ULL; | ||
1119 | |||
1120 | size = 8; | ||
1121 | } | 1115 | } |
1122 | 1116 | ||
1123 | head += size; | 1117 | head += size; |
@@ -1226,17 +1220,11 @@ more: | |||
1226 | 1220 | ||
1227 | if (size == 0 || | 1221 | if (size == 0 || |
1228 | perf_session__process_event(session, event, tool, file_pos) < 0) { | 1222 | perf_session__process_event(session, event, tool, file_pos) < 0) { |
1229 | dump_printf("%#" PRIx64 " [%#x]: skipping unknown header type: %d\n", | 1223 | pr_err("%#" PRIx64 " [%#x]: failed to process type: %d\n", |
1230 | file_offset + head, event->header.size, | 1224 | file_offset + head, event->header.size, |
1231 | event->header.type); | 1225 | event->header.type); |
1232 | /* | 1226 | err = -EINVAL; |
1233 | * assume we lost track of the stream, check alignment, and | 1227 | goto out_err; |
1234 | * increment a single u64 in the hope to catch on again 'soon'. | ||
1235 | */ | ||
1236 | if (unlikely(head & 7)) | ||
1237 | head &= ~7ULL; | ||
1238 | |||
1239 | size = 8; | ||
1240 | } | 1228 | } |
1241 | 1229 | ||
1242 | head += size; | 1230 | head += size; |
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c new file mode 100644 index 000000000000..1064d5b148ad --- /dev/null +++ b/tools/perf/util/target.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Helper functions for handling target threads/cpus | ||
3 | * | ||
4 | * Copyright (C) 2012, LG Electronics, Namhyung Kim <namhyung.kim@lge.com> | ||
5 | * | ||
6 | * Released under the GPL v2. | ||
7 | */ | ||
8 | |||
9 | #include "target.h" | ||
10 | #include "debug.h" | ||
11 | |||
12 | #include <pwd.h> | ||
13 | #include <string.h> | ||
14 | |||
15 | |||
16 | enum perf_target_errno perf_target__validate(struct perf_target *target) | ||
17 | { | ||
18 | enum perf_target_errno ret = PERF_ERRNO_TARGET__SUCCESS; | ||
19 | |||
20 | if (target->pid) | ||
21 | target->tid = target->pid; | ||
22 | |||
23 | /* CPU and PID are mutually exclusive */ | ||
24 | if (target->tid && target->cpu_list) { | ||
25 | target->cpu_list = NULL; | ||
26 | if (ret == PERF_ERRNO_TARGET__SUCCESS) | ||
27 | ret = PERF_ERRNO_TARGET__PID_OVERRIDE_CPU; | ||
28 | } | ||
29 | |||
30 | /* UID and PID are mutually exclusive */ | ||
31 | if (target->tid && target->uid_str) { | ||
32 | target->uid_str = NULL; | ||
33 | if (ret == PERF_ERRNO_TARGET__SUCCESS) | ||
34 | ret = PERF_ERRNO_TARGET__PID_OVERRIDE_UID; | ||
35 | } | ||
36 | |||
37 | /* UID and CPU are mutually exclusive */ | ||
38 | if (target->uid_str && target->cpu_list) { | ||
39 | target->cpu_list = NULL; | ||
40 | if (ret == PERF_ERRNO_TARGET__SUCCESS) | ||
41 | ret = PERF_ERRNO_TARGET__UID_OVERRIDE_CPU; | ||
42 | } | ||
43 | |||
44 | /* PID and SYSTEM are mutually exclusive */ | ||
45 | if (target->tid && target->system_wide) { | ||
46 | target->system_wide = false; | ||
47 | if (ret == PERF_ERRNO_TARGET__SUCCESS) | ||
48 | ret = PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM; | ||
49 | } | ||
50 | |||
51 | /* UID and SYSTEM are mutually exclusive */ | ||
52 | if (target->uid_str && target->system_wide) { | ||
53 | target->system_wide = false; | ||
54 | if (ret == PERF_ERRNO_TARGET__SUCCESS) | ||
55 | ret = PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM; | ||
56 | } | ||
57 | |||
58 | return ret; | ||
59 | } | ||
60 | |||
61 | enum perf_target_errno perf_target__parse_uid(struct perf_target *target) | ||
62 | { | ||
63 | struct passwd pwd, *result; | ||
64 | char buf[1024]; | ||
65 | const char *str = target->uid_str; | ||
66 | |||
67 | target->uid = UINT_MAX; | ||
68 | if (str == NULL) | ||
69 | return PERF_ERRNO_TARGET__SUCCESS; | ||
70 | |||
71 | /* Try user name first */ | ||
72 | getpwnam_r(str, &pwd, buf, sizeof(buf), &result); | ||
73 | |||
74 | if (result == NULL) { | ||
75 | /* | ||
76 | * The user name not found. Maybe it's a UID number. | ||
77 | */ | ||
78 | char *endptr; | ||
79 | int uid = strtol(str, &endptr, 10); | ||
80 | |||
81 | if (*endptr != '\0') | ||
82 | return PERF_ERRNO_TARGET__INVALID_UID; | ||
83 | |||
84 | getpwuid_r(uid, &pwd, buf, sizeof(buf), &result); | ||
85 | |||
86 | if (result == NULL) | ||
87 | return PERF_ERRNO_TARGET__USER_NOT_FOUND; | ||
88 | } | ||
89 | |||
90 | target->uid = result->pw_uid; | ||
91 | return PERF_ERRNO_TARGET__SUCCESS; | ||
92 | } | ||
93 | |||
94 | /* | ||
95 | * This must have a same ordering as the enum perf_target_errno. | ||
96 | */ | ||
97 | static const char *perf_target__error_str[] = { | ||
98 | "PID/TID switch overriding CPU", | ||
99 | "PID/TID switch overriding UID", | ||
100 | "UID switch overriding CPU", | ||
101 | "PID/TID switch overriding SYSTEM", | ||
102 | "UID switch overriding SYSTEM", | ||
103 | "Invalid User: %s", | ||
104 | "Problems obtaining information for user %s", | ||
105 | }; | ||
106 | |||
107 | int perf_target__strerror(struct perf_target *target, int errnum, | ||
108 | char *buf, size_t buflen) | ||
109 | { | ||
110 | int idx; | ||
111 | const char *msg; | ||
112 | |||
113 | if (errnum >= 0) { | ||
114 | strerror_r(errnum, buf, buflen); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | if (errnum < __PERF_ERRNO_TARGET__START || | ||
119 | errnum >= __PERF_ERRNO_TARGET__END) | ||
120 | return -1; | ||
121 | |||
122 | idx = errnum - __PERF_ERRNO_TARGET__START; | ||
123 | msg = perf_target__error_str[idx]; | ||
124 | |||
125 | switch (errnum) { | ||
126 | case PERF_ERRNO_TARGET__PID_OVERRIDE_CPU | ||
127 | ... PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM: | ||
128 | snprintf(buf, buflen, "%s", msg); | ||
129 | break; | ||
130 | |||
131 | case PERF_ERRNO_TARGET__INVALID_UID: | ||
132 | case PERF_ERRNO_TARGET__USER_NOT_FOUND: | ||
133 | snprintf(buf, buflen, msg, target->uid_str); | ||
134 | break; | ||
135 | |||
136 | default: | ||
137 | /* cannot reach here */ | ||
138 | break; | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
diff --git a/tools/perf/util/target.h b/tools/perf/util/target.h new file mode 100644 index 000000000000..127cff3f8ced --- /dev/null +++ b/tools/perf/util/target.h | |||
@@ -0,0 +1,64 @@ | |||
1 | #ifndef _PERF_TARGET_H | ||
2 | #define _PERF_TARGET_H | ||
3 | |||
4 | #include <stdbool.h> | ||
5 | #include <sys/types.h> | ||
6 | |||
7 | struct perf_target { | ||
8 | const char *pid; | ||
9 | const char *tid; | ||
10 | const char *cpu_list; | ||
11 | const char *uid_str; | ||
12 | uid_t uid; | ||
13 | bool system_wide; | ||
14 | }; | ||
15 | |||
16 | enum perf_target_errno { | ||
17 | PERF_ERRNO_TARGET__SUCCESS = 0, | ||
18 | |||
19 | /* | ||
20 | * Choose an arbitrary negative big number not to clash with standard | ||
21 | * errno since SUS requires the errno has distinct positive values. | ||
22 | * See 'Issue 6' in the link below. | ||
23 | * | ||
24 | * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html | ||
25 | */ | ||
26 | __PERF_ERRNO_TARGET__START = -10000, | ||
27 | |||
28 | |||
29 | /* for perf_target__validate() */ | ||
30 | PERF_ERRNO_TARGET__PID_OVERRIDE_CPU = __PERF_ERRNO_TARGET__START, | ||
31 | PERF_ERRNO_TARGET__PID_OVERRIDE_UID, | ||
32 | PERF_ERRNO_TARGET__UID_OVERRIDE_CPU, | ||
33 | PERF_ERRNO_TARGET__PID_OVERRIDE_SYSTEM, | ||
34 | PERF_ERRNO_TARGET__UID_OVERRIDE_SYSTEM, | ||
35 | |||
36 | /* for perf_target__parse_uid() */ | ||
37 | PERF_ERRNO_TARGET__INVALID_UID, | ||
38 | PERF_ERRNO_TARGET__USER_NOT_FOUND, | ||
39 | |||
40 | __PERF_ERRNO_TARGET__END, | ||
41 | }; | ||
42 | |||
43 | enum perf_target_errno perf_target__validate(struct perf_target *target); | ||
44 | enum perf_target_errno perf_target__parse_uid(struct perf_target *target); | ||
45 | |||
46 | int perf_target__strerror(struct perf_target *target, int errnum, char *buf, | ||
47 | size_t buflen); | ||
48 | |||
49 | static inline bool perf_target__no_task(struct perf_target *target) | ||
50 | { | ||
51 | return !target->pid && !target->tid && !target->uid_str; | ||
52 | } | ||
53 | |||
54 | static inline bool perf_target__no_cpu(struct perf_target *target) | ||
55 | { | ||
56 | return !target->system_wide && !target->cpu_list; | ||
57 | } | ||
58 | |||
59 | static inline bool perf_target__none(struct perf_target *target) | ||
60 | { | ||
61 | return perf_target__no_task(target) && perf_target__no_cpu(target); | ||
62 | } | ||
63 | |||
64 | #endif /* _PERF_TARGET_H */ | ||
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c index 09fe579ccafb..abe0e8e95068 100644 --- a/tools/perf/util/top.c +++ b/tools/perf/util/top.c | |||
@@ -69,23 +69,24 @@ size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) | |||
69 | 69 | ||
70 | ret += SNPRINTF(bf + ret, size - ret, "], "); | 70 | ret += SNPRINTF(bf + ret, size - ret, "], "); |
71 | 71 | ||
72 | if (top->target_pid) | 72 | if (top->target.pid) |
73 | ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s", | 73 | ret += SNPRINTF(bf + ret, size - ret, " (target_pid: %s", |
74 | top->target_pid); | 74 | top->target.pid); |
75 | else if (top->target_tid) | 75 | else if (top->target.tid) |
76 | ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s", | 76 | ret += SNPRINTF(bf + ret, size - ret, " (target_tid: %s", |
77 | top->target_tid); | 77 | top->target.tid); |
78 | else if (top->uid_str != NULL) | 78 | else if (top->target.uid_str != NULL) |
79 | ret += SNPRINTF(bf + ret, size - ret, " (uid: %s", | 79 | ret += SNPRINTF(bf + ret, size - ret, " (uid: %s", |
80 | top->uid_str); | 80 | top->target.uid_str); |
81 | else | 81 | else |
82 | ret += SNPRINTF(bf + ret, size - ret, " (all"); | 82 | ret += SNPRINTF(bf + ret, size - ret, " (all"); |
83 | 83 | ||
84 | if (top->cpu_list) | 84 | if (top->target.cpu_list) |
85 | ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", | 85 | ret += SNPRINTF(bf + ret, size - ret, ", CPU%s: %s)", |
86 | top->evlist->cpus->nr > 1 ? "s" : "", top->cpu_list); | 86 | top->evlist->cpus->nr > 1 ? "s" : "", |
87 | top->target.cpu_list); | ||
87 | else { | 88 | else { |
88 | if (top->target_tid) | 89 | if (top->target.tid) |
89 | ret += SNPRINTF(bf + ret, size - ret, ")"); | 90 | ret += SNPRINTF(bf + ret, size - ret, ")"); |
90 | else | 91 | else |
91 | ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", | 92 | ret += SNPRINTF(bf + ret, size - ret, ", %d CPU%s)", |
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index ce61cb2d1acf..33347ca89ee4 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
@@ -13,6 +13,7 @@ struct perf_session; | |||
13 | struct perf_top { | 13 | struct perf_top { |
14 | struct perf_tool tool; | 14 | struct perf_tool tool; |
15 | struct perf_evlist *evlist; | 15 | struct perf_evlist *evlist; |
16 | struct perf_target target; | ||
16 | /* | 17 | /* |
17 | * Symbols will be added here in perf_event__process_sample and will | 18 | * Symbols will be added here in perf_event__process_sample and will |
18 | * get out after decayed. | 19 | * get out after decayed. |
@@ -23,10 +24,7 @@ struct perf_top { | |||
23 | u64 guest_us_samples, guest_kernel_samples; | 24 | u64 guest_us_samples, guest_kernel_samples; |
24 | int print_entries, count_filter, delay_secs; | 25 | int print_entries, count_filter, delay_secs; |
25 | int freq; | 26 | int freq; |
26 | const char *target_pid, *target_tid; | ||
27 | uid_t uid; | ||
28 | bool hide_kernel_symbols, hide_user_symbols, zero; | 27 | bool hide_kernel_symbols, hide_user_symbols, zero; |
29 | bool system_wide; | ||
30 | bool use_tui, use_stdio; | 28 | bool use_tui, use_stdio; |
31 | bool sort_has_symbols; | 29 | bool sort_has_symbols; |
32 | bool dont_use_callchains; | 30 | bool dont_use_callchains; |
@@ -37,7 +35,6 @@ struct perf_top { | |||
37 | bool sample_id_all_missing; | 35 | bool sample_id_all_missing; |
38 | bool exclude_guest_missing; | 36 | bool exclude_guest_missing; |
39 | bool dump_symtab; | 37 | bool dump_symtab; |
40 | const char *cpu_list; | ||
41 | struct hist_entry *sym_filter_entry; | 38 | struct hist_entry *sym_filter_entry; |
42 | struct perf_evsel *sym_evsel; | 39 | struct perf_evsel *sym_evsel; |
43 | struct perf_session *session; | 40 | struct perf_session *session; |
@@ -47,7 +44,6 @@ struct perf_top { | |||
47 | int realtime_prio; | 44 | int realtime_prio; |
48 | int sym_pcnt_filter; | 45 | int sym_pcnt_filter; |
49 | const char *sym_filter; | 46 | const char *sym_filter; |
50 | const char *uid_str; | ||
51 | }; | 47 | }; |
52 | 48 | ||
53 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); | 49 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); |
diff --git a/tools/perf/util/usage.c b/tools/perf/util/usage.c index 52bb07c6442a..4007aca8e0ca 100644 --- a/tools/perf/util/usage.c +++ b/tools/perf/util/usage.c | |||
@@ -82,41 +82,3 @@ void warning(const char *warn, ...) | |||
82 | warn_routine(warn, params); | 82 | warn_routine(warn, params); |
83 | va_end(params); | 83 | va_end(params); |
84 | } | 84 | } |
85 | |||
86 | uid_t parse_target_uid(const char *str, const char *tid, const char *pid) | ||
87 | { | ||
88 | struct passwd pwd, *result; | ||
89 | char buf[1024]; | ||
90 | |||
91 | if (str == NULL) | ||
92 | return UINT_MAX; | ||
93 | |||
94 | /* UID and PID are mutually exclusive */ | ||
95 | if (tid || pid) { | ||
96 | ui__warning("PID/TID switch overriding UID\n"); | ||
97 | sleep(1); | ||
98 | return UINT_MAX; | ||
99 | } | ||
100 | |||
101 | getpwnam_r(str, &pwd, buf, sizeof(buf), &result); | ||
102 | |||
103 | if (result == NULL) { | ||
104 | char *endptr; | ||
105 | int uid = strtol(str, &endptr, 10); | ||
106 | |||
107 | if (*endptr != '\0') { | ||
108 | ui__error("Invalid user %s\n", str); | ||
109 | return UINT_MAX - 1; | ||
110 | } | ||
111 | |||
112 | getpwuid_r(uid, &pwd, buf, sizeof(buf), &result); | ||
113 | |||
114 | if (result == NULL) { | ||
115 | ui__error("Problems obtaining information for user %s\n", | ||
116 | str); | ||
117 | return UINT_MAX - 1; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | return result->pw_uid; | ||
122 | } | ||
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 6121e24fefc0..2daaedb83d84 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
@@ -74,7 +74,6 @@ | |||
74 | #include <netinet/tcp.h> | 74 | #include <netinet/tcp.h> |
75 | #include <arpa/inet.h> | 75 | #include <arpa/inet.h> |
76 | #include <netdb.h> | 76 | #include <netdb.h> |
77 | #include <pwd.h> | ||
78 | #include <inttypes.h> | 77 | #include <inttypes.h> |
79 | #include "../../../include/linux/magic.h" | 78 | #include "../../../include/linux/magic.h" |
80 | #include "types.h" | 79 | #include "types.h" |
@@ -249,8 +248,6 @@ struct perf_event_attr; | |||
249 | 248 | ||
250 | void event_attr_init(struct perf_event_attr *attr); | 249 | void event_attr_init(struct perf_event_attr *attr); |
251 | 250 | ||
252 | uid_t parse_target_uid(const char *str, const char *tid, const char *pid); | ||
253 | |||
254 | #define _STR(x) #x | 251 | #define _STR(x) #x |
255 | #define STR(x) _STR(x) | 252 | #define STR(x) _STR(x) |
256 | 253 | ||