| .. | .. |
|---|
| 4 | 4 | #include "builtin.h" |
|---|
| 5 | 5 | #include "perf.h" |
|---|
| 6 | 6 | |
|---|
| 7 | | -#include "util/evlist.h" |
|---|
| 7 | +#include "util/evlist.h" // for struct evsel_str_handler |
|---|
| 8 | 8 | #include "util/evsel.h" |
|---|
| 9 | | -#include "util/util.h" |
|---|
| 10 | | -#include "util/cache.h" |
|---|
| 11 | 9 | #include "util/symbol.h" |
|---|
| 12 | 10 | #include "util/thread.h" |
|---|
| 13 | 11 | #include "util/header.h" |
|---|
| 14 | 12 | |
|---|
| 13 | +#include <subcmd/pager.h> |
|---|
| 15 | 14 | #include <subcmd/parse-options.h> |
|---|
| 16 | 15 | #include "util/trace-event.h" |
|---|
| 17 | 16 | |
|---|
| .. | .. |
|---|
| 30 | 29 | #include <linux/list.h> |
|---|
| 31 | 30 | #include <linux/hash.h> |
|---|
| 32 | 31 | #include <linux/kernel.h> |
|---|
| 32 | +#include <linux/zalloc.h> |
|---|
| 33 | +#include <linux/err.h> |
|---|
| 33 | 34 | |
|---|
| 34 | 35 | static struct perf_session *session; |
|---|
| 35 | 36 | |
|---|
| .. | .. |
|---|
| 47 | 48 | struct rb_node rb; /* used for sorting */ |
|---|
| 48 | 49 | |
|---|
| 49 | 50 | /* |
|---|
| 50 | | - * FIXME: perf_evsel__intval() returns u64, |
|---|
| 51 | + * FIXME: evsel__intval() returns u64, |
|---|
| 51 | 52 | * so address of lockdep_map should be dealed as 64bit. |
|---|
| 52 | 53 | * Is there more better solution? |
|---|
| 53 | 54 | */ |
|---|
| .. | .. |
|---|
| 347 | 348 | } |
|---|
| 348 | 349 | |
|---|
| 349 | 350 | struct trace_lock_handler { |
|---|
| 350 | | - int (*acquire_event)(struct perf_evsel *evsel, |
|---|
| 351 | + int (*acquire_event)(struct evsel *evsel, |
|---|
| 351 | 352 | struct perf_sample *sample); |
|---|
| 352 | 353 | |
|---|
| 353 | | - int (*acquired_event)(struct perf_evsel *evsel, |
|---|
| 354 | + int (*acquired_event)(struct evsel *evsel, |
|---|
| 354 | 355 | struct perf_sample *sample); |
|---|
| 355 | 356 | |
|---|
| 356 | | - int (*contended_event)(struct perf_evsel *evsel, |
|---|
| 357 | + int (*contended_event)(struct evsel *evsel, |
|---|
| 357 | 358 | struct perf_sample *sample); |
|---|
| 358 | 359 | |
|---|
| 359 | | - int (*release_event)(struct perf_evsel *evsel, |
|---|
| 360 | + int (*release_event)(struct evsel *evsel, |
|---|
| 360 | 361 | struct perf_sample *sample); |
|---|
| 361 | 362 | }; |
|---|
| 362 | 363 | |
|---|
| .. | .. |
|---|
| 396 | 397 | READ_LOCK = 2, |
|---|
| 397 | 398 | }; |
|---|
| 398 | 399 | |
|---|
| 399 | | -static int report_lock_acquire_event(struct perf_evsel *evsel, |
|---|
| 400 | +static int report_lock_acquire_event(struct evsel *evsel, |
|---|
| 400 | 401 | struct perf_sample *sample) |
|---|
| 401 | 402 | { |
|---|
| 402 | 403 | void *addr; |
|---|
| 403 | 404 | struct lock_stat *ls; |
|---|
| 404 | 405 | struct thread_stat *ts; |
|---|
| 405 | 406 | struct lock_seq_stat *seq; |
|---|
| 406 | | - const char *name = perf_evsel__strval(evsel, sample, "name"); |
|---|
| 407 | | - u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 408 | | - int flag = perf_evsel__intval(evsel, sample, "flag"); |
|---|
| 407 | + const char *name = evsel__strval(evsel, sample, "name"); |
|---|
| 408 | + u64 tmp = evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 409 | + int flag = evsel__intval(evsel, sample, "flags"); |
|---|
| 409 | 410 | |
|---|
| 410 | 411 | memcpy(&addr, &tmp, sizeof(void *)); |
|---|
| 411 | 412 | |
|---|
| .. | .. |
|---|
| 454 | 455 | /* broken lock sequence, discard it */ |
|---|
| 455 | 456 | ls->discard = 1; |
|---|
| 456 | 457 | bad_hist[BROKEN_ACQUIRE]++; |
|---|
| 457 | | - list_del(&seq->list); |
|---|
| 458 | + list_del_init(&seq->list); |
|---|
| 458 | 459 | free(seq); |
|---|
| 459 | 460 | goto end; |
|---|
| 460 | 461 | default: |
|---|
| .. | .. |
|---|
| 468 | 469 | return 0; |
|---|
| 469 | 470 | } |
|---|
| 470 | 471 | |
|---|
| 471 | | -static int report_lock_acquired_event(struct perf_evsel *evsel, |
|---|
| 472 | +static int report_lock_acquired_event(struct evsel *evsel, |
|---|
| 472 | 473 | struct perf_sample *sample) |
|---|
| 473 | 474 | { |
|---|
| 474 | 475 | void *addr; |
|---|
| .. | .. |
|---|
| 476 | 477 | struct thread_stat *ts; |
|---|
| 477 | 478 | struct lock_seq_stat *seq; |
|---|
| 478 | 479 | u64 contended_term; |
|---|
| 479 | | - const char *name = perf_evsel__strval(evsel, sample, "name"); |
|---|
| 480 | | - u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 480 | + const char *name = evsel__strval(evsel, sample, "name"); |
|---|
| 481 | + u64 tmp = evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 481 | 482 | |
|---|
| 482 | 483 | memcpy(&addr, &tmp, sizeof(void *)); |
|---|
| 483 | 484 | |
|---|
| .. | .. |
|---|
| 515 | 516 | /* broken lock sequence, discard it */ |
|---|
| 516 | 517 | ls->discard = 1; |
|---|
| 517 | 518 | bad_hist[BROKEN_ACQUIRED]++; |
|---|
| 518 | | - list_del(&seq->list); |
|---|
| 519 | + list_del_init(&seq->list); |
|---|
| 519 | 520 | free(seq); |
|---|
| 520 | 521 | goto end; |
|---|
| 521 | 522 | default: |
|---|
| .. | .. |
|---|
| 531 | 532 | return 0; |
|---|
| 532 | 533 | } |
|---|
| 533 | 534 | |
|---|
| 534 | | -static int report_lock_contended_event(struct perf_evsel *evsel, |
|---|
| 535 | +static int report_lock_contended_event(struct evsel *evsel, |
|---|
| 535 | 536 | struct perf_sample *sample) |
|---|
| 536 | 537 | { |
|---|
| 537 | 538 | void *addr; |
|---|
| 538 | 539 | struct lock_stat *ls; |
|---|
| 539 | 540 | struct thread_stat *ts; |
|---|
| 540 | 541 | struct lock_seq_stat *seq; |
|---|
| 541 | | - const char *name = perf_evsel__strval(evsel, sample, "name"); |
|---|
| 542 | | - u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 542 | + const char *name = evsel__strval(evsel, sample, "name"); |
|---|
| 543 | + u64 tmp = evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 543 | 544 | |
|---|
| 544 | 545 | memcpy(&addr, &tmp, sizeof(void *)); |
|---|
| 545 | 546 | |
|---|
| .. | .. |
|---|
| 570 | 571 | /* broken lock sequence, discard it */ |
|---|
| 571 | 572 | ls->discard = 1; |
|---|
| 572 | 573 | bad_hist[BROKEN_CONTENDED]++; |
|---|
| 573 | | - list_del(&seq->list); |
|---|
| 574 | + list_del_init(&seq->list); |
|---|
| 574 | 575 | free(seq); |
|---|
| 575 | 576 | goto end; |
|---|
| 576 | 577 | default: |
|---|
| .. | .. |
|---|
| 586 | 587 | return 0; |
|---|
| 587 | 588 | } |
|---|
| 588 | 589 | |
|---|
| 589 | | -static int report_lock_release_event(struct perf_evsel *evsel, |
|---|
| 590 | +static int report_lock_release_event(struct evsel *evsel, |
|---|
| 590 | 591 | struct perf_sample *sample) |
|---|
| 591 | 592 | { |
|---|
| 592 | 593 | void *addr; |
|---|
| 593 | 594 | struct lock_stat *ls; |
|---|
| 594 | 595 | struct thread_stat *ts; |
|---|
| 595 | 596 | struct lock_seq_stat *seq; |
|---|
| 596 | | - const char *name = perf_evsel__strval(evsel, sample, "name"); |
|---|
| 597 | | - u64 tmp = perf_evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 597 | + const char *name = evsel__strval(evsel, sample, "name"); |
|---|
| 598 | + u64 tmp = evsel__intval(evsel, sample, "lockdep_addr"); |
|---|
| 598 | 599 | |
|---|
| 599 | 600 | memcpy(&addr, &tmp, sizeof(void *)); |
|---|
| 600 | 601 | |
|---|
| .. | .. |
|---|
| 639 | 640 | |
|---|
| 640 | 641 | ls->nr_release++; |
|---|
| 641 | 642 | free_seq: |
|---|
| 642 | | - list_del(&seq->list); |
|---|
| 643 | + list_del_init(&seq->list); |
|---|
| 643 | 644 | free(seq); |
|---|
| 644 | 645 | end: |
|---|
| 645 | 646 | return 0; |
|---|
| .. | .. |
|---|
| 656 | 657 | |
|---|
| 657 | 658 | static struct trace_lock_handler *trace_handler; |
|---|
| 658 | 659 | |
|---|
| 659 | | -static int perf_evsel__process_lock_acquire(struct perf_evsel *evsel, |
|---|
| 660 | | - struct perf_sample *sample) |
|---|
| 660 | +static int evsel__process_lock_acquire(struct evsel *evsel, struct perf_sample *sample) |
|---|
| 661 | 661 | { |
|---|
| 662 | 662 | if (trace_handler->acquire_event) |
|---|
| 663 | 663 | return trace_handler->acquire_event(evsel, sample); |
|---|
| 664 | 664 | return 0; |
|---|
| 665 | 665 | } |
|---|
| 666 | 666 | |
|---|
| 667 | | -static int perf_evsel__process_lock_acquired(struct perf_evsel *evsel, |
|---|
| 668 | | - struct perf_sample *sample) |
|---|
| 667 | +static int evsel__process_lock_acquired(struct evsel *evsel, struct perf_sample *sample) |
|---|
| 669 | 668 | { |
|---|
| 670 | 669 | if (trace_handler->acquired_event) |
|---|
| 671 | 670 | return trace_handler->acquired_event(evsel, sample); |
|---|
| 672 | 671 | return 0; |
|---|
| 673 | 672 | } |
|---|
| 674 | 673 | |
|---|
| 675 | | -static int perf_evsel__process_lock_contended(struct perf_evsel *evsel, |
|---|
| 676 | | - struct perf_sample *sample) |
|---|
| 674 | +static int evsel__process_lock_contended(struct evsel *evsel, struct perf_sample *sample) |
|---|
| 677 | 675 | { |
|---|
| 678 | 676 | if (trace_handler->contended_event) |
|---|
| 679 | 677 | return trace_handler->contended_event(evsel, sample); |
|---|
| 680 | 678 | return 0; |
|---|
| 681 | 679 | } |
|---|
| 682 | 680 | |
|---|
| 683 | | -static int perf_evsel__process_lock_release(struct perf_evsel *evsel, |
|---|
| 684 | | - struct perf_sample *sample) |
|---|
| 681 | +static int evsel__process_lock_release(struct evsel *evsel, struct perf_sample *sample) |
|---|
| 685 | 682 | { |
|---|
| 686 | 683 | if (trace_handler->release_event) |
|---|
| 687 | 684 | return trace_handler->release_event(evsel, sample); |
|---|
| .. | .. |
|---|
| 774 | 771 | pr_info("%10d: %s\n", st->tid, thread__comm_str(t)); |
|---|
| 775 | 772 | node = rb_next(node); |
|---|
| 776 | 773 | thread__put(t); |
|---|
| 777 | | - }; |
|---|
| 774 | + } |
|---|
| 778 | 775 | } |
|---|
| 779 | 776 | |
|---|
| 780 | 777 | static void dump_map(void) |
|---|
| .. | .. |
|---|
| 806 | 803 | return rc; |
|---|
| 807 | 804 | } |
|---|
| 808 | 805 | |
|---|
| 809 | | -typedef int (*tracepoint_handler)(struct perf_evsel *evsel, |
|---|
| 806 | +typedef int (*tracepoint_handler)(struct evsel *evsel, |
|---|
| 810 | 807 | struct perf_sample *sample); |
|---|
| 811 | 808 | |
|---|
| 812 | 809 | static int process_sample_event(struct perf_tool *tool __maybe_unused, |
|---|
| 813 | 810 | union perf_event *event, |
|---|
| 814 | 811 | struct perf_sample *sample, |
|---|
| 815 | | - struct perf_evsel *evsel, |
|---|
| 812 | + struct evsel *evsel, |
|---|
| 816 | 813 | struct machine *machine) |
|---|
| 817 | 814 | { |
|---|
| 818 | 815 | int err = 0; |
|---|
| .. | .. |
|---|
| 847 | 844 | } |
|---|
| 848 | 845 | } |
|---|
| 849 | 846 | |
|---|
| 850 | | -static const struct perf_evsel_str_handler lock_tracepoints[] = { |
|---|
| 851 | | - { "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ |
|---|
| 852 | | - { "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ |
|---|
| 853 | | - { "lock:lock_contended", perf_evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ |
|---|
| 854 | | - { "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ |
|---|
| 847 | +static const struct evsel_str_handler lock_tracepoints[] = { |
|---|
| 848 | + { "lock:lock_acquire", evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ |
|---|
| 849 | + { "lock:lock_acquired", evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ |
|---|
| 850 | + { "lock:lock_contended", evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ |
|---|
| 851 | + { "lock:lock_release", evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ |
|---|
| 855 | 852 | }; |
|---|
| 856 | 853 | |
|---|
| 857 | 854 | static bool force; |
|---|
| .. | .. |
|---|
| 866 | 863 | .ordered_events = true, |
|---|
| 867 | 864 | }; |
|---|
| 868 | 865 | struct perf_data data = { |
|---|
| 869 | | - .file = { |
|---|
| 870 | | - .path = input_name, |
|---|
| 871 | | - }, |
|---|
| 872 | | - .mode = PERF_DATA_MODE_READ, |
|---|
| 873 | | - .force = force, |
|---|
| 866 | + .path = input_name, |
|---|
| 867 | + .mode = PERF_DATA_MODE_READ, |
|---|
| 868 | + .force = force, |
|---|
| 874 | 869 | }; |
|---|
| 875 | 870 | |
|---|
| 876 | 871 | session = perf_session__new(&data, false, &eops); |
|---|
| 877 | | - if (!session) { |
|---|
| 872 | + if (IS_ERR(session)) { |
|---|
| 878 | 873 | pr_err("Initializing perf session failed\n"); |
|---|
| 879 | | - return -1; |
|---|
| 874 | + return PTR_ERR(session); |
|---|
| 880 | 875 | } |
|---|
| 881 | 876 | |
|---|
| 882 | 877 | symbol__init(&session->header.env); |
|---|