提交 375eb2be 编写于 作者: D Davidlohr Bueso 提交者: Arnaldo Carvalho de Melo

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: NDavidlohr 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.comSigned-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
上级 0a98c7fe
...@@ -818,6 +818,18 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, ...@@ -818,6 +818,18 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
return 0; return 0;
} }
static void sort_result(void)
{
unsigned int i;
struct lock_stat *st;
for (i = 0; i < LOCKHASH_SIZE; i++) {
list_for_each_entry(st, &lockhash_table[i], hash_entry) {
insert_to_result(st, compare);
}
}
}
static const struct perf_evsel_str_handler lock_tracepoints[] = { static const struct perf_evsel_str_handler lock_tracepoints[] = {
{ "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */ { "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
{ "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */ { "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,51 +837,47 @@ static const struct perf_evsel_str_handler lock_tracepoints[] = {
{ "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */ { "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
}; };
static int read_events(void) static int __cmd_report(bool display_info)
{ {
int err = -EINVAL;
struct perf_tool eops = { struct perf_tool eops = {
.sample = process_sample_event, .sample = process_sample_event,
.comm = perf_event__process_comm, .comm = perf_event__process_comm,
.ordered_samples = true, .ordered_samples = true,
}; };
session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
if (!session) { if (!session) {
pr_err("Initializing perf session failed\n"); pr_err("Initializing perf session failed\n");
return -1; return -ENOMEM;
} }
if (!perf_session__has_traces(session, "lock record"))
goto out_delete;
if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) { if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
pr_err("Initializing perf session tracepoint handlers failed\n"); pr_err("Initializing perf session tracepoint handlers failed\n");
return -1; goto out_delete;
} }
return perf_session__process_events(session, &eops); if (select_key())
} goto out_delete;
static void sort_result(void) err = perf_session__process_events(session, &eops);
{ if (err)
unsigned int i; goto out_delete;
struct lock_stat *st;
for (i = 0; i < LOCKHASH_SIZE; i++) {
list_for_each_entry(st, &lockhash_table[i], hash_entry) {
insert_to_result(st, compare);
}
}
}
static int __cmd_report(void)
{
setup_pager(); setup_pager();
if (display_info) /* used for info subcommand */
err = dump_info();
else {
sort_result();
print_result();
}
if ((select_key() != 0) || out_delete:
(read_events() != 0)) perf_session__delete(session);
return -1; return err;
sort_result();
print_result();
return 0;
} }
static int __cmd_record(int argc, const char **argv) 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,7 +978,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
if (argc) if (argc)
usage_with_options(report_usage, report_options); usage_with_options(report_usage, report_options);
} }
__cmd_report(); rc = __cmd_report(false);
} else if (!strcmp(argv[0], "script")) { } else if (!strcmp(argv[0], "script")) {
/* Aliased to 'perf script' */ /* Aliased to 'perf script' */
return cmd_script(argc, argv, prefix); return cmd_script(argc, argv, prefix);
...@@ -983,11 +991,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -983,11 +991,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
} }
/* recycling report_lock_ops */ /* recycling report_lock_ops */
trace_handler = &report_lock_ops; trace_handler = &report_lock_ops;
setup_pager(); rc = __cmd_report(true);
if (read_events() != 0)
rc = -1;
else
rc = dump_info();
} else { } else {
usage_with_options(lock_usage, lock_options); usage_with_options(lock_usage, lock_options);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册