diff options
| author | Ingo Molnar <mingo@kernel.org> | 2012-09-07 01:36:59 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2012-09-07 01:36:59 -0400 |
| commit | 479d875835a49e849683743ec50c30b6a429696b (patch) | |
| tree | 616b96197e489d3fbd5ef8bdde5a59a50d6dcd76 | |
| parent | bab57e994d6311298b4e3915d2c75296cd81638c (diff) | |
| parent | 275ef3878f698941353780440fec6926107a320b (diff) | |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
- Rename libtraceevent 'private' struct member to 'priv' so that it works
in C++, from Steven Rostedt
- Remove lots of exit()/die() calls from tools so that the main perf exit
routine can take place, from David Ahern
- Fix x86 build on x86-64, from David Ahern.
- Remove some headers that prevented perf from building on Android,
from David Ahern
- {int,str,rb}list fixes from Suzuki K Poulose
- perf.data header fixes from Namhyung Kim
- Replace needless mempcpy with memcpy, to allow build on Android, from Irina Tirdea
- Allow user to indicate objdump path, needed in cross environments, from
Maciek Borzecki
- Fix hardware cache event name generation, fix from Jiri Olsa
- Add round trip test for sw, hw and cache event names, catching the
problem Jiri fixed, after Jiri's patch, the test passes successfully.
- Clean target should do clean for lib/traceevent too, fix from David Ahern
- Check the right variable for allocation failure, fix from Namhyung Kim
- Set up evsel->tp_format regardless of evsel->name being set already,
fix from Namhyung Kim
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
27 files changed, 550 insertions, 202 deletions
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 527df038a25f..863a0bbda7f1 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
| @@ -49,7 +49,7 @@ struct pevent_record { | |||
| 49 | int cpu; | 49 | int cpu; |
| 50 | int ref_count; | 50 | int ref_count; |
| 51 | int locked; /* Do not free, even if ref_count is zero */ | 51 | int locked; /* Do not free, even if ref_count is zero */ |
| 52 | void *private; | 52 | void *priv; |
| 53 | #if DEBUG_RECORD | 53 | #if DEBUG_RECORD |
| 54 | struct pevent_record *prev; | 54 | struct pevent_record *prev; |
| 55 | struct pevent_record *next; | 55 | struct pevent_record *next; |
| @@ -106,7 +106,7 @@ struct plugin_option { | |||
| 106 | char *plugin_alias; | 106 | char *plugin_alias; |
| 107 | char *description; | 107 | char *description; |
| 108 | char *value; | 108 | char *value; |
| 109 | void *private; | 109 | void *priv; |
| 110 | int set; | 110 | int set; |
| 111 | }; | 111 | }; |
| 112 | 112 | ||
diff --git a/tools/perf/Documentation/perf-annotate.txt b/tools/perf/Documentation/perf-annotate.txt index c89f9e1453f7..c8ffd9fd5c6a 100644 --- a/tools/perf/Documentation/perf-annotate.txt +++ b/tools/perf/Documentation/perf-annotate.txt | |||
| @@ -85,6 +85,9 @@ OPTIONS | |||
| 85 | -M:: | 85 | -M:: |
| 86 | --disassembler-style=:: Set disassembler style for objdump. | 86 | --disassembler-style=:: Set disassembler style for objdump. |
| 87 | 87 | ||
| 88 | --objdump=<path>:: | ||
| 89 | Path to objdump binary. | ||
| 90 | |||
| 88 | SEE ALSO | 91 | SEE ALSO |
| 89 | -------- | 92 | -------- |
| 90 | linkperf:perf-record[1], linkperf:perf-report[1] | 93 | linkperf:perf-record[1], linkperf:perf-report[1] |
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index 495210a612c4..f4d91bebd59d 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt | |||
| @@ -168,6 +168,9 @@ OPTIONS | |||
| 168 | branch stacks and it will automatically switch to the branch view mode, | 168 | branch stacks and it will automatically switch to the branch view mode, |
| 169 | unless --no-branch-stack is used. | 169 | unless --no-branch-stack is used. |
| 170 | 170 | ||
| 171 | --objdump=<path>:: | ||
| 172 | Path to objdump binary. | ||
| 173 | |||
| 171 | SEE ALSO | 174 | SEE ALSO |
| 172 | -------- | 175 | -------- |
| 173 | linkperf:perf-stat[1], linkperf:perf-annotate[1] | 176 | linkperf:perf-stat[1], linkperf:perf-annotate[1] |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 722ddee61f9f..afd507574902 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
| @@ -64,12 +64,12 @@ AR = $(CROSS_COMPILE)ar | |||
| 64 | 64 | ||
| 65 | # Additional ARCH settings for x86 | 65 | # Additional ARCH settings for x86 |
| 66 | ifeq ($(ARCH),i386) | 66 | ifeq ($(ARCH),i386) |
| 67 | ARCH := x86 | 67 | override ARCH := x86 |
| 68 | NO_PERF_REGS := 0 | 68 | NO_PERF_REGS := 0 |
| 69 | LIBUNWIND_LIBS = -lunwind -lunwind-x86 | 69 | LIBUNWIND_LIBS = -lunwind -lunwind-x86 |
| 70 | endif | 70 | endif |
| 71 | ifeq ($(ARCH),x86_64) | 71 | ifeq ($(ARCH),x86_64) |
| 72 | ARCH := x86 | 72 | override ARCH := x86 |
| 73 | IS_X86_64 := 0 | 73 | IS_X86_64 := 0 |
| 74 | ifeq (, $(findstring m32,$(EXTRA_CFLAGS))) | 74 | ifeq (, $(findstring m32,$(EXTRA_CFLAGS))) |
| 75 | IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) | 75 | IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) |
| @@ -917,6 +917,9 @@ $(LIB_FILE): $(LIB_OBJS) | |||
| 917 | $(LIBTRACEEVENT): | 917 | $(LIBTRACEEVENT): |
| 918 | $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a | 918 | $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a |
| 919 | 919 | ||
| 920 | $(LIBTRACEEVENT)-clean: | ||
| 921 | $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean | ||
| 922 | |||
| 920 | help: | 923 | help: |
| 921 | @echo 'Perf make targets:' | 924 | @echo 'Perf make targets:' |
| 922 | @echo ' doc - make *all* documentation (see below)' | 925 | @echo ' doc - make *all* documentation (see below)' |
| @@ -1056,7 +1059,7 @@ quick-install-html: | |||
| 1056 | 1059 | ||
| 1057 | ### Cleaning rules | 1060 | ### Cleaning rules |
| 1058 | 1061 | ||
| 1059 | clean: | 1062 | clean: $(LIBTRACEEVENT)-clean |
| 1060 | $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) | 1063 | $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) |
| 1061 | $(RM) $(ALL_PROGRAMS) perf | 1064 | $(RM) $(ALL_PROGRAMS) perf |
| 1062 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* | 1065 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 67522cf87405..2f3f0029c0f7 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -282,6 +282,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) | |||
| 282 | "Display raw encoding of assembly instructions (default)"), | 282 | "Display raw encoding of assembly instructions (default)"), |
| 283 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", | 283 | OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", |
| 284 | "Specify disassembler style (e.g. -M intel for intel syntax)"), | 284 | "Specify disassembler style (e.g. -M intel for intel syntax)"), |
| 285 | OPT_STRING(0, "objdump", &objdump_path, "path", | ||
| 286 | "objdump binary to use for disassembly and annotations"), | ||
| 285 | OPT_END() | 287 | OPT_END() |
| 286 | }; | 288 | }; |
| 287 | 289 | ||
diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 6d5a8a7faf48..f9daae5ac47a 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c | |||
| @@ -24,13 +24,14 @@ static struct man_viewer_info_list { | |||
| 24 | } *man_viewer_info_list; | 24 | } *man_viewer_info_list; |
| 25 | 25 | ||
| 26 | enum help_format { | 26 | enum help_format { |
| 27 | HELP_FORMAT_NONE, | ||
| 27 | HELP_FORMAT_MAN, | 28 | HELP_FORMAT_MAN, |
| 28 | HELP_FORMAT_INFO, | 29 | HELP_FORMAT_INFO, |
| 29 | HELP_FORMAT_WEB, | 30 | HELP_FORMAT_WEB, |
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | static bool show_all = false; | 33 | static bool show_all = false; |
| 33 | static enum help_format help_format = HELP_FORMAT_MAN; | 34 | static enum help_format help_format = HELP_FORMAT_NONE; |
| 34 | static struct option builtin_help_options[] = { | 35 | static struct option builtin_help_options[] = { |
| 35 | OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), | 36 | OPT_BOOLEAN('a', "all", &show_all, "print all available commands"), |
| 36 | OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), | 37 | OPT_SET_UINT('m', "man", &help_format, "show man page", HELP_FORMAT_MAN), |
| @@ -54,7 +55,9 @@ static enum help_format parse_help_format(const char *format) | |||
| 54 | return HELP_FORMAT_INFO; | 55 | return HELP_FORMAT_INFO; |
| 55 | if (!strcmp(format, "web") || !strcmp(format, "html")) | 56 | if (!strcmp(format, "web") || !strcmp(format, "html")) |
| 56 | return HELP_FORMAT_WEB; | 57 | return HELP_FORMAT_WEB; |
| 57 | die("unrecognized help format '%s'", format); | 58 | |
| 59 | pr_err("unrecognized help format '%s'", format); | ||
| 60 | return HELP_FORMAT_NONE; | ||
| 58 | } | 61 | } |
| 59 | 62 | ||
| 60 | static const char *get_man_viewer_info(const char *name) | 63 | static const char *get_man_viewer_info(const char *name) |
| @@ -259,6 +262,8 @@ static int perf_help_config(const char *var, const char *value, void *cb) | |||
| 259 | if (!value) | 262 | if (!value) |
| 260 | return config_error_nonbool(var); | 263 | return config_error_nonbool(var); |
| 261 | help_format = parse_help_format(value); | 264 | help_format = parse_help_format(value); |
| 265 | if (help_format == HELP_FORMAT_NONE) | ||
| 266 | return -1; | ||
| 262 | return 0; | 267 | return 0; |
| 263 | } | 268 | } |
| 264 | if (!strcmp(var, "man.viewer")) { | 269 | if (!strcmp(var, "man.viewer")) { |
| @@ -352,7 +357,7 @@ static void exec_viewer(const char *name, const char *page) | |||
| 352 | warning("'%s': unknown man viewer.", name); | 357 | warning("'%s': unknown man viewer.", name); |
| 353 | } | 358 | } |
| 354 | 359 | ||
| 355 | static void show_man_page(const char *perf_cmd) | 360 | static int show_man_page(const char *perf_cmd) |
| 356 | { | 361 | { |
| 357 | struct man_viewer_list *viewer; | 362 | struct man_viewer_list *viewer; |
| 358 | const char *page = cmd_to_page(perf_cmd); | 363 | const char *page = cmd_to_page(perf_cmd); |
| @@ -365,28 +370,35 @@ static void show_man_page(const char *perf_cmd) | |||
| 365 | if (fallback) | 370 | if (fallback) |
| 366 | exec_viewer(fallback, page); | 371 | exec_viewer(fallback, page); |
| 367 | exec_viewer("man", page); | 372 | exec_viewer("man", page); |
| 368 | die("no man viewer handled the request"); | 373 | |
| 374 | pr_err("no man viewer handled the request"); | ||
| 375 | return -1; | ||
| 369 | } | 376 | } |
| 370 | 377 | ||
| 371 | static void show_info_page(const char *perf_cmd) | 378 | static int show_info_page(const char *perf_cmd) |
| 372 | { | 379 | { |
| 373 | const char *page = cmd_to_page(perf_cmd); | 380 | const char *page = cmd_to_page(perf_cmd); |
| 374 | setenv("INFOPATH", system_path(PERF_INFO_PATH), 1); | 381 | setenv("INFOPATH", system_path(PERF_INFO_PATH), 1); |
| 375 | execlp("info", "info", "perfman", page, NULL); | 382 | execlp("info", "info", "perfman", page, NULL); |
| 383 | return -1; | ||
| 376 | } | 384 | } |
| 377 | 385 | ||
| 378 | static void get_html_page_path(struct strbuf *page_path, const char *page) | 386 | static int get_html_page_path(struct strbuf *page_path, const char *page) |
| 379 | { | 387 | { |
| 380 | struct stat st; | 388 | struct stat st; |
| 381 | const char *html_path = system_path(PERF_HTML_PATH); | 389 | const char *html_path = system_path(PERF_HTML_PATH); |
| 382 | 390 | ||
| 383 | /* Check that we have a perf documentation directory. */ | 391 | /* Check that we have a perf documentation directory. */ |
| 384 | if (stat(mkpath("%s/perf.html", html_path), &st) | 392 | if (stat(mkpath("%s/perf.html", html_path), &st) |
| 385 | || !S_ISREG(st.st_mode)) | 393 | || !S_ISREG(st.st_mode)) { |
| 386 | die("'%s': not a documentation directory.", html_path); | 394 | pr_err("'%s': not a documentation directory.", html_path); |
| 395 | return -1; | ||
| 396 | } | ||
| 387 | 397 | ||
| 388 | strbuf_init(page_path, 0); | 398 | strbuf_init(page_path, 0); |
| 389 | strbuf_addf(page_path, "%s/%s.html", html_path, page); | 399 | strbuf_addf(page_path, "%s/%s.html", html_path, page); |
| 400 | |||
| 401 | return 0; | ||
| 390 | } | 402 | } |
| 391 | 403 | ||
| 392 | /* | 404 | /* |
| @@ -401,19 +413,23 @@ static void open_html(const char *path) | |||
| 401 | } | 413 | } |
| 402 | #endif | 414 | #endif |
| 403 | 415 | ||
| 404 | static void show_html_page(const char *perf_cmd) | 416 | static int show_html_page(const char *perf_cmd) |
| 405 | { | 417 | { |
| 406 | const char *page = cmd_to_page(perf_cmd); | 418 | const char *page = cmd_to_page(perf_cmd); |
| 407 | struct strbuf page_path; /* it leaks but we exec bellow */ | 419 | struct strbuf page_path; /* it leaks but we exec bellow */ |
| 408 | 420 | ||
| 409 | get_html_page_path(&page_path, page); | 421 | if (get_html_page_path(&page_path, page) != 0) |
| 422 | return -1; | ||
| 410 | 423 | ||
| 411 | open_html(page_path.buf); | 424 | open_html(page_path.buf); |
| 425 | |||
| 426 | return 0; | ||
| 412 | } | 427 | } |
| 413 | 428 | ||
| 414 | int cmd_help(int argc, const char **argv, const char *prefix __used) | 429 | int cmd_help(int argc, const char **argv, const char *prefix __used) |
| 415 | { | 430 | { |
| 416 | const char *alias; | 431 | const char *alias; |
| 432 | int rc = 0; | ||
| 417 | 433 | ||
| 418 | load_command_list("perf-", &main_cmds, &other_cmds); | 434 | load_command_list("perf-", &main_cmds, &other_cmds); |
| 419 | 435 | ||
| @@ -444,16 +460,20 @@ int cmd_help(int argc, const char **argv, const char *prefix __used) | |||
| 444 | 460 | ||
| 445 | switch (help_format) { | 461 | switch (help_format) { |
| 446 | case HELP_FORMAT_MAN: | 462 | case HELP_FORMAT_MAN: |
| 447 | show_man_page(argv[0]); | 463 | rc = show_man_page(argv[0]); |
| 448 | break; | 464 | break; |
| 449 | case HELP_FORMAT_INFO: | 465 | case HELP_FORMAT_INFO: |
| 450 | show_info_page(argv[0]); | 466 | rc = show_info_page(argv[0]); |
| 451 | break; | 467 | break; |
| 452 | case HELP_FORMAT_WEB: | 468 | case HELP_FORMAT_WEB: |
| 453 | show_html_page(argv[0]); | 469 | rc = show_html_page(argv[0]); |
| 470 | break; | ||
| 471 | case HELP_FORMAT_NONE: | ||
| 472 | /* fall-through */ | ||
| 454 | default: | 473 | default: |
| 474 | rc = -1; | ||
| 455 | break; | 475 | break; |
| 456 | } | 476 | } |
| 457 | 477 | ||
| 458 | return 0; | 478 | return rc; |
| 459 | } | 479 | } |
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 585aae2858b8..75153c87e650 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
| @@ -161,8 +161,10 @@ static struct thread_stat *thread_stat_findnew_after_first(u32 tid) | |||
| 161 | return st; | 161 | return st; |
| 162 | 162 | ||
| 163 | st = zalloc(sizeof(struct thread_stat)); | 163 | st = zalloc(sizeof(struct thread_stat)); |
| 164 | if (!st) | 164 | if (!st) { |
| 165 | die("memory allocation failed\n"); | 165 | pr_err("memory allocation failed\n"); |
| 166 | return NULL; | ||
| 167 | } | ||
| 166 | 168 | ||
| 167 | st->tid = tid; | 169 | st->tid = tid; |
| 168 | INIT_LIST_HEAD(&st->seq_list); | 170 | INIT_LIST_HEAD(&st->seq_list); |
| @@ -181,8 +183,10 @@ static struct thread_stat *thread_stat_findnew_first(u32 tid) | |||
| 181 | struct thread_stat *st; | 183 | struct thread_stat *st; |
| 182 | 184 | ||
| 183 | st = zalloc(sizeof(struct thread_stat)); | 185 | st = zalloc(sizeof(struct thread_stat)); |
| 184 | if (!st) | 186 | if (!st) { |
| 185 | die("memory allocation failed\n"); | 187 | pr_err("memory allocation failed\n"); |
| 188 | return NULL; | ||
| 189 | } | ||
| 186 | st->tid = tid; | 190 | st->tid = tid; |
| 187 | INIT_LIST_HEAD(&st->seq_list); | 191 | INIT_LIST_HEAD(&st->seq_list); |
| 188 | 192 | ||
| @@ -248,18 +252,20 @@ struct lock_key keys[] = { | |||
| 248 | { NULL, NULL } | 252 | { NULL, NULL } |
| 249 | }; | 253 | }; |
| 250 | 254 | ||
| 251 | static void select_key(void) | 255 | static int select_key(void) |
| 252 | { | 256 | { |
| 253 | int i; | 257 | int i; |
| 254 | 258 | ||
| 255 | for (i = 0; keys[i].name; i++) { | 259 | for (i = 0; keys[i].name; i++) { |
| 256 | if (!strcmp(keys[i].name, sort_key)) { | 260 | if (!strcmp(keys[i].name, sort_key)) { |
| 257 | compare = keys[i].key; | 261 | compare = keys[i].key; |
| 258 | return; | 262 | return 0; |
| 259 | } | 263 | } |
| 260 | } | 264 | } |
| 261 | 265 | ||
| 262 | die("Unknown compare key:%s\n", sort_key); | 266 | pr_err("Unknown compare key: %s\n", sort_key); |
| 267 | |||
| 268 | return -1; | ||
| 263 | } | 269 | } |
| 264 | 270 | ||
| 265 | static void insert_to_result(struct lock_stat *st, | 271 | static void insert_to_result(struct lock_stat *st, |
| @@ -324,7 +330,8 @@ static struct lock_stat *lock_stat_findnew(void *addr, const char *name) | |||
| 324 | return new; | 330 | return new; |
| 325 | 331 | ||
| 326 | alloc_failed: | 332 | alloc_failed: |
| 327 | die("memory allocation failed\n"); | 333 | pr_err("memory allocation failed\n"); |
| 334 | return NULL; | ||
| 328 | } | 335 | } |
| 329 | 336 | ||
| 330 | static const char *input_name; | 337 | static const char *input_name; |
| @@ -356,16 +363,16 @@ struct trace_release_event { | |||
| 356 | }; | 363 | }; |
| 357 | 364 | ||
| 358 | struct trace_lock_handler { | 365 | struct trace_lock_handler { |
| 359 | void (*acquire_event)(struct trace_acquire_event *, | 366 | int (*acquire_event)(struct trace_acquire_event *, |
| 360 | const struct perf_sample *sample); | 367 | const struct perf_sample *sample); |
| 361 | 368 | ||
| 362 | void (*acquired_event)(struct trace_acquired_event *, | 369 | int (*acquired_event)(struct trace_acquired_event *, |
| 363 | const struct perf_sample *sample); | 370 | const struct perf_sample *sample); |
| 364 | 371 | ||
| 365 | void (*contended_event)(struct trace_contended_event *, | 372 | int (*contended_event)(struct trace_contended_event *, |
| 366 | const struct perf_sample *sample); | 373 | const struct perf_sample *sample); |
| 367 | 374 | ||
| 368 | void (*release_event)(struct trace_release_event *, | 375 | int (*release_event)(struct trace_release_event *, |
| 369 | const struct perf_sample *sample); | 376 | const struct perf_sample *sample); |
| 370 | }; | 377 | }; |
| 371 | 378 | ||
| @@ -379,8 +386,10 @@ static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr) | |||
| 379 | } | 386 | } |
| 380 | 387 | ||
| 381 | seq = zalloc(sizeof(struct lock_seq_stat)); | 388 | seq = zalloc(sizeof(struct lock_seq_stat)); |
| 382 | if (!seq) | 389 | if (!seq) { |
| 383 | die("Not enough memory\n"); | 390 | pr_err("memory allocation failed\n"); |
| 391 | return NULL; | ||
| 392 | } | ||
| 384 | seq->state = SEQ_STATE_UNINITIALIZED; | 393 | seq->state = SEQ_STATE_UNINITIALIZED; |
| 385 | seq->addr = addr; | 394 | seq->addr = addr; |
| 386 | 395 | ||
| @@ -403,7 +412,7 @@ enum acquire_flags { | |||
| 403 | READ_LOCK = 2, | 412 | READ_LOCK = 2, |
| 404 | }; | 413 | }; |
| 405 | 414 | ||
| 406 | static void | 415 | static int |
| 407 | report_lock_acquire_event(struct trace_acquire_event *acquire_event, | 416 | report_lock_acquire_event(struct trace_acquire_event *acquire_event, |
| 408 | const struct perf_sample *sample) | 417 | const struct perf_sample *sample) |
| 409 | { | 418 | { |
| @@ -412,11 +421,18 @@ report_lock_acquire_event(struct trace_acquire_event *acquire_event, | |||
| 412 | struct lock_seq_stat *seq; | 421 | struct lock_seq_stat *seq; |
| 413 | 422 | ||
| 414 | ls = lock_stat_findnew(acquire_event->addr, acquire_event->name); | 423 | ls = lock_stat_findnew(acquire_event->addr, acquire_event->name); |
| 424 | if (!ls) | ||
| 425 | return -1; | ||
| 415 | if (ls->discard) | 426 | if (ls->discard) |
| 416 | return; | 427 | return 0; |
| 417 | 428 | ||
| 418 | ts = thread_stat_findnew(sample->tid); | 429 | ts = thread_stat_findnew(sample->tid); |
| 430 | if (!ts) | ||
| 431 | return -1; | ||
| 432 | |||
| 419 | seq = get_seq(ts, acquire_event->addr); | 433 | seq = get_seq(ts, acquire_event->addr); |
| 434 | if (!seq) | ||
| 435 | return -1; | ||
| 420 | 436 | ||
| 421 | switch (seq->state) { | 437 | switch (seq->state) { |
| 422 | case SEQ_STATE_UNINITIALIZED: | 438 | case SEQ_STATE_UNINITIALIZED: |
| @@ -461,10 +477,10 @@ broken: | |||
| 461 | ls->nr_acquire++; | 477 | ls->nr_acquire++; |
| 462 | seq->prev_event_time = sample->time; | 478 | seq->prev_event_time = sample->time; |
| 463 | end: | 479 | end: |
| 464 | return; | 480 | return 0; |
| 465 | } | 481 | } |
| 466 | 482 | ||
| 467 | static void | 483 | static int |
| 468 | report_lock_acquired_event(struct trace_acquired_event *acquired_event, | 484 | report_lock_acquired_event(struct trace_acquired_event *acquired_event, |
| 469 | const struct perf_sample *sample) | 485 | const struct perf_sample *sample) |
| 470 | { | 486 | { |
| @@ -475,16 +491,23 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event, | |||
| 475 | u64 contended_term; | 491 | u64 contended_term; |
| 476 | 492 | ||
| 477 | ls = lock_stat_findnew(acquired_event->addr, acquired_event->name); | 493 | ls = lock_stat_findnew(acquired_event->addr, acquired_event->name); |
| 494 | if (!ls) | ||
| 495 | return -1; | ||
| 478 | if (ls->discard) | 496 | if (ls->discard) |
| 479 | return; | 497 | return 0; |
| 480 | 498 | ||
| 481 | ts = thread_stat_findnew(sample->tid); | 499 | ts = thread_stat_findnew(sample->tid); |
| 500 | if (!ts) | ||
| 501 | return -1; | ||
| 502 | |||
| 482 | seq = get_seq(ts, acquired_event->addr); | 503 | seq = get_seq(ts, acquired_event->addr); |
| 504 | if (!seq) | ||
| 505 | return -1; | ||
| 483 | 506 | ||
| 484 | switch (seq->state) { | 507 | switch (seq->state) { |
| 485 | case SEQ_STATE_UNINITIALIZED: | 508 | case SEQ_STATE_UNINITIALIZED: |
| 486 | /* orphan event, do nothing */ | 509 | /* orphan event, do nothing */ |
| 487 | return; | 510 | return 0; |
| 488 | case SEQ_STATE_ACQUIRING: | 511 | case SEQ_STATE_ACQUIRING: |
| 489 | break; | 512 | break; |
| 490 | case SEQ_STATE_CONTENDED: | 513 | case SEQ_STATE_CONTENDED: |
| @@ -515,10 +538,10 @@ report_lock_acquired_event(struct trace_acquired_event *acquired_event, | |||
| 515 | ls->nr_acquired++; | 538 | ls->nr_acquired++; |
| 516 | seq->prev_event_time = timestamp; | 539 | seq->prev_event_time = timestamp; |
| 517 | end: | 540 | end: |
| 518 | return; | 541 | return 0; |
| 519 | } | 542 | } |
| 520 | 543 | ||
| 521 | static void | 544 | static int |
| 522 | report_lock_contended_event(struct trace_contended_event *contended_event, | 545 | report_lock_contended_event(struct trace_contended_event *contended_event, |
| 523 | const struct perf_sample *sample) | 546 | const struct perf_sample *sample) |
| 524 | { | 547 | { |
| @@ -527,16 +550,23 @@ report_lock_contended_event(struct trace_contended_event *contended_event, | |||
| 527 | struct lock_seq_stat *seq; | 550 | struct lock_seq_stat *seq; |
| 528 | 551 | ||
| 529 | ls = lock_stat_findnew(contended_event->addr, contended_event->name); | 552 | ls = lock_stat_findnew(contended_event->addr, contended_event->name); |
| 553 | if (!ls) | ||
| 554 | return -1; | ||
| 530 | if (ls->discard) | 555 | if (ls->discard) |
| 531 | return; | 556 | return 0; |
| 532 | 557 | ||
| 533 | ts = thread_stat_findnew(sample->tid); | 558 | ts = thread_stat_findnew(sample->tid); |
| 559 | if (!ts) | ||
| 560 | return -1; | ||
| 561 | |||
| 534 | seq = get_seq(ts, contended_event->addr); | 562 | seq = get_seq(ts, contended_event->addr); |
| 563 | if (!seq) | ||
| 564 | return -1; | ||
| 535 | 565 | ||
| 536 | switch (seq->state) { | 566 | switch (seq->state) { |
| 537 | case SEQ_STATE_UNINITIALIZED: | 567 | case SEQ_STATE_UNINITIALIZED: |
| 538 | /* orphan event, do nothing */ | 568 | /* orphan event, do nothing */ |
| 539 | return; | 569 | return 0; |
| 540 | case SEQ_STATE_ACQUIRING: | 570 | case SEQ_STATE_ACQUIRING: |
| 541 | break; | 571 | break; |
| 542 | case SEQ_STATE_RELEASED: | 572 | case SEQ_STATE_RELEASED: |
| @@ -559,10 +589,10 @@ report_lock_contended_event(struct trace_contended_event *contended_event, | |||
| 559 | ls->nr_contended++; | 589 | ls->nr_contended++; |
| 560 | seq->prev_event_time = sample->time; | 590 | seq->prev_event_time = sample->time; |
| 561 | end: | 591 | end: |
| 562 | return; | 592 | return 0; |
| 563 | } | 593 | } |
| 564 | 594 | ||
| 565 | static void | 595 | static int |
| 566 | report_lock_release_event(struct trace_release_event *release_event, | 596 | report_lock_release_event(struct trace_release_event *release_event, |
| 567 | const struct perf_sample *sample) | 597 | const struct perf_sample *sample) |
| 568 | { | 598 | { |
| @@ -571,11 +601,18 @@ report_lock_release_event(struct trace_release_event *release_event, | |||
| 571 | struct lock_seq_stat *seq; | 601 | struct lock_seq_stat *seq; |
| 572 | 602 | ||
| 573 | ls = lock_stat_findnew(release_event->addr, release_event->name); | 603 | ls = lock_stat_findnew(release_event->addr, release_event->name); |
| 604 | if (!ls) | ||
| 605 | return -1; | ||
| 574 | if (ls->discard) | 606 | if (ls->discard) |
| 575 | return; | 607 | return 0; |
| 576 | 608 | ||
| 577 | ts = thread_stat_findnew(sample->tid); | 609 | ts = thread_stat_findnew(sample->tid); |
| 610 | if (!ts) | ||
| 611 | return -1; | ||
| 612 | |||
| 578 | seq = get_seq(ts, release_event->addr); | 613 | seq = get_seq(ts, release_event->addr); |
| 614 | if (!seq) | ||
| 615 | return -1; | ||
| 579 | 616 | ||
| 580 | switch (seq->state) { | 617 | switch (seq->state) { |
| 581 | case SEQ_STATE_UNINITIALIZED: | 618 | case SEQ_STATE_UNINITIALIZED: |
| @@ -609,7 +646,7 @@ free_seq: | |||
| 609 | list_del(&seq->list); | 646 | list_del(&seq->list); |
| 610 | free(seq); | 647 | free(seq); |
| 611 | end: | 648 | end: |
| 612 | return; | 649 | return 0; |
| 613 | } | 650 | } |
| 614 | 651 | ||
| 615 | /* lock oriented handlers */ | 652 | /* lock oriented handlers */ |
| @@ -623,13 +660,14 @@ static struct trace_lock_handler report_lock_ops = { | |||
| 623 | 660 | ||
| 624 | static struct trace_lock_handler *trace_handler; | 661 | static struct trace_lock_handler *trace_handler; |
| 625 | 662 | ||
| 626 | static void perf_evsel__process_lock_acquire(struct perf_evsel *evsel, | 663 | static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel, |
| 627 | struct perf_sample *sample) | 664 | struct perf_sample *sample) |
| 628 | { | 665 | { |
| 629 | struct trace_acquire_event acquire_event; | 666 | struct trace_acquire_event acquire_event; |
| 630 | struct event_format *event = evsel->tp_format; | 667 | struct event_format *event = evsel->tp_format; |
| 631 | void *data = sample->raw_data; | 668 | void *data = sample->raw_data; |
| 632 | u64 tmp; /* this is required for casting... */ | 669 | u64 tmp; /* this is required for casting... */ |
| 670 | int rc = 0; | ||
| 633 | 671 | ||
| 634 | tmp = raw_field_value(event, "lockdep_addr", data); | 672 | tmp = raw_field_value(event, "lockdep_addr", data); |
| 635 | memcpy(&acquire_event.addr, &tmp, sizeof(void *)); | 673 | memcpy(&acquire_event.addr, &tmp, sizeof(void *)); |
| @@ -637,70 +675,84 @@ static void perf_evsel__process_lock_acquire(struct perf_evsel *evsel, | |||
| 637 | acquire_event.flag = (int)raw_field_value(event, "flag", data); | 675 | acquire_event.flag = (int)raw_field_value(event, "flag", data); |
| 638 | 676 | ||
| 639 | if (trace_handler->acquire_event) | 677 | if (trace_handler->acquire_event) |
| 640 | trace_handler->acquire_event(&acquire_event, sample); | 678 | rc = trace_handler->acquire_event(&acquire_event, sample); |
| 679 | |||
| 680 | return rc; | ||
| 641 | } | 681 | } |
| 642 | 682 | ||
| 643 | static void perf_evsel__process_lock_acquired(struct perf_evsel *evsel, | 683 | static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel, |
| 644 | struct perf_sample *sample) | 684 | struct perf_sample *sample) |
| 645 | { | 685 | { |
| 646 | struct trace_acquired_event acquired_event; | 686 | struct trace_acquired_event acquired_event; |
| 647 | struct event_format *event = evsel->tp_format; | 687 | struct event_format *event = evsel->tp_format; |
| 648 | void *data = sample->raw_data; | 688 | void *data = sample->raw_data; |
| 649 | u64 tmp; /* this is required for casting... */ | 689 | u64 tmp; /* this is required for casting... */ |
| 690 | int rc = 0; | ||
| 650 | 691 | ||
| 651 | tmp = raw_field_value(event, "lockdep_addr", data); | 692 | tmp = raw_field_value(event, "lockdep_addr", data); |
| 652 | memcpy(&acquired_event.addr, &tmp, sizeof(void *)); | 693 | memcpy(&acquired_event.addr, &tmp, sizeof(void *)); |
| 653 | acquired_event.name = (char *)raw_field_ptr(event, "name", data); | 694 | acquired_event.name = (char *)raw_field_ptr(event, "name", data); |
| 654 | 695 | ||
| 655 | if (trace_handler->acquire_event) | 696 | if (trace_handler->acquired_event) |
| 656 | trace_handler->acquired_event(&acquired_event, sample); | 697 | rc = trace_handler->acquired_event(&acquired_event, sample); |
| 698 | |||
| 699 | return rc; | ||
| 657 | } | 700 | } |
| 658 | 701 | ||
| 659 | static void perf_evsel__process_lock_contended(struct perf_evsel *evsel, | 702 | static int perf_evsel__process_lock_contended(struct perf_evsel *evsel, |
| 660 | struct perf_sample *sample) | 703 | struct perf_sample *sample) |
| 661 | { | 704 | { |
| 662 | struct trace_contended_event contended_event; | 705 | struct trace_contended_event contended_event; |
| 663 | struct event_format *event = evsel->tp_format; | 706 | struct event_format *event = evsel->tp_format; |
| 664 | void *data = sample->raw_data; | 707 | void *data = sample->raw_data; |
| 665 | u64 tmp; /* this is required for casting... */ | 708 | u64 tmp; /* this is required for casting... */ |
| 709 | int rc = 0; | ||
| 666 | 710 | ||
| 667 | tmp = raw_field_value(event, "lockdep_addr", data); | 711 | tmp = raw_field_value(event, "lockdep_addr", data); |
| 668 | memcpy(&contended_event.addr, &tmp, sizeof(void *)); | 712 | memcpy(&contended_event.addr, &tmp, sizeof(void *)); |
| 669 | contended_event.name = (char *)raw_field_ptr(event, "name", data); | 713 | contended_event.name = (char *)raw_field_ptr(event, "name", data); |
| 670 | 714 | ||
| 671 | if (trace_handler->acquire_event) | 715 | if (trace_handler->contended_event) |
| 672 | trace_handler->contended_event(&contended_event, sample); | 716 | rc = trace_handler->contended_event(&contended_event, sample); |
| 717 | |||
| 718 | return rc; | ||
| 673 | } | 719 | } |
| 674 | 720 | ||
| 675 | static void perf_evsel__process_lock_release(struct perf_evsel *evsel, | 721 | static int perf_evsel__process_lock_release(struct perf_evsel *evsel, |
| 676 | struct perf_sample *sample) | 722 | struct perf_sample *sample) |
| 677 | { | 723 | { |
| 678 | struct trace_release_event release_event; | 724 | struct trace_release_event release_event; |
| 679 | struct event_format *event = evsel->tp_format; | 725 | struct event_format *event = evsel->tp_format; |
| 680 | void *data = sample->raw_data; | 726 | void *data = sample->raw_data; |
| 681 | u64 tmp; /* this is required for casting... */ | 727 | u64 tmp; /* this is required for casting... */ |
| 728 | int rc = 0; | ||
| 682 | 729 | ||
| 683 | tmp = raw_field_value(event, "lockdep_addr", data); | 730 | tmp = raw_field_value(event, "lockdep_addr", data); |
| 684 | memcpy(&release_event.addr, &tmp, sizeof(void *)); | 731 | memcpy(&release_event.addr, &tmp, sizeof(void *)); |
| 685 | release_event.name = (char *)raw_field_ptr(event, "name", data); | 732 | release_event.name = (char *)raw_field_ptr(event, "name", data); |
| 686 | 733 | ||
| 687 | if (trace_handler->acquire_event) | 734 | if (trace_handler->release_event) |
| 688 | trace_handler->release_event(&release_event, sample); | 735 | rc = trace_handler->release_event(&release_event, sample); |
| 736 | |||
| 737 | return rc; | ||
| 689 | } | 738 | } |
| 690 | 739 | ||
| 691 | static void perf_evsel__process_lock_event(struct perf_evsel *evsel, | 740 | static int perf_evsel__process_lock_event(struct perf_evsel *evsel, |
| 692 | struct perf_sample *sample) | 741 | struct perf_sample *sample) |
| 693 | { | 742 | { |
| 694 | struct event_format *event = evsel->tp_format; | 743 | struct event_format *event = evsel->tp_format; |
| 744 | int rc = 0; | ||
| 695 | 745 | ||
| 696 | if (!strcmp(event->name, "lock_acquire")) | 746 | if (!strcmp(event->name, "lock_acquire")) |
| 697 | perf_evsel__process_lock_acquire(evsel, sample); | 747 | rc = perf_evsel__process_lock_acquire(evsel, sample); |
| 698 | if (!strcmp(event->name, "lock_acquired")) | 748 | if (!strcmp(event->name, "lock_acquired")) |
| 699 | perf_evsel__process_lock_acquired(evsel, sample); | 749 | rc = perf_evsel__process_lock_acquired(evsel, sample); |
| 700 | if (!strcmp(event->name, "lock_contended")) | 750 | if (!strcmp(event->name, "lock_contended")) |
| 701 | perf_evsel__process_lock_contended(evsel, sample); | 751 | rc = perf_evsel__process_lock_contended(evsel, sample); |
| 702 | if (!strcmp(event->name, "lock_release")) | 752 | if (!strcmp(event->name, "lock_release")) |
| 703 | perf_evsel__process_lock_release(evsel, sample); | 753 | rc = perf_evsel__process_lock_release(evsel, sample); |
| 754 | |||
| 755 | return rc; | ||
| 704 | } | 756 | } |
| 705 | 757 | ||
| 706 | static void print_bad_events(int bad, int total) | 758 | static void print_bad_events(int bad, int total) |
| @@ -802,14 +854,20 @@ static void dump_map(void) | |||
| 802 | } | 854 | } |
| 803 | } | 855 | } |
| 804 | 856 | ||
| 805 | static void dump_info(void) | 857 | static int dump_info(void) |
| 806 | { | 858 | { |
| 859 | int rc = 0; | ||
| 860 | |||
| 807 | if (info_threads) | 861 | if (info_threads) |
| 808 | dump_threads(); | 862 | dump_threads(); |
| 809 | else if (info_map) | 863 | else if (info_map) |
| 810 | dump_map(); | 864 | dump_map(); |
| 811 | else | 865 | else { |
| 812 | die("Unknown type of information\n"); | 866 | rc = -1; |
| 867 | pr_err("Unknown type of information\n"); | ||
| 868 | } | ||
| 869 | |||
| 870 | return rc; | ||
| 813 | } | 871 | } |
| 814 | 872 | ||
| 815 | static int process_sample_event(struct perf_tool *tool __used, | 873 | static int process_sample_event(struct perf_tool *tool __used, |
| @@ -826,8 +884,7 @@ static int process_sample_event(struct perf_tool *tool __used, | |||
| 826 | return -1; | 884 | return -1; |
| 827 | } | 885 | } |
| 828 | 886 | ||
| 829 | perf_evsel__process_lock_event(evsel, sample); | 887 | return perf_evsel__process_lock_event(evsel, sample); |
| 830 | return 0; | ||
| 831 | } | 888 | } |
| 832 | 889 | ||
| 833 | static struct perf_tool eops = { | 890 | static struct perf_tool eops = { |
| @@ -839,8 +896,10 @@ static struct perf_tool eops = { | |||
| 839 | static int read_events(void) | 896 | static int read_events(void) |
| 840 | { | 897 | { |
| 841 | session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); | 898 | session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); |
| 842 | if (!session) | 899 | if (!session) { |
| 843 | die("Initializing perf session failed\n"); | 900 | pr_err("Initializing perf session failed\n"); |
| 901 | return -1; | ||
| 902 | } | ||
| 844 | 903 | ||
| 845 | return perf_session__process_events(session, &eops); | 904 | return perf_session__process_events(session, &eops); |
| 846 | } | 905 | } |
| @@ -857,13 +916,18 @@ static void sort_result(void) | |||
| 857 | } | 916 | } |
| 858 | } | 917 | } |
| 859 | 918 | ||
| 860 | static void __cmd_report(void) | 919 | static int __cmd_report(void) |
| 861 | { | 920 | { |
| 862 | setup_pager(); | 921 | setup_pager(); |
| 863 | select_key(); | 922 | |
| 864 | read_events(); | 923 | if ((select_key() != 0) || |
| 924 | (read_events() != 0)) | ||
| 925 | return -1; | ||
| 926 | |||
| 865 | sort_result(); | 927 | sort_result(); |
| 866 | print_result(); | 928 | print_result(); |
| 929 | |||
| 930 | return 0; | ||
| 867 | } | 931 | } |
| 868 | 932 | ||
| 869 | static const char * const report_usage[] = { | 933 | static const char * const report_usage[] = { |
| @@ -959,6 +1023,7 @@ static int __cmd_record(int argc, const char **argv) | |||
| 959 | int cmd_lock(int argc, const char **argv, const char *prefix __used) | 1023 | int cmd_lock(int argc, const char **argv, const char *prefix __used) |
| 960 | { | 1024 | { |
| 961 | unsigned int i; | 1025 | unsigned int i; |
| 1026 | int rc = 0; | ||
| 962 | 1027 | ||
| 963 | symbol__init(); | 1028 | symbol__init(); |
| 964 | for (i = 0; i < LOCKHASH_SIZE; i++) | 1029 | for (i = 0; i < LOCKHASH_SIZE; i++) |
| @@ -993,11 +1058,13 @@ int cmd_lock(int argc, const char **argv, const char *prefix __used) | |||
| 993 | /* recycling report_lock_ops */ | 1058 | /* recycling report_lock_ops */ |
| 994 | trace_handler = &report_lock_ops; | 1059 | trace_handler = &report_lock_ops; |
| 995 | setup_pager(); | 1060 | setup_pager(); |
| 996 | read_events(); | 1061 | if (read_events() != 0) |
| 997 | dump_info(); | 1062 | rc = -1; |
| 1063 | else | ||
| 1064 | rc = dump_info(); | ||
| 998 | } else { | 1065 | } else { |
| 999 | usage_with_options(lock_usage, lock_options); | 1066 | usage_with_options(lock_usage, lock_options); |
| 1000 | } | 1067 | } |
| 1001 | 1068 | ||
| 1002 | return 0; | 1069 | return rc; |
| 1003 | } | 1070 | } |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 479ff2a038fc..7b8b891d4d56 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
| @@ -71,19 +71,23 @@ static void advance_output(struct perf_record *rec, size_t size) | |||
| 71 | rec->bytes_written += size; | 71 | rec->bytes_written += size; |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static void write_output(struct perf_record *rec, void *buf, size_t size) | 74 | static int write_output(struct perf_record *rec, void *buf, size_t size) |
| 75 | { | 75 | { |
| 76 | while (size) { | 76 | while (size) { |
| 77 | int ret = write(rec->output, buf, size); | 77 | int ret = write(rec->output, buf, size); |
| 78 | 78 | ||
| 79 | if (ret < 0) | 79 | if (ret < 0) { |
| 80 | die("failed to write"); | 80 | pr_err("failed to write\n"); |
| 81 | return -1; | ||
| 82 | } | ||
| 81 | 83 | ||
| 82 | size -= ret; | 84 | size -= ret; |
| 83 | buf += ret; | 85 | buf += ret; |
| 84 | 86 | ||
| 85 | rec->bytes_written += ret; | 87 | rec->bytes_written += ret; |
| 86 | } | 88 | } |
| 89 | |||
| 90 | return 0; | ||
| 87 | } | 91 | } |
| 88 | 92 | ||
| 89 | static int process_synthesized_event(struct perf_tool *tool, | 93 | static int process_synthesized_event(struct perf_tool *tool, |
| @@ -92,11 +96,13 @@ static int process_synthesized_event(struct perf_tool *tool, | |||
| 92 | struct machine *machine __used) | 96 | struct machine *machine __used) |
| 93 | { | 97 | { |
| 94 | struct perf_record *rec = container_of(tool, struct perf_record, tool); | 98 | struct perf_record *rec = container_of(tool, struct perf_record, tool); |
| 95 | write_output(rec, event, event->header.size); | 99 | if (write_output(rec, event, event->header.size) < 0) |
| 100 | return -1; | ||
| 101 | |||
| 96 | return 0; | 102 | return 0; |
| 97 | } | 103 | } |
| 98 | 104 | ||
| 99 | static void perf_record__mmap_read(struct perf_record *rec, | 105 | static int perf_record__mmap_read(struct perf_record *rec, |
| 100 | struct perf_mmap *md) | 106 | struct perf_mmap *md) |
| 101 | { | 107 | { |
| 102 | unsigned int head = perf_mmap__read_head(md); | 108 | unsigned int head = perf_mmap__read_head(md); |
| @@ -104,9 +110,10 @@ static void perf_record__mmap_read(struct perf_record *rec, | |||
| 104 | unsigned char *data = md->base + rec->page_size; | 110 | unsigned char *data = md->base + rec->page_size; |
| 105 | unsigned long size; | 111 | unsigned long size; |
| 106 | void *buf; | 112 | void *buf; |
| 113 | int rc = 0; | ||
| 107 | 114 | ||
| 108 | if (old == head) | 115 | if (old == head) |
| 109 | return; | 116 | return 0; |
| 110 | 117 | ||
| 111 | rec->samples++; | 118 | rec->samples++; |
| 112 | 119 | ||
| @@ -117,17 +124,26 @@ static void perf_record__mmap_read(struct perf_record *rec, | |||
| 117 | size = md->mask + 1 - (old & md->mask); | 124 | size = md->mask + 1 - (old & md->mask); |
| 118 | old += size; | 125 | old += size; |
| 119 | 126 | ||
| 120 | write_output(rec, buf, size); | 127 | if (write_output(rec, buf, size) < 0) { |
| 128 | rc = -1; | ||
| 129 | goto out; | ||
| 130 | } | ||
| 121 | } | 131 | } |
| 122 | 132 | ||
| 123 | buf = &data[old & md->mask]; | 133 | buf = &data[old & md->mask]; |
| 124 | size = head - old; | 134 | size = head - old; |
| 125 | old += size; | 135 | old += size; |
| 126 | 136 | ||
| 127 | write_output(rec, buf, size); | 137 | if (write_output(rec, buf, size) < 0) { |
| 138 | rc = -1; | ||
| 139 | goto out; | ||
| 140 | } | ||
| 128 | 141 | ||
| 129 | md->prev = old; | 142 | md->prev = old; |
| 130 | perf_mmap__write_tail(md, old); | 143 | perf_mmap__write_tail(md, old); |
| 144 | |||
| 145 | out: | ||
| 146 | return rc; | ||
| 131 | } | 147 | } |
| 132 | 148 | ||
| 133 | static volatile int done = 0; | 149 | static volatile int done = 0; |
| @@ -183,12 +199,13 @@ static bool perf_evlist__equal(struct perf_evlist *evlist, | |||
| 183 | return true; | 199 | return true; |
| 184 | } | 200 | } |
| 185 | 201 | ||
| 186 | static void perf_record__open(struct perf_record *rec) | 202 | static int perf_record__open(struct perf_record *rec) |
| 187 | { | 203 | { |
| 188 | struct perf_evsel *pos; | 204 | struct perf_evsel *pos; |
| 189 | struct perf_evlist *evlist = rec->evlist; | 205 | struct perf_evlist *evlist = rec->evlist; |
| 190 | struct perf_session *session = rec->session; | 206 | struct perf_session *session = rec->session; |
| 191 | struct perf_record_opts *opts = &rec->opts; | 207 | struct perf_record_opts *opts = &rec->opts; |
| 208 | int rc = 0; | ||
| 192 | 209 | ||
| 193 | perf_evlist__config_attrs(evlist, opts); | 210 | perf_evlist__config_attrs(evlist, opts); |
| 194 | 211 | ||
| @@ -222,10 +239,13 @@ try_again: | |||
| 222 | 239 | ||
| 223 | if (err == EPERM || err == EACCES) { | 240 | if (err == EPERM || err == EACCES) { |
| 224 | ui__error_paranoid(); | 241 | ui__error_paranoid(); |
| 225 | exit(EXIT_FAILURE); | 242 | rc = -err; |
| 243 | goto out; | ||
| 226 | } else if (err == ENODEV && opts->target.cpu_list) { | 244 | } else if (err == ENODEV && opts->target.cpu_list) { |
| 227 | die("No such device - did you specify" | 245 | pr_err("No such device - did you specify" |
| 228 | " an out-of-range profile CPU?\n"); | 246 | " an out-of-range profile CPU?\n"); |
| 247 | rc = -err; | ||
| 248 | goto out; | ||
| 229 | } else if (err == EINVAL) { | 249 | } else if (err == EINVAL) { |
| 230 | if (!opts->exclude_guest_missing && | 250 | if (!opts->exclude_guest_missing && |
| 231 | (attr->exclude_guest || attr->exclude_host)) { | 251 | (attr->exclude_guest || attr->exclude_host)) { |
| @@ -272,7 +292,8 @@ try_again: | |||
| 272 | if (err == ENOENT) { | 292 | if (err == ENOENT) { |
| 273 | ui__error("The %s event is not supported.\n", | 293 | ui__error("The %s event is not supported.\n", |
| 274 | perf_evsel__name(pos)); | 294 | perf_evsel__name(pos)); |
| 275 | exit(EXIT_FAILURE); | 295 | rc = -err; |
| 296 | goto out; | ||
| 276 | } | 297 | } |
| 277 | 298 | ||
| 278 | printf("\n"); | 299 | printf("\n"); |
| @@ -280,34 +301,46 @@ try_again: | |||
| 280 | err, strerror(err)); | 301 | err, strerror(err)); |
| 281 | 302 | ||
| 282 | #if defined(__i386__) || defined(__x86_64__) | 303 | #if defined(__i386__) || defined(__x86_64__) |
| 283 | if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP) | 304 | if (attr->type == PERF_TYPE_HARDWARE && |
| 284 | die("No hardware sampling interrupt available." | 305 | err == EOPNOTSUPP) { |
| 285 | " No APIC? If so then you can boot the kernel" | 306 | pr_err("No hardware sampling interrupt available." |
| 286 | " with the \"lapic\" boot parameter to" | 307 | " No APIC? If so then you can boot the kernel" |
| 287 | " force-enable it.\n"); | 308 | " with the \"lapic\" boot parameter to" |
| 309 | " force-enable it.\n"); | ||
| 310 | rc = -err; | ||
| 311 | goto out; | ||
| 312 | } | ||
| 288 | #endif | 313 | #endif |
| 289 | 314 | ||
| 290 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | 315 | pr_err("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); |
| 316 | rc = -err; | ||
| 317 | goto out; | ||
| 291 | } | 318 | } |
| 292 | } | 319 | } |
| 293 | 320 | ||
| 294 | if (perf_evlist__set_filters(evlist)) { | 321 | if (perf_evlist__set_filters(evlist)) { |
| 295 | error("failed to set filter with %d (%s)\n", errno, | 322 | error("failed to set filter with %d (%s)\n", errno, |
| 296 | strerror(errno)); | 323 | strerror(errno)); |
| 297 | exit(-1); | 324 | rc = -1; |
| 325 | goto out; | ||
| 298 | } | 326 | } |
| 299 | 327 | ||
| 300 | if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { | 328 | if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { |
| 301 | if (errno == EPERM) | 329 | if (errno == EPERM) { |
| 302 | die("Permission error mapping pages.\n" | 330 | pr_err("Permission error mapping pages.\n" |
| 303 | "Consider increasing " | 331 | "Consider increasing " |
| 304 | "/proc/sys/kernel/perf_event_mlock_kb,\n" | 332 | "/proc/sys/kernel/perf_event_mlock_kb,\n" |
| 305 | "or try again with a smaller value of -m/--mmap_pages.\n" | 333 | "or try again with a smaller value of -m/--mmap_pages.\n" |
| 306 | "(current value: %d)\n", opts->mmap_pages); | 334 | "(current value: %d)\n", opts->mmap_pages); |
| 307 | else if (!is_power_of_2(opts->mmap_pages)) | 335 | rc = -errno; |
| 308 | die("--mmap_pages/-m value must be a power of two."); | 336 | } else if (!is_power_of_2(opts->mmap_pages)) { |
| 309 | 337 | pr_err("--mmap_pages/-m value must be a power of two."); | |
| 310 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); | 338 | rc = -EINVAL; |
| 339 | } else { | ||
| 340 | pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno)); | ||
| 341 | rc = -errno; | ||
| 342 | } | ||
| 343 | goto out; | ||
| 311 | } | 344 | } |
| 312 | 345 | ||
| 313 | if (rec->file_new) | 346 | if (rec->file_new) |
| @@ -315,11 +348,14 @@ try_again: | |||
| 315 | else { | 348 | else { |
| 316 | if (!perf_evlist__equal(session->evlist, evlist)) { | 349 | if (!perf_evlist__equal(session->evlist, evlist)) { |
| 317 | fprintf(stderr, "incompatible append\n"); | 350 | fprintf(stderr, "incompatible append\n"); |
| 318 | exit(-1); | 351 | rc = -1; |
| 352 | goto out; | ||
| 319 | } | 353 | } |
| 320 | } | 354 | } |
| 321 | 355 | ||
| 322 | perf_session__set_id_hdr_size(session); | 356 | perf_session__set_id_hdr_size(session); |
| 357 | out: | ||
| 358 | return rc; | ||
| 323 | } | 359 | } |
| 324 | 360 | ||
| 325 | static int process_buildids(struct perf_record *rec) | 361 | static int process_buildids(struct perf_record *rec) |
| @@ -335,10 +371,13 @@ static int process_buildids(struct perf_record *rec) | |||
| 335 | size, &build_id__mark_dso_hit_ops); | 371 | size, &build_id__mark_dso_hit_ops); |
| 336 | } | 372 | } |
| 337 | 373 | ||
| 338 | static void perf_record__exit(int status __used, void *arg) | 374 | static void perf_record__exit(int status, void *arg) |
| 339 | { | 375 | { |
| 340 | struct perf_record *rec = arg; | 376 | struct perf_record *rec = arg; |
| 341 | 377 | ||
| 378 | if (status != 0) | ||
| 379 | return; | ||
| 380 | |||
| 342 | if (!rec->opts.pipe_output) { | 381 | if (!rec->opts.pipe_output) { |
| 343 | rec->session->header.data_size += rec->bytes_written; | 382 | rec->session->header.data_size += rec->bytes_written; |
| 344 | 383 | ||
| @@ -393,17 +432,26 @@ static struct perf_event_header finished_round_event = { | |||
| 393 | .type = PERF_RECORD_FINISHED_ROUND, | 432 | .type = PERF_RECORD_FINISHED_ROUND, |
| 394 | }; | 433 | }; |
| 395 | 434 | ||
| 396 | static void perf_record__mmap_read_all(struct perf_record *rec) | 435 | static int perf_record__mmap_read_all(struct perf_record *rec) |
| 397 | { | 436 | { |
| 398 | int i; | 437 | int i; |
| 438 | int rc = 0; | ||
| 399 | 439 | ||
| 400 | for (i = 0; i < rec->evlist->nr_mmaps; i++) { | 440 | for (i = 0; i < rec->evlist->nr_mmaps; i++) { |
| 401 | if (rec->evlist->mmap[i].base) | 441 | if (rec->evlist->mmap[i].base) { |
| 402 | perf_record__mmap_read(rec, &rec->evlist->mmap[i]); | 442 | if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { |
| 443 | rc = -1; | ||
| 444 | goto out; | ||
| 445 | } | ||
| 446 | } | ||
| 403 | } | 447 | } |
| 404 | 448 | ||
| 405 | if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) | 449 | if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) |
| 406 | write_output(rec, &finished_round_event, sizeof(finished_round_event)); | 450 | rc = write_output(rec, &finished_round_event, |
| 451 | sizeof(finished_round_event)); | ||
| 452 | |||
| 453 | out: | ||
| 454 | return rc; | ||
| 407 | } | 455 | } |
| 408 | 456 | ||
| 409 | static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | 457 | static int __cmd_record(struct perf_record *rec, int argc, const char **argv) |
| @@ -463,7 +511,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 463 | output = open(output_name, flags, S_IRUSR | S_IWUSR); | 511 | output = open(output_name, flags, S_IRUSR | S_IWUSR); |
| 464 | if (output < 0) { | 512 | if (output < 0) { |
| 465 | perror("failed to create output file"); | 513 | perror("failed to create output file"); |
| 466 | exit(-1); | 514 | return -1; |
| 467 | } | 515 | } |
| 468 | 516 | ||
| 469 | rec->output = output; | 517 | rec->output = output; |
| @@ -503,7 +551,10 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 503 | } | 551 | } |
| 504 | } | 552 | } |
| 505 | 553 | ||
| 506 | perf_record__open(rec); | 554 | if (perf_record__open(rec) != 0) { |
| 555 | err = -1; | ||
| 556 | goto out_delete_session; | ||
| 557 | } | ||
| 507 | 558 | ||
| 508 | /* | 559 | /* |
| 509 | * perf_session__delete(session) will be called at perf_record__exit() | 560 | * perf_session__delete(session) will be called at perf_record__exit() |
| @@ -513,19 +564,20 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 513 | if (opts->pipe_output) { | 564 | if (opts->pipe_output) { |
| 514 | err = perf_header__write_pipe(output); | 565 | err = perf_header__write_pipe(output); |
| 515 | if (err < 0) | 566 | if (err < 0) |
| 516 | return err; | 567 | goto out_delete_session; |
| 517 | } else if (rec->file_new) { | 568 | } else if (rec->file_new) { |
| 518 | err = perf_session__write_header(session, evsel_list, | 569 | err = perf_session__write_header(session, evsel_list, |
| 519 | output, false); | 570 | output, false); |
| 520 | if (err < 0) | 571 | if (err < 0) |
| 521 | return err; | 572 | goto out_delete_session; |
| 522 | } | 573 | } |
| 523 | 574 | ||
| 524 | if (!rec->no_buildid | 575 | if (!rec->no_buildid |
| 525 | && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { | 576 | && !perf_header__has_feat(&session->header, HEADER_BUILD_ID)) { |
| 526 | pr_err("Couldn't generate buildids. " | 577 | pr_err("Couldn't generate buildids. " |
| 527 | "Use --no-buildid to profile anyway.\n"); | 578 | "Use --no-buildid to profile anyway.\n"); |
| 528 | return -1; | 579 | err = -1; |
| 580 | goto out_delete_session; | ||
| 529 | } | 581 | } |
| 530 | 582 | ||
| 531 | rec->post_processing_offset = lseek(output, 0, SEEK_CUR); | 583 | rec->post_processing_offset = lseek(output, 0, SEEK_CUR); |
| @@ -533,7 +585,8 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 533 | machine = perf_session__find_host_machine(session); | 585 | machine = perf_session__find_host_machine(session); |
| 534 | if (!machine) { | 586 | if (!machine) { |
| 535 | pr_err("Couldn't find native kernel information.\n"); | 587 | pr_err("Couldn't find native kernel information.\n"); |
| 536 | return -1; | 588 | err = -1; |
| 589 | goto out_delete_session; | ||
| 537 | } | 590 | } |
| 538 | 591 | ||
| 539 | if (opts->pipe_output) { | 592 | if (opts->pipe_output) { |
| @@ -541,14 +594,14 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 541 | process_synthesized_event); | 594 | process_synthesized_event); |
| 542 | if (err < 0) { | 595 | if (err < 0) { |
| 543 | pr_err("Couldn't synthesize attrs.\n"); | 596 | pr_err("Couldn't synthesize attrs.\n"); |
| 544 | return err; | 597 | goto out_delete_session; |
| 545 | } | 598 | } |
| 546 | 599 | ||
| 547 | err = perf_event__synthesize_event_types(tool, process_synthesized_event, | 600 | err = perf_event__synthesize_event_types(tool, process_synthesized_event, |
| 548 | machine); | 601 | machine); |
| 549 | if (err < 0) { | 602 | if (err < 0) { |
| 550 | pr_err("Couldn't synthesize event_types.\n"); | 603 | pr_err("Couldn't synthesize event_types.\n"); |
| 551 | return err; | 604 | goto out_delete_session; |
| 552 | } | 605 | } |
| 553 | 606 | ||
| 554 | if (have_tracepoints(&evsel_list->entries)) { | 607 | if (have_tracepoints(&evsel_list->entries)) { |
| @@ -564,7 +617,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 564 | process_synthesized_event); | 617 | process_synthesized_event); |
| 565 | if (err <= 0) { | 618 | if (err <= 0) { |
| 566 | pr_err("Couldn't record tracing data.\n"); | 619 | pr_err("Couldn't record tracing data.\n"); |
| 567 | return err; | 620 | goto out_delete_session; |
| 568 | } | 621 | } |
| 569 | advance_output(rec, err); | 622 | advance_output(rec, err); |
| 570 | } | 623 | } |
| @@ -592,20 +645,24 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 592 | perf_event__synthesize_guest_os); | 645 | perf_event__synthesize_guest_os); |
| 593 | 646 | ||
| 594 | if (!opts->target.system_wide) | 647 | if (!opts->target.system_wide) |
| 595 | perf_event__synthesize_thread_map(tool, evsel_list->threads, | 648 | err = perf_event__synthesize_thread_map(tool, evsel_list->threads, |
| 596 | process_synthesized_event, | 649 | process_synthesized_event, |
| 597 | machine); | 650 | machine); |
| 598 | else | 651 | else |
| 599 | perf_event__synthesize_threads(tool, process_synthesized_event, | 652 | err = perf_event__synthesize_threads(tool, process_synthesized_event, |
| 600 | machine); | 653 | machine); |
| 601 | 654 | ||
| 655 | if (err != 0) | ||
| 656 | goto out_delete_session; | ||
| 657 | |||
| 602 | if (rec->realtime_prio) { | 658 | if (rec->realtime_prio) { |
| 603 | struct sched_param param; | 659 | struct sched_param param; |
| 604 | 660 | ||
| 605 | param.sched_priority = rec->realtime_prio; | 661 | param.sched_priority = rec->realtime_prio; |
| 606 | if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { | 662 | if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { |
| 607 | pr_err("Could not set realtime priority.\n"); | 663 | pr_err("Could not set realtime priority.\n"); |
| 608 | exit(-1); | 664 | err = -1; |
| 665 | goto out_delete_session; | ||
| 609 | } | 666 | } |
| 610 | } | 667 | } |
| 611 | 668 | ||
| @@ -620,7 +677,10 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) | |||
| 620 | for (;;) { | 677 | for (;;) { |
| 621 | int hits = rec->samples; | 678 | int hits = rec->samples; |
| 622 | 679 | ||
| 623 | perf_record__mmap_read_all(rec); | 680 | if (perf_record__mmap_read_all(rec) < 0) { |
| 681 | err = -1; | ||
| 682 | goto out_delete_session; | ||
| 683 | } | ||
| 624 | 684 | ||
| 625 | if (hits == rec->samples) { | 685 | if (hits == rec->samples) { |
| 626 | if (done) | 686 | if (done) |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d61825371adc..1f8d11b4f7ff 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -638,6 +638,8 @@ int cmd_report(int argc, const char **argv, const char *prefix __used) | |||
| 638 | "Show a column with the sum of periods"), | 638 | "Show a column with the sum of periods"), |
| 639 | OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "", | 639 | OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "", |
| 640 | "use branch records for histogram filling", parse_branch_mode), | 640 | "use branch records for histogram filling", parse_branch_mode), |
| 641 | OPT_STRING(0, "objdump", &objdump_path, "path", | ||
| 642 | "objdump binary to use for disassembly and annotations"), | ||
| 641 | OPT_END() | 643 | OPT_END() |
| 642 | }; | 644 | }; |
| 643 | 645 | ||
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 2d6e3b226aad..c350cfee3157 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -1153,18 +1153,23 @@ static const struct option options[] = { | |||
| 1153 | OPT_END() | 1153 | OPT_END() |
| 1154 | }; | 1154 | }; |
| 1155 | 1155 | ||
| 1156 | static bool have_cmd(int argc, const char **argv) | 1156 | static int have_cmd(int argc, const char **argv) |
| 1157 | { | 1157 | { |
| 1158 | char **__argv = malloc(sizeof(const char *) * argc); | 1158 | char **__argv = malloc(sizeof(const char *) * argc); |
| 1159 | 1159 | ||
| 1160 | if (!__argv) | 1160 | if (!__argv) { |
| 1161 | die("malloc"); | 1161 | pr_err("malloc failed\n"); |
| 1162 | return -1; | ||
| 1163 | } | ||
| 1164 | |||
| 1162 | memcpy(__argv, argv, sizeof(const char *) * argc); | 1165 | memcpy(__argv, argv, sizeof(const char *) * argc); |
| 1163 | argc = parse_options(argc, (const char **)__argv, record_options, | 1166 | argc = parse_options(argc, (const char **)__argv, record_options, |
| 1164 | NULL, PARSE_OPT_STOP_AT_NON_OPTION); | 1167 | NULL, PARSE_OPT_STOP_AT_NON_OPTION); |
| 1165 | free(__argv); | 1168 | free(__argv); |
| 1166 | 1169 | ||
| 1167 | return argc != 0; | 1170 | system_wide = (argc == 0); |
| 1171 | |||
| 1172 | return 0; | ||
| 1168 | } | 1173 | } |
| 1169 | 1174 | ||
| 1170 | int cmd_script(int argc, const char **argv, const char *prefix __used) | 1175 | int cmd_script(int argc, const char **argv, const char *prefix __used) |
| @@ -1231,13 +1236,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
| 1231 | 1236 | ||
| 1232 | if (pipe(live_pipe) < 0) { | 1237 | if (pipe(live_pipe) < 0) { |
| 1233 | perror("failed to create pipe"); | 1238 | perror("failed to create pipe"); |
| 1234 | exit(-1); | 1239 | return -1; |
| 1235 | } | 1240 | } |
| 1236 | 1241 | ||
| 1237 | pid = fork(); | 1242 | pid = fork(); |
| 1238 | if (pid < 0) { | 1243 | if (pid < 0) { |
| 1239 | perror("failed to fork"); | 1244 | perror("failed to fork"); |
| 1240 | exit(-1); | 1245 | return -1; |
| 1241 | } | 1246 | } |
| 1242 | 1247 | ||
| 1243 | if (!pid) { | 1248 | if (!pid) { |
| @@ -1249,13 +1254,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
| 1249 | if (is_top_script(argv[0])) { | 1254 | if (is_top_script(argv[0])) { |
| 1250 | system_wide = true; | 1255 | system_wide = true; |
| 1251 | } else if (!system_wide) { | 1256 | } else if (!system_wide) { |
| 1252 | system_wide = !have_cmd(argc - rep_args, | 1257 | if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { |
| 1253 | &argv[rep_args]); | 1258 | err = -1; |
| 1259 | goto out; | ||
| 1260 | } | ||
| 1254 | } | 1261 | } |
| 1255 | 1262 | ||
| 1256 | __argv = malloc((argc + 6) * sizeof(const char *)); | 1263 | __argv = malloc((argc + 6) * sizeof(const char *)); |
| 1257 | if (!__argv) | 1264 | if (!__argv) { |
| 1258 | die("malloc"); | 1265 | pr_err("malloc failed\n"); |
| 1266 | err = -ENOMEM; | ||
| 1267 | goto out; | ||
| 1268 | } | ||
| 1259 | 1269 | ||
| 1260 | __argv[j++] = "/bin/sh"; | 1270 | __argv[j++] = "/bin/sh"; |
| 1261 | __argv[j++] = rec_script_path; | 1271 | __argv[j++] = rec_script_path; |
| @@ -1277,8 +1287,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
| 1277 | close(live_pipe[1]); | 1287 | close(live_pipe[1]); |
| 1278 | 1288 | ||
| 1279 | __argv = malloc((argc + 4) * sizeof(const char *)); | 1289 | __argv = malloc((argc + 4) * sizeof(const char *)); |
| 1280 | if (!__argv) | 1290 | if (!__argv) { |
| 1281 | die("malloc"); | 1291 | pr_err("malloc failed\n"); |
| 1292 | err = -ENOMEM; | ||
| 1293 | goto out; | ||
| 1294 | } | ||
| 1295 | |||
| 1282 | j = 0; | 1296 | j = 0; |
| 1283 | __argv[j++] = "/bin/sh"; | 1297 | __argv[j++] = "/bin/sh"; |
| 1284 | __argv[j++] = rep_script_path; | 1298 | __argv[j++] = rep_script_path; |
| @@ -1303,12 +1317,20 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
| 1303 | 1317 | ||
| 1304 | if (!rec_script_path) | 1318 | if (!rec_script_path) |
| 1305 | system_wide = false; | 1319 | system_wide = false; |
| 1306 | else if (!system_wide) | 1320 | else if (!system_wide) { |
| 1307 | system_wide = !have_cmd(argc - 1, &argv[1]); | 1321 | if (have_cmd(argc - 1, &argv[1]) != 0) { |
| 1322 | err = -1; | ||
| 1323 | goto out; | ||
| 1324 | } | ||
| 1325 | } | ||
| 1308 | 1326 | ||
| 1309 | __argv = malloc((argc + 2) * sizeof(const char *)); | 1327 | __argv = malloc((argc + 2) * sizeof(const char *)); |
| 1310 | if (!__argv) | 1328 | if (!__argv) { |
| 1311 | die("malloc"); | 1329 | pr_err("malloc failed\n"); |
| 1330 | err = -ENOMEM; | ||
| 1331 | goto out; | ||
| 1332 | } | ||
| 1333 | |||
| 1312 | __argv[j++] = "/bin/sh"; | 1334 | __argv[j++] = "/bin/sh"; |
| 1313 | __argv[j++] = script_path; | 1335 | __argv[j++] = script_path; |
| 1314 | if (system_wide) | 1336 | if (system_wide) |
| @@ -1357,18 +1379,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) | |||
| 1357 | input = open(session->filename, O_RDONLY); /* input_name */ | 1379 | input = open(session->filename, O_RDONLY); /* input_name */ |
| 1358 | if (input < 0) { | 1380 | if (input < 0) { |
| 1359 | perror("failed to open file"); | 1381 | perror("failed to open file"); |
| 1360 | exit(-1); | 1382 | return -1; |
| 1361 | } | 1383 | } |
| 1362 | 1384 | ||
| 1363 | err = fstat(input, &perf_stat); | 1385 | err = fstat(input, &perf_stat); |
| 1364 | if (err < 0) { | 1386 | if (err < 0) { |
| 1365 | perror("failed to stat file"); | 1387 | perror("failed to stat file"); |
| 1366 | exit(-1); | 1388 | return -1; |
| 1367 | } | 1389 | } |
| 1368 | 1390 | ||
| 1369 | if (!perf_stat.st_size) { | 1391 | if (!perf_stat.st_size) { |
| 1370 | fprintf(stderr, "zero-sized file, nothing to do!\n"); | 1392 | fprintf(stderr, "zero-sized file, nothing to do!\n"); |
| 1371 | exit(0); | 1393 | return 0; |
| 1372 | } | 1394 | } |
| 1373 | 1395 | ||
| 1374 | scripting_ops = script_spec__lookup(generate_script_lang); | 1396 | scripting_ops = script_spec__lookup(generate_script_lang); |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index d53d8ab099b1..02f49eba677f 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -428,7 +428,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
| 428 | 428 | ||
| 429 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { | 429 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { |
| 430 | perror("failed to create pipes"); | 430 | perror("failed to create pipes"); |
| 431 | exit(1); | 431 | return -1; |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | if (forks) { | 434 | if (forks) { |
| @@ -510,7 +510,8 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
| 510 | } | 510 | } |
| 511 | if (child_pid != -1) | 511 | if (child_pid != -1) |
| 512 | kill(child_pid, SIGTERM); | 512 | kill(child_pid, SIGTERM); |
| 513 | die("Not all events could be opened.\n"); | 513 | |
| 514 | pr_err("Not all events could be opened.\n"); | ||
| 514 | return -1; | 515 | return -1; |
| 515 | } | 516 | } |
| 516 | counter->supported = true; | 517 | counter->supported = true; |
| @@ -1189,7 +1190,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
| 1189 | output = fopen(output_name, mode); | 1190 | output = fopen(output_name, mode); |
| 1190 | if (!output) { | 1191 | if (!output) { |
| 1191 | perror("failed to create output file"); | 1192 | perror("failed to create output file"); |
| 1192 | exit(-1); | 1193 | return -1; |
| 1193 | } | 1194 | } |
| 1194 | clock_gettime(CLOCK_REALTIME, &tm); | 1195 | clock_gettime(CLOCK_REALTIME, &tm); |
| 1195 | fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); | 1196 | fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 381d5ab87124..cf33e5081c36 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
| @@ -1092,6 +1092,116 @@ static int test__perf_pmu(void) | |||
| 1092 | return perf_pmu__test(); | 1092 | return perf_pmu__test(); |
| 1093 | } | 1093 | } |
| 1094 | 1094 | ||
| 1095 | static int perf_evsel__roundtrip_cache_name_test(void) | ||
| 1096 | { | ||
| 1097 | char name[128]; | ||
| 1098 | int type, op, err = 0, ret = 0, i, idx; | ||
| 1099 | struct perf_evsel *evsel; | ||
| 1100 | struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); | ||
| 1101 | |||
| 1102 | if (evlist == NULL) | ||
| 1103 | return -ENOMEM; | ||
| 1104 | |||
| 1105 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { | ||
| 1106 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { | ||
| 1107 | /* skip invalid cache type */ | ||
| 1108 | if (!perf_evsel__is_cache_op_valid(type, op)) | ||
| 1109 | continue; | ||
| 1110 | |||
| 1111 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | ||
| 1112 | __perf_evsel__hw_cache_type_op_res_name(type, op, i, | ||
| 1113 | name, sizeof(name)); | ||
| 1114 | err = parse_events(evlist, name, 0); | ||
| 1115 | if (err) | ||
| 1116 | ret = err; | ||
| 1117 | } | ||
| 1118 | } | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | idx = 0; | ||
| 1122 | evsel = perf_evlist__first(evlist); | ||
| 1123 | |||
| 1124 | for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { | ||
| 1125 | for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { | ||
| 1126 | /* skip invalid cache type */ | ||
| 1127 | if (!perf_evsel__is_cache_op_valid(type, op)) | ||
| 1128 | continue; | ||
| 1129 | |||
| 1130 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | ||
| 1131 | __perf_evsel__hw_cache_type_op_res_name(type, op, i, | ||
| 1132 | name, sizeof(name)); | ||
| 1133 | if (evsel->idx != idx) | ||
| 1134 | continue; | ||
| 1135 | |||
| 1136 | ++idx; | ||
| 1137 | |||
| 1138 | if (strcmp(perf_evsel__name(evsel), name)) { | ||
| 1139 | pr_debug("%s != %s\n", perf_evsel__name(evsel), name); | ||
| 1140 | ret = -1; | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | evsel = perf_evsel__next(evsel); | ||
| 1144 | } | ||
| 1145 | } | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | perf_evlist__delete(evlist); | ||
| 1149 | return ret; | ||
| 1150 | } | ||
| 1151 | |||
| 1152 | static int __perf_evsel__name_array_test(const char *names[], int nr_names) | ||
| 1153 | { | ||
| 1154 | int i, err; | ||
| 1155 | struct perf_evsel *evsel; | ||
| 1156 | struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); | ||
| 1157 | |||
| 1158 | if (evlist == NULL) | ||
| 1159 | return -ENOMEM; | ||
| 1160 | |||
| 1161 | for (i = 0; i < nr_names; ++i) { | ||
| 1162 | err = parse_events(evlist, names[i], 0); | ||
| 1163 | if (err) { | ||
| 1164 | pr_debug("failed to parse event '%s', err %d\n", | ||
| 1165 | names[i], err); | ||
| 1166 | goto out_delete_evlist; | ||
| 1167 | } | ||
| 1168 | } | ||
| 1169 | |||
| 1170 | err = 0; | ||
| 1171 | list_for_each_entry(evsel, &evlist->entries, node) { | ||
| 1172 | if (strcmp(perf_evsel__name(evsel), names[evsel->idx])) { | ||
| 1173 | --err; | ||
| 1174 | pr_debug("%s != %s\n", perf_evsel__name(evsel), names[evsel->idx]); | ||
| 1175 | } | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | out_delete_evlist: | ||
| 1179 | perf_evlist__delete(evlist); | ||
| 1180 | return err; | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | #define perf_evsel__name_array_test(names) \ | ||
| 1184 | __perf_evsel__name_array_test(names, ARRAY_SIZE(names)) | ||
| 1185 | |||
| 1186 | static int perf_evsel__roundtrip_name_test(void) | ||
| 1187 | { | ||
| 1188 | int err = 0, ret = 0; | ||
| 1189 | |||
| 1190 | err = perf_evsel__name_array_test(perf_evsel__hw_names); | ||
| 1191 | if (err) | ||
| 1192 | ret = err; | ||
| 1193 | |||
| 1194 | err = perf_evsel__name_array_test(perf_evsel__sw_names); | ||
| 1195 | if (err) | ||
| 1196 | ret = err; | ||
| 1197 | |||
| 1198 | err = perf_evsel__roundtrip_cache_name_test(); | ||
| 1199 | if (err) | ||
| 1200 | ret = err; | ||
| 1201 | |||
| 1202 | return ret; | ||
| 1203 | } | ||
| 1204 | |||
| 1095 | static struct test { | 1205 | static struct test { |
| 1096 | const char *desc; | 1206 | const char *desc; |
| 1097 | int (*func)(void); | 1207 | int (*func)(void); |
| @@ -1135,6 +1245,10 @@ static struct test { | |||
| 1135 | .func = dso__test_data, | 1245 | .func = dso__test_data, |
| 1136 | }, | 1246 | }, |
| 1137 | { | 1247 | { |
| 1248 | .desc = "roundtrip evsel->name check", | ||
| 1249 | .func = perf_evsel__roundtrip_name_test, | ||
| 1250 | }, | ||
| 1251 | { | ||
| 1138 | .func = NULL, | 1252 | .func = NULL, |
| 1139 | }, | 1253 | }, |
| 1140 | }; | 1254 | }; |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 3a282c0057d2..51ef69c9841d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <pthread.h> | 17 | #include <pthread.h> |
| 18 | 18 | ||
| 19 | const char *disassembler_style; | 19 | const char *disassembler_style; |
| 20 | const char *objdump_path; | ||
| 20 | 21 | ||
| 21 | static struct ins *ins__find(const char *name); | 22 | static struct ins *ins__find(const char *name); |
| 22 | static int disasm_line__parse(char *line, char **namep, char **rawp); | 23 | static int disasm_line__parse(char *line, char **namep, char **rawp); |
| @@ -820,9 +821,10 @@ fallback: | |||
| 820 | dso, dso->long_name, sym, sym->name); | 821 | dso, dso->long_name, sym, sym->name); |
| 821 | 822 | ||
| 822 | snprintf(command, sizeof(command), | 823 | snprintf(command, sizeof(command), |
| 823 | "objdump %s%s --start-address=0x%016" PRIx64 | 824 | "%s %s%s --start-address=0x%016" PRIx64 |
| 824 | " --stop-address=0x%016" PRIx64 | 825 | " --stop-address=0x%016" PRIx64 |
| 825 | " -d %s %s -C %s|grep -v %s|expand", | 826 | " -d %s %s -C %s|grep -v %s|expand", |
| 827 | objdump_path ? objdump_path : "objdump", | ||
| 826 | disassembler_style ? "-M " : "", | 828 | disassembler_style ? "-M " : "", |
| 827 | disassembler_style ? disassembler_style : "", | 829 | disassembler_style ? disassembler_style : "", |
| 828 | map__rip_2objdump(map, sym->start), | 830 | map__rip_2objdump(map, sym->start), |
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 78a5692dd718..a6d6bc5d7164 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
| @@ -152,5 +152,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx, | |||
| 152 | #endif | 152 | #endif |
| 153 | 153 | ||
| 154 | extern const char *disassembler_style; | 154 | extern const char *disassembler_style; |
| 155 | extern const char *objdump_path; | ||
| 155 | 156 | ||
| 156 | #endif /* __PERF_ANNOTATE_H */ | 157 | #endif /* __PERF_ANNOTATE_H */ |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 3a0f1a5da91c..84ff6f160cd0 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
| @@ -120,7 +120,9 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, | |||
| 120 | if (!full) { | 120 | if (!full) { |
| 121 | event->comm.tid = pid; | 121 | event->comm.tid = pid; |
| 122 | 122 | ||
| 123 | process(tool, event, &synth_sample, machine); | 123 | if (process(tool, event, &synth_sample, machine) != 0) |
| 124 | return -1; | ||
| 125 | |||
| 124 | goto out; | 126 | goto out; |
| 125 | } | 127 | } |
| 126 | 128 | ||
| @@ -151,7 +153,10 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, | |||
| 151 | 153 | ||
| 152 | event->comm.tid = pid; | 154 | event->comm.tid = pid; |
| 153 | 155 | ||
| 154 | process(tool, event, &synth_sample, machine); | 156 | if (process(tool, event, &synth_sample, machine) != 0) { |
| 157 | tgid = -1; | ||
| 158 | break; | ||
| 159 | } | ||
| 155 | } | 160 | } |
| 156 | 161 | ||
| 157 | closedir(tasks); | 162 | closedir(tasks); |
| @@ -167,6 +172,7 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
| 167 | { | 172 | { |
| 168 | char filename[PATH_MAX]; | 173 | char filename[PATH_MAX]; |
| 169 | FILE *fp; | 174 | FILE *fp; |
| 175 | int rc = 0; | ||
| 170 | 176 | ||
| 171 | snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); | 177 | snprintf(filename, sizeof(filename), "/proc/%d/maps", pid); |
| 172 | 178 | ||
| @@ -231,18 +237,22 @@ static int perf_event__synthesize_mmap_events(struct perf_tool *tool, | |||
| 231 | event->mmap.pid = tgid; | 237 | event->mmap.pid = tgid; |
| 232 | event->mmap.tid = pid; | 238 | event->mmap.tid = pid; |
| 233 | 239 | ||
| 234 | process(tool, event, &synth_sample, machine); | 240 | if (process(tool, event, &synth_sample, machine) != 0) { |
| 241 | rc = -1; | ||
| 242 | break; | ||
| 243 | } | ||
| 235 | } | 244 | } |
| 236 | } | 245 | } |
| 237 | 246 | ||
| 238 | fclose(fp); | 247 | fclose(fp); |
| 239 | return 0; | 248 | return rc; |
| 240 | } | 249 | } |
| 241 | 250 | ||
| 242 | int perf_event__synthesize_modules(struct perf_tool *tool, | 251 | int perf_event__synthesize_modules(struct perf_tool *tool, |
| 243 | perf_event__handler_t process, | 252 | perf_event__handler_t process, |
| 244 | struct machine *machine) | 253 | struct machine *machine) |
| 245 | { | 254 | { |
| 255 | int rc = 0; | ||
| 246 | struct rb_node *nd; | 256 | struct rb_node *nd; |
| 247 | struct map_groups *kmaps = &machine->kmaps; | 257 | struct map_groups *kmaps = &machine->kmaps; |
| 248 | union perf_event *event = zalloc((sizeof(event->mmap) + | 258 | union perf_event *event = zalloc((sizeof(event->mmap) + |
| @@ -284,11 +294,14 @@ int perf_event__synthesize_modules(struct perf_tool *tool, | |||
| 284 | 294 | ||
| 285 | memcpy(event->mmap.filename, pos->dso->long_name, | 295 | memcpy(event->mmap.filename, pos->dso->long_name, |
| 286 | pos->dso->long_name_len + 1); | 296 | pos->dso->long_name_len + 1); |
| 287 | process(tool, event, &synth_sample, machine); | 297 | if (process(tool, event, &synth_sample, machine) != 0) { |
| 298 | rc = -1; | ||
| 299 | break; | ||
| 300 | } | ||
| 288 | } | 301 | } |
| 289 | 302 | ||
| 290 | free(event); | 303 | free(event); |
| 291 | return 0; | 304 | return rc; |
| 292 | } | 305 | } |
| 293 | 306 | ||
| 294 | static int __event__synthesize_thread(union perf_event *comm_event, | 307 | static int __event__synthesize_thread(union perf_event *comm_event, |
| @@ -392,12 +405,16 @@ int perf_event__synthesize_threads(struct perf_tool *tool, | |||
| 392 | if (*end) /* only interested in proper numerical dirents */ | 405 | if (*end) /* only interested in proper numerical dirents */ |
| 393 | continue; | 406 | continue; |
| 394 | 407 | ||
| 395 | __event__synthesize_thread(comm_event, mmap_event, pid, 1, | 408 | if (__event__synthesize_thread(comm_event, mmap_event, pid, 1, |
| 396 | process, tool, machine); | 409 | process, tool, machine) != 0) { |
| 410 | err = -1; | ||
| 411 | goto out_closedir; | ||
| 412 | } | ||
| 397 | } | 413 | } |
| 398 | 414 | ||
| 399 | closedir(proc); | ||
| 400 | err = 0; | 415 | err = 0; |
| 416 | out_closedir: | ||
| 417 | closedir(proc); | ||
| 401 | out_free_mmap: | 418 | out_free_mmap: |
| 402 | free(mmap_event); | 419 | free(mmap_event); |
| 403 | out_free_comm: | 420 | out_free_comm: |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4774ac1e3d5f..892353729c7a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -889,3 +889,16 @@ int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *even | |||
| 889 | struct perf_evsel *evsel = perf_evlist__first(evlist); | 889 | struct perf_evsel *evsel = perf_evlist__first(evlist); |
| 890 | return perf_evsel__parse_sample(evsel, event, sample, swapped); | 890 | return perf_evsel__parse_sample(evsel, event, sample, swapped); |
| 891 | } | 891 | } |
| 892 | |||
| 893 | size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp) | ||
| 894 | { | ||
| 895 | struct perf_evsel *evsel; | ||
| 896 | size_t printed = 0; | ||
| 897 | |||
| 898 | list_for_each_entry(evsel, &evlist->entries, node) { | ||
| 899 | printed += fprintf(fp, "%s%s", evsel->idx ? ", " : "", | ||
| 900 | perf_evsel__name(evsel)); | ||
| 901 | } | ||
| 902 | |||
| 903 | return printed + fprintf(fp, "\n");; | ||
| 904 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 2ed255792c6b..3f2e1e4ccdd5 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -143,4 +143,6 @@ static inline struct perf_evsel *perf_evlist__last(struct perf_evlist *evlist) | |||
| 143 | { | 143 | { |
| 144 | return list_entry(evlist->entries.prev, struct perf_evsel, node); | 144 | return list_entry(evlist->entries.prev, struct perf_evsel, node); |
| 145 | } | 145 | } |
| 146 | |||
| 147 | size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp); | ||
| 146 | #endif /* __PERF_EVLIST_H */ | 148 | #endif /* __PERF_EVLIST_H */ |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 7ff3c8fb736c..06f76441547a 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -68,7 +68,7 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) | |||
| 68 | return evsel; | 68 | return evsel; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { | 71 | const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = { |
| 72 | "cycles", | 72 | "cycles", |
| 73 | "instructions", | 73 | "instructions", |
| 74 | "cache-references", | 74 | "cache-references", |
| @@ -131,12 +131,12 @@ static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size) | |||
| 131 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); | 131 | return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); |
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | static const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { | 134 | const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX] = { |
| 135 | "cpu-clock", | 135 | "cpu-clock", |
| 136 | "task-clock", | 136 | "task-clock", |
| 137 | "page-faults", | 137 | "page-faults", |
| 138 | "context-switches", | 138 | "context-switches", |
| 139 | "CPU-migrations", | 139 | "cpu-migrations", |
| 140 | "minor-faults", | 140 | "minor-faults", |
| 141 | "major-faults", | 141 | "major-faults", |
| 142 | "alignment-faults", | 142 | "alignment-faults", |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 94f6ba16747f..a3f562cec433 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -97,8 +97,10 @@ extern const char *perf_evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX] | |||
| 97 | [PERF_EVSEL__MAX_ALIASES]; | 97 | [PERF_EVSEL__MAX_ALIASES]; |
| 98 | extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] | 98 | extern const char *perf_evsel__hw_cache_op[PERF_COUNT_HW_CACHE_OP_MAX] |
| 99 | [PERF_EVSEL__MAX_ALIASES]; | 99 | [PERF_EVSEL__MAX_ALIASES]; |
| 100 | const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] | 100 | extern const char *perf_evsel__hw_cache_result[PERF_COUNT_HW_CACHE_RESULT_MAX] |
| 101 | [PERF_EVSEL__MAX_ALIASES]; | 101 | [PERF_EVSEL__MAX_ALIASES]; |
| 102 | extern const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX]; | ||
| 103 | extern const char *perf_evsel__sw_names[PERF_COUNT_SW_MAX]; | ||
| 102 | int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, | 104 | int __perf_evsel__hw_cache_type_op_res_name(u8 type, u8 op, u8 result, |
| 103 | char *bf, size_t size); | 105 | char *bf, size_t size); |
| 104 | const char *perf_evsel__name(struct perf_evsel *evsel); | 106 | const char *perf_evsel__name(struct perf_evsel *evsel); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 9696e64c9dbd..d07bc134e562 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -610,11 +610,10 @@ static int write_event_desc(int fd, struct perf_header *h __used, | |||
| 610 | struct perf_evlist *evlist) | 610 | struct perf_evlist *evlist) |
| 611 | { | 611 | { |
| 612 | struct perf_evsel *evsel; | 612 | struct perf_evsel *evsel; |
| 613 | u32 nre = 0, nri, sz; | 613 | u32 nre, nri, sz; |
| 614 | int ret; | 614 | int ret; |
| 615 | 615 | ||
| 616 | list_for_each_entry(evsel, &evlist->entries, node) | 616 | nre = evlist->nr_entries; |
| 617 | nre++; | ||
| 618 | 617 | ||
| 619 | /* | 618 | /* |
| 620 | * write number of events | 619 | * write number of events |
| @@ -1441,6 +1440,9 @@ static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp) | |||
| 1441 | if (ret != sizeof(pmu_num)) | 1440 | if (ret != sizeof(pmu_num)) |
| 1442 | goto error; | 1441 | goto error; |
| 1443 | 1442 | ||
| 1443 | if (ph->needs_swap) | ||
| 1444 | pmu_num = bswap_32(pmu_num); | ||
| 1445 | |||
| 1444 | if (!pmu_num) { | 1446 | if (!pmu_num) { |
| 1445 | fprintf(fp, "# pmu mappings: not available\n"); | 1447 | fprintf(fp, "# pmu mappings: not available\n"); |
| 1446 | return; | 1448 | return; |
| @@ -1449,6 +1451,9 @@ static void print_pmu_mappings(struct perf_header *ph, int fd, FILE *fp) | |||
| 1449 | while (pmu_num) { | 1451 | while (pmu_num) { |
| 1450 | if (read(fd, &type, sizeof(type)) != sizeof(type)) | 1452 | if (read(fd, &type, sizeof(type)) != sizeof(type)) |
| 1451 | break; | 1453 | break; |
| 1454 | if (ph->needs_swap) | ||
| 1455 | type = bswap_32(type); | ||
| 1456 | |||
| 1452 | name = do_read_string(fd, ph); | 1457 | name = do_read_string(fd, ph); |
| 1453 | if (!name) | 1458 | if (!name) |
| 1454 | break; | 1459 | break; |
| @@ -2290,33 +2295,39 @@ static int read_attr(int fd, struct perf_header *ph, | |||
| 2290 | return ret <= 0 ? -1 : 0; | 2295 | return ret <= 0 ? -1 : 0; |
| 2291 | } | 2296 | } |
| 2292 | 2297 | ||
| 2293 | static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel, | 2298 | static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel, |
| 2294 | struct pevent *pevent) | 2299 | struct pevent *pevent) |
| 2295 | { | 2300 | { |
| 2296 | struct event_format *event = pevent_find_event(pevent, | 2301 | struct event_format *event; |
| 2297 | evsel->attr.config); | ||
| 2298 | char bf[128]; | 2302 | char bf[128]; |
| 2299 | 2303 | ||
| 2304 | /* already prepared */ | ||
| 2305 | if (evsel->tp_format) | ||
| 2306 | return 0; | ||
| 2307 | |||
| 2308 | event = pevent_find_event(pevent, evsel->attr.config); | ||
| 2300 | if (event == NULL) | 2309 | if (event == NULL) |
| 2301 | return -1; | 2310 | return -1; |
| 2302 | 2311 | ||
| 2303 | snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); | 2312 | if (!evsel->name) { |
| 2304 | evsel->name = strdup(bf); | 2313 | snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); |
| 2305 | if (event->name == NULL) | 2314 | evsel->name = strdup(bf); |
| 2306 | return -1; | 2315 | if (evsel->name == NULL) |
| 2316 | return -1; | ||
| 2317 | } | ||
| 2307 | 2318 | ||
| 2308 | evsel->tp_format = event; | 2319 | evsel->tp_format = event; |
| 2309 | return 0; | 2320 | return 0; |
| 2310 | } | 2321 | } |
| 2311 | 2322 | ||
| 2312 | static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist, | 2323 | static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist, |
| 2313 | struct pevent *pevent) | 2324 | struct pevent *pevent) |
| 2314 | { | 2325 | { |
| 2315 | struct perf_evsel *pos; | 2326 | struct perf_evsel *pos; |
| 2316 | 2327 | ||
| 2317 | list_for_each_entry(pos, &evlist->entries, node) { | 2328 | list_for_each_entry(pos, &evlist->entries, node) { |
| 2318 | if (pos->attr.type == PERF_TYPE_TRACEPOINT && | 2329 | if (pos->attr.type == PERF_TYPE_TRACEPOINT && |
| 2319 | perf_evsel__set_tracepoint_name(pos, pevent)) | 2330 | perf_evsel__prepare_tracepoint_event(pos, pevent)) |
| 2320 | return -1; | 2331 | return -1; |
| 2321 | } | 2332 | } |
| 2322 | 2333 | ||
| @@ -2404,7 +2415,8 @@ int perf_session__read_header(struct perf_session *session, int fd) | |||
| 2404 | 2415 | ||
| 2405 | lseek(fd, header->data_offset, SEEK_SET); | 2416 | lseek(fd, header->data_offset, SEEK_SET); |
| 2406 | 2417 | ||
| 2407 | if (perf_evlist__set_tracepoint_names(session->evlist, session->pevent)) | 2418 | if (perf_evlist__prepare_tracepoint_events(session->evlist, |
| 2419 | session->pevent)) | ||
| 2408 | goto out_delete_evlist; | 2420 | goto out_delete_evlist; |
| 2409 | 2421 | ||
| 2410 | header->frozen = 1; | 2422 | header->frozen = 1; |
| @@ -2638,7 +2650,8 @@ int perf_event__process_tracing_data(union perf_event *event, | |||
| 2638 | if (size_read + padding != size) | 2650 | if (size_read + padding != size) |
| 2639 | die("tracing data size mismatch"); | 2651 | die("tracing data size mismatch"); |
| 2640 | 2652 | ||
| 2641 | perf_evlist__set_tracepoint_names(session->evlist, session->pevent); | 2653 | perf_evlist__prepare_tracepoint_events(session->evlist, |
| 2654 | session->pevent); | ||
| 2642 | 2655 | ||
| 2643 | return size_read + padding; | 2656 | return size_read + padding; |
| 2644 | } | 2657 | } |
diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c index fd530dced9cb..77c504ff0088 100644 --- a/tools/perf/util/intlist.c +++ b/tools/perf/util/intlist.c | |||
| @@ -52,9 +52,9 @@ int intlist__add(struct intlist *ilist, int i) | |||
| 52 | return rblist__add_node(&ilist->rblist, (void *)((long)i)); | 52 | return rblist__add_node(&ilist->rblist, (void *)((long)i)); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | void intlist__remove(struct intlist *ilist __used, struct int_node *node) | 55 | void intlist__remove(struct intlist *ilist, struct int_node *node) |
| 56 | { | 56 | { |
| 57 | int_node__delete(node); | 57 | rblist__remove_node(&ilist->rblist, &node->rb_node); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | struct int_node *intlist__find(struct intlist *ilist, int i) | 60 | struct int_node *intlist__find(struct intlist *ilist, int i) |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index b24630398b92..a031ee1f54f6 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -308,7 +308,7 @@ int parse_events_add_cache(struct list_head **list, int *idx, | |||
| 308 | for (i = 0; (i < 2) && (op_result[i]); i++) { | 308 | for (i = 0; (i < 2) && (op_result[i]); i++) { |
| 309 | char *str = op_result[i]; | 309 | char *str = op_result[i]; |
| 310 | 310 | ||
| 311 | snprintf(name + n, MAX_NAME_LEN - n, "-%s\n", str); | 311 | n += snprintf(name + n, MAX_NAME_LEN - n, "-%s", str); |
| 312 | 312 | ||
| 313 | if (cache_op == -1) { | 313 | if (cache_op == -1) { |
| 314 | cache_op = parse_aliases(str, perf_evsel__hw_cache_op, | 314 | cache_op = parse_aliases(str, perf_evsel__hw_cache_op, |
diff --git a/tools/perf/util/scripting-engines/trace-event-perl.c b/tools/perf/util/scripting-engines/trace-event-perl.c index d28001016fb5..94e673643bcb 100644 --- a/tools/perf/util/scripting-engines/trace-event-perl.c +++ b/tools/perf/util/scripting-engines/trace-event-perl.c | |||
| @@ -25,16 +25,16 @@ | |||
| 25 | #include <ctype.h> | 25 | #include <ctype.h> |
| 26 | #include <errno.h> | 26 | #include <errno.h> |
| 27 | 27 | ||
| 28 | #include "../../perf.h" | ||
| 29 | #include "../util.h" | 28 | #include "../util.h" |
| 29 | #include <EXTERN.h> | ||
| 30 | #include <perl.h> | ||
| 31 | |||
| 32 | #include "../../perf.h" | ||
| 30 | #include "../thread.h" | 33 | #include "../thread.h" |
| 31 | #include "../event.h" | 34 | #include "../event.h" |
| 32 | #include "../trace-event.h" | 35 | #include "../trace-event.h" |
| 33 | #include "../evsel.h" | 36 | #include "../evsel.h" |
| 34 | 37 | ||
| 35 | #include <EXTERN.h> | ||
| 36 | #include <perl.h> | ||
| 37 | |||
| 38 | void boot_Perf__Trace__Context(pTHX_ CV *cv); | 38 | void boot_Perf__Trace__Context(pTHX_ CV *cv); |
| 39 | void boot_DynaLoader(pTHX_ CV *cv); | 39 | void boot_DynaLoader(pTHX_ CV *cv); |
| 40 | typedef PerlInterpreter * INTERP; | 40 | typedef PerlInterpreter * INTERP; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f7bb7ae328da..945375897c2a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -692,7 +692,7 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
| 692 | struct perf_tool *tool, | 692 | struct perf_tool *tool, |
| 693 | u64 file_offset); | 693 | u64 file_offset); |
| 694 | 694 | ||
| 695 | static void flush_sample_queue(struct perf_session *s, | 695 | static int flush_sample_queue(struct perf_session *s, |
| 696 | struct perf_tool *tool) | 696 | struct perf_tool *tool) |
| 697 | { | 697 | { |
| 698 | struct ordered_samples *os = &s->ordered_samples; | 698 | struct ordered_samples *os = &s->ordered_samples; |
| @@ -705,7 +705,7 @@ static void flush_sample_queue(struct perf_session *s, | |||
| 705 | int ret; | 705 | int ret; |
| 706 | 706 | ||
| 707 | if (!tool->ordered_samples || !limit) | 707 | if (!tool->ordered_samples || !limit) |
| 708 | return; | 708 | return 0; |
| 709 | 709 | ||
| 710 | list_for_each_entry_safe(iter, tmp, head, list) { | 710 | list_for_each_entry_safe(iter, tmp, head, list) { |
| 711 | if (iter->timestamp > limit) | 711 | if (iter->timestamp > limit) |
| @@ -715,9 +715,12 @@ static void flush_sample_queue(struct perf_session *s, | |||
| 715 | s->header.needs_swap); | 715 | s->header.needs_swap); |
| 716 | if (ret) | 716 | if (ret) |
| 717 | pr_err("Can't parse sample, err = %d\n", ret); | 717 | pr_err("Can't parse sample, err = %d\n", ret); |
| 718 | else | 718 | else { |
| 719 | perf_session_deliver_event(s, iter->event, &sample, tool, | 719 | ret = perf_session_deliver_event(s, iter->event, &sample, tool, |
| 720 | iter->file_offset); | 720 | iter->file_offset); |
| 721 | if (ret) | ||
| 722 | return ret; | ||
| 723 | } | ||
| 721 | 724 | ||
| 722 | os->last_flush = iter->timestamp; | 725 | os->last_flush = iter->timestamp; |
| 723 | list_del(&iter->list); | 726 | list_del(&iter->list); |
| @@ -737,6 +740,8 @@ static void flush_sample_queue(struct perf_session *s, | |||
| 737 | } | 740 | } |
| 738 | 741 | ||
| 739 | os->nr_samples = 0; | 742 | os->nr_samples = 0; |
| 743 | |||
| 744 | return 0; | ||
| 740 | } | 745 | } |
| 741 | 746 | ||
| 742 | /* | 747 | /* |
| @@ -782,10 +787,11 @@ static int process_finished_round(struct perf_tool *tool, | |||
| 782 | union perf_event *event __used, | 787 | union perf_event *event __used, |
| 783 | struct perf_session *session) | 788 | struct perf_session *session) |
| 784 | { | 789 | { |
| 785 | flush_sample_queue(session, tool); | 790 | int ret = flush_sample_queue(session, tool); |
| 786 | session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; | 791 | if (!ret) |
| 792 | session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; | ||
| 787 | 793 | ||
| 788 | return 0; | 794 | return ret; |
| 789 | } | 795 | } |
| 790 | 796 | ||
| 791 | /* The queue is ordered by time */ | 797 | /* The queue is ordered by time */ |
| @@ -1443,7 +1449,7 @@ more: | |||
| 1443 | err = 0; | 1449 | err = 0; |
| 1444 | /* do the final flush for ordered samples */ | 1450 | /* do the final flush for ordered samples */ |
| 1445 | session->ordered_samples.next_flush = ULLONG_MAX; | 1451 | session->ordered_samples.next_flush = ULLONG_MAX; |
| 1446 | flush_sample_queue(session, tool); | 1452 | err = flush_sample_queue(session, tool); |
| 1447 | out_err: | 1453 | out_err: |
| 1448 | perf_session__warn_about_errors(session, tool); | 1454 | perf_session__warn_about_errors(session, tool); |
| 1449 | perf_session_free_sample_buffers(session); | 1455 | perf_session_free_sample_buffers(session); |
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index 95856ff3dda4..155d8b7078a7 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
| @@ -93,7 +93,7 @@ out: | |||
| 93 | 93 | ||
| 94 | void strlist__remove(struct strlist *slist, struct str_node *snode) | 94 | void strlist__remove(struct strlist *slist, struct str_node *snode) |
| 95 | { | 95 | { |
| 96 | str_node__delete(snode, slist->dupstr); | 96 | rblist__remove_node(&slist->rblist, &snode->rb_node); |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | struct str_node *strlist__find(struct strlist *slist, const char *entry) | 99 | struct str_node *strlist__find(struct strlist *slist, const char *entry) |
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 051eaa68095e..065528b7563e 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c | |||
| @@ -117,8 +117,8 @@ int perf_target__strerror(struct perf_target *target, int errnum, | |||
| 117 | 117 | ||
| 118 | if (err != buf) { | 118 | if (err != buf) { |
| 119 | size_t len = strlen(err); | 119 | size_t len = strlen(err); |
| 120 | char *c = mempcpy(buf, err, min(buflen - 1, len)); | 120 | memcpy(buf, err, min(buflen - 1, len)); |
| 121 | *c = '\0'; | 121 | *(buf + min(buflen - 1, len)) = '\0'; |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | return 0; | 124 | return 0; |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 00a93a91a235..67a371355c75 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
| @@ -69,11 +69,6 @@ | |||
| 69 | #include <sys/poll.h> | 69 | #include <sys/poll.h> |
| 70 | #include <sys/socket.h> | 70 | #include <sys/socket.h> |
| 71 | #include <sys/ioctl.h> | 71 | #include <sys/ioctl.h> |
| 72 | #include <sys/select.h> | ||
| 73 | #include <netinet/in.h> | ||
| 74 | #include <netinet/tcp.h> | ||
| 75 | #include <arpa/inet.h> | ||
| 76 | #include <netdb.h> | ||
| 77 | #include <inttypes.h> | 72 | #include <inttypes.h> |
| 78 | #include "../../../include/linux/magic.h" | 73 | #include "../../../include/linux/magic.h" |
| 79 | #include "types.h" | 74 | #include "types.h" |
