diff options
author | Davidlohr Bueso <davidlohr@hp.com> | 2013-09-08 22:19:16 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-10-09 10:23:48 -0400 |
commit | 375eb2be5584b8182a917124ca217b74e43d2dc4 (patch) | |
tree | 16f12c133dec56fc7700e55248b1bf32cdf3e59f /tools/perf/builtin-lock.c | |
parent | 0a98c7febf55325ebac4f28289a9433f4b66ed0e (diff) |
perf lock: Redo __cmd_report
This function should be straightforward, and we can remove some trivial
logic by moving the functionality of read_events() into __cmd_report() -
thus allowing a new session to be properly deleted.
Since the 'info' subcommand also needs to process the recorded events,
add a 'display_info' flag to differentiate between report and info
commands.
Furthermore, this patch also calls perf_session__has_traces(), making
sure that we don't compare apples and oranges, fixing a segfault when
using an perf.data file generated by a different subcommand. ie:
./perf mem record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.017 MB perf.data (~724 samples) ]
./perf lock report
Segmentation fault (core dumped)
Signed-off-by: Davidlohr Bueso <davidlohr@hp.com>
Cc: Aswin Chandramouleeswaran <aswin@hp.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1378693159-8747-5-git-send-email-davidlohr@hp.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-lock.c')
-rw-r--r-- | tools/perf/builtin-lock.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 77843478a27a..780484fb59a0 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c | |||
@@ -818,6 +818,18 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, | |||
818 | return 0; | 818 | return 0; |
819 | } | 819 | } |
820 | 820 | ||
821 | static void sort_result(void) | ||
822 | { | ||
823 | unsigned int i; | ||
824 | struct lock_stat *st; | ||
825 | |||
826 | for (i = 0; i < LOCKHASH_SIZE; i++) { | ||
827 | list_for_each_entry(st, &lockhash_table[i], hash_entry) { | ||
828 | insert_to_result(st, compare); | ||
829 | } | ||
830 | } | ||
831 | } | ||
832 | |||
821 | static const struct perf_evsel_str_handler lock_tracepoints[] = { | 833 | static const struct perf_evsel_str_handler lock_tracepoints[] = { |
822 | { "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ | 834 | { "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ |
823 | { "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ | 835 | { "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ |
@@ -825,51 +837,47 @@ static const struct perf_evsel_str_handler lock_tracepoints[] = { | |||
825 | { "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ | 837 | { "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ |
826 | }; | 838 | }; |
827 | 839 | ||
828 | static int read_events(void) | 840 | static int __cmd_report(bool display_info) |
829 | { | 841 | { |
842 | int err = -EINVAL; | ||
830 | struct perf_tool eops = { | 843 | struct perf_tool eops = { |
831 | .sample = process_sample_event, | 844 | .sample = process_sample_event, |
832 | .comm = perf_event__process_comm, | 845 | .comm = perf_event__process_comm, |
833 | .ordered_samples = true, | 846 | .ordered_samples = true, |
834 | }; | 847 | }; |
848 | |||
835 | session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); | 849 | session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); |
836 | if (!session) { | 850 | if (!session) { |
837 | pr_err("Initializing perf session failed\n"); | 851 | pr_err("Initializing perf session failed\n"); |
838 | return -1; | 852 | return -ENOMEM; |
839 | } | 853 | } |
840 | 854 | ||
855 | if (!perf_session__has_traces(session, "lock record")) | ||
856 | goto out_delete; | ||
857 | |||
841 | if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) { | 858 | if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) { |
842 | pr_err("Initializing perf session tracepoint handlers failed\n"); | 859 | pr_err("Initializing perf session tracepoint handlers failed\n"); |
843 | return -1; | 860 | goto out_delete; |
844 | } | 861 | } |
845 | 862 | ||
846 | return perf_session__process_events(session, &eops); | 863 | if (select_key()) |
847 | } | 864 | goto out_delete; |
848 | 865 | ||
849 | static void sort_result(void) | 866 | err = perf_session__process_events(session, &eops); |
850 | { | 867 | if (err) |
851 | unsigned int i; | 868 | goto out_delete; |
852 | struct lock_stat *st; | ||
853 | |||
854 | for (i = 0; i < LOCKHASH_SIZE; i++) { | ||
855 | list_for_each_entry(st, &lockhash_table[i], hash_entry) { | ||
856 | insert_to_result(st, compare); | ||
857 | } | ||
858 | } | ||
859 | } | ||
860 | 869 | ||
861 | static int __cmd_report(void) | ||
862 | { | ||
863 | setup_pager(); | 870 | setup_pager(); |
871 | if (display_info) /* used for info subcommand */ | ||
872 | err = dump_info(); | ||
873 | else { | ||
874 | sort_result(); | ||
875 | print_result(); | ||
876 | } | ||
864 | 877 | ||
865 | if ((select_key() != 0) || | 878 | out_delete: |
866 | (read_events() != 0)) | 879 | perf_session__delete(session); |
867 | return -1; | 880 | return err; |
868 | |||
869 | sort_result(); | ||
870 | print_result(); | ||
871 | |||
872 | return 0; | ||
873 | } | 881 | } |
874 | 882 | ||
875 | static int __cmd_record(int argc, const char **argv) | 883 | static int __cmd_record(int argc, const char **argv) |
@@ -970,7 +978,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) | |||
970 | if (argc) | 978 | if (argc) |
971 | usage_with_options(report_usage, report_options); | 979 | usage_with_options(report_usage, report_options); |
972 | } | 980 | } |
973 | __cmd_report(); | 981 | rc = __cmd_report(false); |
974 | } else if (!strcmp(argv[0], "script")) { | 982 | } else if (!strcmp(argv[0], "script")) { |
975 | /* Aliased to 'perf script' */ | 983 | /* Aliased to 'perf script' */ |
976 | return cmd_script(argc, argv, prefix); | 984 | return cmd_script(argc, argv, prefix); |
@@ -983,11 +991,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) | |||
983 | } | 991 | } |
984 | /* recycling report_lock_ops */ | 992 | /* recycling report_lock_ops */ |
985 | trace_handler = &report_lock_ops; | 993 | trace_handler = &report_lock_ops; |
986 | setup_pager(); | 994 | rc = __cmd_report(true); |
987 | if (read_events() != 0) | ||
988 | rc = -1; | ||
989 | else | ||
990 | rc = dump_info(); | ||
991 | } else { | 995 | } else { |
992 | usage_with_options(lock_usage, lock_options); | 996 | usage_with_options(lock_usage, lock_options); |
993 | } | 997 | } |