diff options
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 81 |
1 files changed, 48 insertions, 33 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 8ef59f8262bb..6bb0277b7dfe 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -588,7 +588,7 @@ static void *display_thread_tui(void *arg) * via --uid. */ list_for_each_entry(pos, &top->evlist->entries, node) - pos->hists.uid_filter_str = top->uid_str; + pos->hists.uid_filter_str = top->target.uid_str; perf_evlist__tui_browse_hists(top->evlist, help, perf_top__sort_new_samples, @@ -787,7 +787,7 @@ static void perf_event__process_sample(struct perf_tool *tool, } if (symbol_conf.use_callchain) { - err = callchain_append(he->callchain, &evsel->hists.callchain_cursor, + err = callchain_append(he->callchain, &callchain_cursor, sample->period); if (err) return; @@ -900,6 +900,9 @@ static void perf_top__start_counters(struct perf_top *top) attr->read_format |= PERF_FORMAT_ID; } + if (perf_target__has_cpu(&top->target)) + attr->sample_type |= PERF_SAMPLE_CPU; + if (symbol_conf.use_callchain) attr->sample_type |= PERF_SAMPLE_CALLCHAIN; @@ -948,20 +951,24 @@ try_again: attr->type = PERF_TYPE_SOFTWARE; attr->config = PERF_COUNT_SW_CPU_CLOCK; + if (counter->name) { + free(counter->name); + counter->name = NULL; + } goto try_again; } if (err == ENOENT) { - ui__warning("The %s event is not supported.\n", + ui__error("The %s event is not supported.\n", event_name(counter)); goto out_err; } else if (err == EMFILE) { - ui__warning("Too many events are opened.\n" + ui__error("Too many events are opened.\n" "Try again after reducing the number of events\n"); goto out_err; } - ui__warning("The sys_perf_event_open() syscall " + ui__error("The sys_perf_event_open() syscall " "returned with %d (%s). /bin/dmesg " "may provide additional information.\n" "No CONFIG_PERF_EVENTS=y kernel support " @@ -971,7 +978,7 @@ try_again: } if (perf_evlist__mmap(evlist, top->mmap_pages, false) < 0) { - ui__warning("Failed to mmap with %d (%s)\n", + ui__error("Failed to mmap with %d (%s)\n", errno, strerror(errno)); goto out_err; } @@ -987,12 +994,12 @@ static int perf_top__setup_sample_type(struct perf_top *top) { if (!top->sort_has_symbols) { if (symbol_conf.use_callchain) { - ui__warning("Selected -g but \"sym\" not present in --sort/-s."); + ui__error("Selected -g but \"sym\" not present in --sort/-s."); return -EINVAL; } } else if (!top->dont_use_callchains && callchain_param.mode != CHAIN_NONE) { if (callchain_register_param(&callchain_param) < 0) { - ui__warning("Can't register callchain params.\n"); + ui__error("Can't register callchain params.\n"); return -EINVAL; } } @@ -1016,7 +1023,7 @@ static int __cmd_top(struct perf_top *top) if (ret) goto out_delete; - if (top->target_tid || top->uid != UINT_MAX) + if (perf_target__has_task(&top->target)) perf_event__synthesize_thread_map(&top->tool, top->evlist->threads, perf_event__process, &top->session->host_machine); @@ -1034,7 +1041,7 @@ static int __cmd_top(struct perf_top *top) if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : display_thread), top)) { - printf("Could not create display thread.\n"); + ui__error("Could not create display thread.\n"); exit(-1); } @@ -1043,7 +1050,7 @@ static int __cmd_top(struct perf_top *top) param.sched_priority = top->realtime_prio; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { - printf("Could not set realtime priority.\n"); + ui__error("Could not set realtime priority.\n"); exit(-1); } } @@ -1150,14 +1157,17 @@ static const char * const top_usage[] = { int cmd_top(int argc, const char **argv, const char *prefix __used) { struct perf_evsel *pos; - int status = -ENOMEM; + int status; + char errbuf[BUFSIZ]; struct perf_top top = { .count_filter = 5, .delay_secs = 2, - .uid = UINT_MAX, - .freq = 1000, /* 1 KHz */ + .freq = 4000, /* 4 KHz */ .mmap_pages = 128, .sym_pcnt_filter = 5, + .target = { + .uses_mmap = true, + }, }; char callchain_default_opt[] = "fractal,0.5,callee"; const struct option options[] = { @@ -1166,13 +1176,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) parse_events_option), OPT_INTEGER('c', "count", &top.default_interval, "event period to sample"), - OPT_STRING('p', "pid", &top.target_pid, "pid", + OPT_STRING('p', "pid", &top.target.pid, "pid", "profile events on existing process id"), - OPT_STRING('t', "tid", &top.target_tid, "tid", + OPT_STRING('t', "tid", &top.target.tid, "tid", "profile events on existing thread id"), - OPT_BOOLEAN('a', "all-cpus", &top.system_wide, + OPT_BOOLEAN('a', "all-cpus", &top.target.system_wide, "system-wide collection from all CPUs"), - OPT_STRING('C', "cpu", &top.cpu_list, "cpu", + OPT_STRING('C', "cpu", &top.target.cpu_list, "cpu", "list of cpus to monitor"), OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), @@ -1227,7 +1237,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) "Display raw encoding of assembly instructions (default)"), OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", "Specify disassembler style (e.g. -M intel for intel syntax)"), - OPT_STRING('u', "uid", &top.uid_str, "user", "user to profile"), + OPT_STRING('u', "uid", &top.target.uid_str, "user", "user to profile"), OPT_END() }; @@ -1253,27 +1263,32 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) setup_browser(false); - top.uid = parse_target_uid(top.uid_str, top.target_tid, top.target_pid); - if (top.uid_str != NULL && top.uid == UINT_MAX - 1) - goto out_delete_evlist; + status = perf_target__validate(&top.target); + if (status) { + perf_target__strerror(&top.target, status, errbuf, BUFSIZ); + ui__warning("%s", errbuf); + } - /* CPU and PID are mutually exclusive */ - if (top.target_tid && top.cpu_list) { - printf("WARNING: PID switch overriding CPU\n"); - sleep(1); - top.cpu_list = NULL; + status = perf_target__parse_uid(&top.target); + if (status) { + int saved_errno = errno; + + perf_target__strerror(&top.target, status, errbuf, BUFSIZ); + ui__error("%s", errbuf); + + status = -saved_errno; + goto out_delete_evlist; } - if (top.target_pid) - top.target_tid = top.target_pid; + if (perf_target__none(&top.target)) + top.target.system_wide = true; - if (perf_evlist__create_maps(top.evlist, top.target_pid, - top.target_tid, top.uid, top.cpu_list) < 0) + if (perf_evlist__create_maps(top.evlist, &top.target) < 0) usage_with_options(top_usage, options); if (!top.evlist->nr_entries && perf_evlist__add_default(top.evlist) < 0) { - pr_err("Not enough memory for event selector list\n"); + ui__error("Not enough memory for event selector list\n"); return -ENOMEM; } @@ -1290,7 +1305,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) else if (top.freq) { top.default_interval = top.freq; } else { - fprintf(stderr, "frequency and count are zero, aborting\n"); + ui__error("frequency and count are zero, aborting\n"); exit(EXIT_FAILURE); } |