diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index e08d21ffd3a6..dfcfe2c131de 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c @@ -1584,7 +1584,7 @@ get_value(struct event_format *event, const char *name; name = get_comm(event, record); - return (unsigned long long)name; + return (unsigned long)name; } pevent_read_number_field(field, record->data, &val); diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 1d3d513beb9b..0eee64cfe9a0 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -80,7 +80,7 @@ ifeq ("$(origin DEBUG)", "command line") PERF_DEBUG = $(DEBUG) endif ifndef PERF_DEBUG - CFLAGS_OPTIMIZE = -O6 + CFLAGS_OPTIMIZE = -O6 -D_FORTIFY_SOURCE=2 endif ifdef PARSER_DEBUG @@ -89,7 +89,7 @@ ifdef PARSER_DEBUG PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG endif -CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS) +CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS) EXTLIBS = -lpthread -lrt -lelf -lm ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE ALL_LDFLAGS = $(LDFLAGS) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 806e0a286634..67522cf87405 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -215,7 +215,7 @@ static int __cmd_annotate(struct perf_annotate *ann) } if (total_nr_samples == 0) { - ui__warning("The %s file has no samples!\n", session->filename); + ui__error("The %s file has no samples!\n", session->filename); goto out_delete; } out_delete: diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e5cb08427e13..f95840d04e4c 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -264,7 +264,7 @@ static void perf_record__open(struct perf_record *rec) } if (err == ENOENT) { - ui__warning("The %s event is not supported.\n", + ui__error("The %s event is not supported.\n", event_name(pos)); exit(EXIT_FAILURE); } @@ -858,8 +858,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) usage_with_options(record_usage, record_options); if (rec->force && rec->append_file) { - fprintf(stderr, "Can't overwrite and append at the same time." - " You need to choose between -f and -A"); + ui__error("Can't overwrite and append at the same time." + " You need to choose between -f and -A"); usage_with_options(record_usage, record_options); } else if (rec->append_file) { rec->write_mode = WRITE_APPEND; @@ -868,8 +868,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) } if (nr_cgroups && !rec->opts.target.system_wide) { - fprintf(stderr, "cgroup monitoring only available in" - " system-wide mode\n"); + ui__error("cgroup monitoring only available in" + " system-wide mode\n"); usage_with_options(record_usage, record_options); } @@ -905,7 +905,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) int saved_errno = errno; perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); - ui__warning("%s", errbuf); + ui__error("%s", errbuf); err = -saved_errno; goto out_free_fd; @@ -933,7 +933,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) else if (rec->opts.freq) { rec->opts.default_interval = rec->opts.freq; } else { - fprintf(stderr, "frequency and count are zero, aborting\n"); + ui__error("frequency and count are zero, aborting\n"); err = -EINVAL; goto out_free_fd; } diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d58e41445d0d..8c767c6bca91 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -251,13 +251,13 @@ static int perf_report__setup_sample_type(struct perf_report *rep) if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { - ui__warning("Selected --sort parent, but no " + ui__error("Selected --sort parent, but no " "callchain data. Did you call " "'perf record' without -g?\n"); return -EINVAL; } if (symbol_conf.use_callchain) { - ui__warning("Selected -g but no callchain data. Did " + ui__error("Selected -g but no callchain data. Did " "you call 'perf record' without -g?\n"); return -1; } @@ -266,17 +266,15 @@ static int perf_report__setup_sample_type(struct perf_report *rep) !symbol_conf.use_callchain) { symbol_conf.use_callchain = true; 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; } } if (sort__branch_mode == 1) { if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { - fprintf(stderr, "selected -b but no branch data." - " Did you call perf record without" - " -b?\n"); + ui__error("Selected -b but no branch data. " + "Did you call perf record without -b?\n"); return -1; } } @@ -420,7 +418,7 @@ static int __cmd_report(struct perf_report *rep) } if (nr_samples == 0) { - ui__warning("The %s file has no samples!\n", session->filename); + ui__error("The %s file has no samples!\n", session->filename); goto out_delete; } diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 6031dce0429f..871b540293e1 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -953,22 +953,22 @@ static void perf_top__start_counters(struct perf_top *top) attr->config = PERF_COUNT_SW_CPU_CLOCK; if (counter->name) { free(counter->name); - counter->name = strdup(event_name(counter)); + 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 " @@ -978,7 +978,7 @@ static void perf_top__start_counters(struct perf_top *top) } 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; } @@ -994,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; } } @@ -1041,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); } @@ -1050,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); } } @@ -1274,7 +1274,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) int saved_errno = errno; perf_target__strerror(&top.target, status, errbuf, BUFSIZ); - ui__warning("%s", errbuf); + ui__error("%s", errbuf); status = -saved_errno; goto out_delete_evlist; @@ -1288,7 +1288,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) 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; } @@ -1305,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); } diff --git a/tools/perf/perf.h b/tools/perf/perf.h index 14f1034f14f9..f960ccb2edc6 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -227,7 +227,7 @@ struct perf_record_opts { unsigned int freq; unsigned int mmap_pages; unsigned int user_freq; - int branch_stack; + u64 branch_stack; u64 default_interval; u64 user_interval; }; diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 6e0ef79be169..aaf36ce0b6fe 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -300,10 +300,14 @@ static void annotate_browser__set_rb_top(struct annotate_browser *browser, { struct browser_disasm_line *bpos; struct disasm_line *pos; + u32 idx; bpos = rb_entry(nd, struct browser_disasm_line, rb_node); pos = ((struct disasm_line *)bpos) - 1; - annotate_browser__set_top(browser, pos, bpos->idx); + idx = bpos->idx; + if (browser->hide_src_code) + idx = bpos->idx_asm; + annotate_browser__set_top(browser, pos, idx); browser->curr_hot = nd; } diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 9f5f888f73e3..791fb15ce350 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -22,6 +22,7 @@ void setup_browser(bool fallback_to_pager) break; /* fall through */ default: + use_browser = 0; if (fallback_to_pager) setup_pager(); break; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 57e4ce57bbcc..91d19138f3ec 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -15,6 +15,7 @@ #include "cpumap.h" #include "thread_map.h" #include "target.h" +#include "../../include/linux/perf_event.h" #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) @@ -64,6 +65,95 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) return evsel; } +static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { + "cycles", + "instructions", + "cache-references", + "cache-misses", + "branches", + "branch-misses", + "bus-cycles", + "stalled-cycles-frontend", + "stalled-cycles-backend", + "ref-cycles", +}; + +const char *__perf_evsel__hw_name(u64 config) +{ + if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config]) + return perf_evsel__hw_names[config]; + + return "unknown-hardware"; +} + +static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) +{ + int colon = 0; + struct perf_event_attr *attr = &evsel->attr; + int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config)); + bool exclude_guest_default = false; + +#define MOD_PRINT(context, mod) do { \ + if (!attr->exclude_##context) { \ + if (!colon) colon = r++; \ + r += scnprintf(bf + r, size - r, "%c", mod); \ + } } while(0) + + if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv) { + MOD_PRINT(kernel, 'k'); + MOD_PRINT(user, 'u'); + MOD_PRINT(hv, 'h'); + exclude_guest_default = true; + } + + if (attr->precise_ip) { + if (!colon) + colon = r++; + r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp"); + exclude_guest_default = true; + } + + if (attr->exclude_host || attr->exclude_guest == exclude_guest_default) { + MOD_PRINT(host, 'H'); + MOD_PRINT(guest, 'G'); + } +#undef MOD_PRINT + if (colon) + bf[colon] = ':'; + return r; +} + +int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size) +{ + int ret; + + switch (evsel->attr.type) { + case PERF_TYPE_RAW: + ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config); + break; + + case PERF_TYPE_HARDWARE: + ret = perf_evsel__hw_name(evsel, bf, size); + break; + default: + /* + * FIXME + * + * This is the minimal perf_evsel__name so that we can + * reconstruct event names taking into account event modifiers. + * + * The old event_name uses it now for raw anr hw events, so that + * we don't drag all the parsing stuff into the python binding. + * + * On the next devel cycle the rest of the event naming will be + * brought here. + */ + return 0; + } + + return ret; +} + void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, struct perf_evsel *first) { diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3d6b3e4cb66b..4ba8b564e6f4 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -83,6 +83,9 @@ void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, struct perf_evsel *first); +const char* __perf_evsel__hw_name(u64 config); +int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size); + int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index fac7d59309b8..05dbc8b3c767 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -62,19 +62,6 @@ static struct event_symbol event_symbols[] = { #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) -static const char *hw_event_names[PERF_COUNT_HW_MAX] = { - "cycles", - "instructions", - "cache-references", - "cache-misses", - "branches", - "branch-misses", - "bus-cycles", - "stalled-cycles-frontend", - "stalled-cycles-backend", - "ref-cycles", -}; - static const char *sw_event_names[PERF_COUNT_SW_MAX] = { "cpu-clock", "task-clock", @@ -300,6 +287,16 @@ const char *event_name(struct perf_evsel *evsel) u64 config = evsel->attr.config; int type = evsel->attr.type; + if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) { + /* + * XXX minimal fix, see comment on perf_evsen__name, this static buffer + * will go away together with event_name in the next devel cycle. + */ + static char bf[128]; + perf_evsel__name(evsel, bf, sizeof(bf)); + return bf; + } + if (evsel->name) return evsel->name; @@ -317,9 +314,7 @@ const char *__event_name(int type, u64 config) switch (type) { case PERF_TYPE_HARDWARE: - if (config < PERF_COUNT_HW_MAX && hw_event_names[config]) - return hw_event_names[config]; - return "unknown-hardware"; + return __perf_evsel__hw_name(config); case PERF_TYPE_HW_CACHE: { u8 cache_type, cache_op, cache_result; diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index 84d9bd782004..9b5f856cc280 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -188,28 +188,27 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str) nt = realloc(threads, (sizeof(*threads) + sizeof(pid_t) * total_tasks)); if (nt == NULL) - goto out_free_threads; + goto out_free_namelist; threads = nt; - if (threads) { - for (i = 0; i < items; i++) - threads->map[j++] = atoi(namelist[i]->d_name); - threads->nr = total_tasks; - } - - for (i = 0; i < items; i++) + for (i = 0; i < items; i++) { + threads->map[j++] = atoi(namelist[i]->d_name); free(namelist[i]); + } + threads->nr = total_tasks; free(namelist); - - if (!threads) - break; } out: strlist__delete(slist); return threads; +out_free_namelist: + for (i = 0; i < items; i++) + free(namelist[i]); + free(namelist); + out_free_threads: free(threads); threads = NULL;