diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-01-12 20:39:47 +0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-01-12 20:39:47 +0400 |
commit | 1341f3e4c0276aae3de6d902c9202265d89fe438 (patch) | |
tree | b33a50166e421383356139c4e8c5645959d6c9c4 /tools/perf/builtin-record.c | |
parent | a21b0b354d4ac39be691f51c53562e2c24443d9e (diff) | |
parent | 74cf249d5cf7de84c88cca69a2f13b13d500ff94 (diff) | |
download | linux-1341f3e4c0276aae3de6d902c9202265d89fe438.tar.xz |
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf updates from Arnaldo Carvalho de Melo:
User visible changes:
Improvements:
* Support showing source code, asking for variables to be collected
at probe time and other 'perf probe' operations that use DWARF information.
This supports only binaries with debugging information at this time, detached
debuginfo (aka debuginfo packages) support should come in later patches.
(Masami Hiramatsu)
* Add a perf.data file header window in the 'perf report' TUI, associated
with the 'i' hotkey, providing a counterpart to the --header option in the
stdio UI. (Namhyung Kim)
* Guest related improvements to 'perf kvm', including allowing to
specify a directory with guest specific /proc information. (Dongsheng Yang)
* Print session information only if --stdio is given (Namhyung Kim)
Developer stuff:
Fixes:
* Get rid of a duplicate va_end() in error reporting (Namhyung Kim)
* If a hist entry doesn't have symbol information, compare it with its
address. Affects upcoming new feature (--cumulate) (Namhyung Kim)
Improvements:
* Make libtraceevent install target quieter (Jiri Olsa)
* Make tests/make output more compact (Jiri Olsa)
* Ignore generated files in feature-checks (Chunwei Chen)
New APIs:
* Introduce pevent_filter_strerror() in libtraceevent, similar in
purpose to libc's strerror() function. (Namhyung Kim)
Refactorings:
* Use perf_data_file methods to write output file in 'record' and
'inject' (Jiri Olsa)
* Use pr_*() functions where applicable in 'report' (Namhyumg Kim)
* Add 'machine' 'addr_location' struct to have full picture (machine,
thread, map, symbol, addr) for a (partially) resolved address, reducing
function signatures (Arnaldo Carvalho de Melo)
* Reduce code duplication in the histogram entry creation/insertion. (Arnaldo Carvalho de Melo)
* Auto allocate annotation histogram data structures, (Arnaldo Carvalho de Melo)
* No need to test against NULL before calling free, also set
freed memory in struct pointers to NULL, to help fixing use after
free bugs. (Arnaldo Carvalho de Melo>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r-- | tools/perf/builtin-record.c | 94 |
1 files changed, 41 insertions, 53 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index c1c1200d2f0a..6ec0cbc2a5d5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -62,9 +62,9 @@ static void __handle_on_exit_funcs(void) } #endif -struct perf_record { +struct record { struct perf_tool tool; - struct perf_record_opts opts; + struct record_opts opts; u64 bytes_written; struct perf_data_file file; struct perf_evlist *evlist; @@ -76,24 +76,14 @@ struct perf_record { long samples; }; -static int perf_record__write(struct perf_record *rec, void *buf, size_t size) +static int record__write(struct record *rec, void *bf, size_t size) { - struct perf_data_file *file = &rec->file; - - while (size) { - ssize_t ret = write(file->fd, buf, size); - - if (ret < 0) { - pr_err("failed to write perf data, error: %m\n"); - return -1; - } - - size -= ret; - buf += ret; - - rec->bytes_written += ret; + if (perf_data_file__write(rec->session->file, bf, size) < 0) { + pr_err("failed to write perf data, error: %m\n"); + return -1; } + rec->bytes_written += size; return 0; } @@ -102,12 +92,11 @@ static int process_synthesized_event(struct perf_tool *tool, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - struct perf_record *rec = container_of(tool, struct perf_record, tool); - return perf_record__write(rec, event, event->header.size); + struct record *rec = container_of(tool, struct record, tool); + return record__write(rec, event, event->header.size); } -static int perf_record__mmap_read(struct perf_record *rec, - struct perf_mmap *md) +static int record__mmap_read(struct record *rec, struct perf_mmap *md) { unsigned int head = perf_mmap__read_head(md); unsigned int old = md->prev; @@ -128,7 +117,7 @@ static int perf_record__mmap_read(struct perf_record *rec, size = md->mask + 1 - (old & md->mask); old += size; - if (perf_record__write(rec, buf, size) < 0) { + if (record__write(rec, buf, size) < 0) { rc = -1; goto out; } @@ -138,7 +127,7 @@ static int perf_record__mmap_read(struct perf_record *rec, size = head - old; old += size; - if (perf_record__write(rec, buf, size) < 0) { + if (record__write(rec, buf, size) < 0) { rc = -1; goto out; } @@ -163,9 +152,9 @@ static void sig_handler(int sig) signr = sig; } -static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) +static void record__sig_exit(int exit_status __maybe_unused, void *arg) { - struct perf_record *rec = arg; + struct record *rec = arg; int status; if (rec->evlist->workload.pid > 0) { @@ -183,13 +172,13 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) signal(signr, SIG_DFL); } -static int perf_record__open(struct perf_record *rec) +static int record__open(struct record *rec) { char msg[512]; struct perf_evsel *pos; struct perf_evlist *evlist = rec->evlist; struct perf_session *session = rec->session; - struct perf_record_opts *opts = &rec->opts; + struct record_opts *opts = &rec->opts; int rc = 0; perf_evlist__config(evlist, opts); @@ -239,7 +228,7 @@ out: return rc; } -static int process_buildids(struct perf_record *rec) +static int process_buildids(struct record *rec) { struct perf_data_file *file = &rec->file; struct perf_session *session = rec->session; @@ -254,9 +243,9 @@ static int process_buildids(struct perf_record *rec) size, &build_id__mark_dso_hit_ops); } -static void perf_record__exit(int status, void *arg) +static void record__exit(int status, void *arg) { - struct perf_record *rec = arg; + struct record *rec = arg; struct perf_data_file *file = &rec->file; if (status != 0) @@ -312,14 +301,14 @@ static struct perf_event_header finished_round_event = { .type = PERF_RECORD_FINISHED_ROUND, }; -static int perf_record__mmap_read_all(struct perf_record *rec) +static int record__mmap_read_all(struct record *rec) { int i; int rc = 0; for (i = 0; i < rec->evlist->nr_mmaps; i++) { if (rec->evlist->mmap[i].base) { - if (perf_record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { + if (record__mmap_read(rec, &rec->evlist->mmap[i]) != 0) { rc = -1; goto out; } @@ -327,14 +316,13 @@ static int perf_record__mmap_read_all(struct perf_record *rec) } if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA)) - rc = perf_record__write(rec, &finished_round_event, - sizeof(finished_round_event)); + rc = record__write(rec, &finished_round_event, sizeof(finished_round_event)); out: return rc; } -static void perf_record__init_features(struct perf_record *rec) +static void record__init_features(struct record *rec) { struct perf_evlist *evsel_list = rec->evlist; struct perf_session *session = rec->session; @@ -353,14 +341,14 @@ static void perf_record__init_features(struct perf_record *rec) perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); } -static int __cmd_record(struct perf_record *rec, int argc, const char **argv) +static int __cmd_record(struct record *rec, int argc, const char **argv) { int err; unsigned long waking = 0; const bool forks = argc > 0; struct machine *machine; struct perf_tool *tool = &rec->tool; - struct perf_record_opts *opts = &rec->opts; + struct record_opts *opts = &rec->opts; struct perf_evlist *evsel_list = rec->evlist; struct perf_data_file *file = &rec->file; struct perf_session *session; @@ -368,7 +356,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) rec->progname = argv[0]; - on_exit(perf_record__sig_exit, rec); + on_exit(record__sig_exit, rec); signal(SIGCHLD, sig_handler); signal(SIGINT, sig_handler); signal(SIGUSR1, sig_handler); @@ -382,7 +370,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) rec->session = session; - perf_record__init_features(rec); + record__init_features(rec); if (forks) { err = perf_evlist__prepare_workload(evsel_list, &opts->target, @@ -394,7 +382,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) } } - if (perf_record__open(rec) != 0) { + if (record__open(rec) != 0) { err = -1; goto out_delete_session; } @@ -403,9 +391,9 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) perf_header__clear_feat(&session->header, HEADER_GROUP_DESC); /* - * perf_session__delete(session) will be called at perf_record__exit() + * perf_session__delete(session) will be called at record__exit() */ - on_exit(perf_record__exit, rec); + on_exit(record__exit, rec); if (file->is_pipe) { err = perf_header__write_pipe(file->fd); @@ -510,7 +498,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) for (;;) { int hits = rec->samples; - if (perf_record__mmap_read_all(rec) < 0) { + if (record__mmap_read_all(rec) < 0) { err = -1; goto out_delete_session; } @@ -669,7 +657,7 @@ static int get_stack_size(char *str, unsigned long *_size) } #endif /* HAVE_LIBUNWIND_SUPPORT */ -int record_parse_callchain(const char *arg, struct perf_record_opts *opts) +int record_parse_callchain(const char *arg, struct record_opts *opts) { char *tok, *name, *saveptr = NULL; char *buf; @@ -725,7 +713,7 @@ int record_parse_callchain(const char *arg, struct perf_record_opts *opts) return ret; } -static void callchain_debug(struct perf_record_opts *opts) +static void callchain_debug(struct record_opts *opts) { pr_debug("callchain: type %d\n", opts->call_graph); @@ -738,7 +726,7 @@ int record_parse_callchain_opt(const struct option *opt, const char *arg, int unset) { - struct perf_record_opts *opts = opt->value; + struct record_opts *opts = opt->value; int ret; /* --no-call-graph */ @@ -759,7 +747,7 @@ int record_callchain_opt(const struct option *opt, const char *arg __maybe_unused, int unset __maybe_unused) { - struct perf_record_opts *opts = opt->value; + struct record_opts *opts = opt->value; if (opts->call_graph == CALLCHAIN_NONE) opts->call_graph = CALLCHAIN_FP; @@ -775,8 +763,8 @@ static const char * const record_usage[] = { }; /* - * XXX Ideally would be local to cmd_record() and passed to a perf_record__new - * because we need to have access to it in perf_record__exit, that is called + * XXX Ideally would be local to cmd_record() and passed to a record__new + * because we need to have access to it in record__exit, that is called * after cmd_record() exits, but since record_options need to be accessible to * builtin-script, leave it here. * @@ -784,7 +772,7 @@ static const char * const record_usage[] = { * * Just say no to tons of global variables, sigh. */ -static struct perf_record record = { +static struct record record = { .opts = { .mmap_pages = UINT_MAX, .user_freq = UINT_MAX, @@ -808,7 +796,7 @@ const char record_callchain_help[] = CALLCHAIN_HELP "fp"; /* * XXX Will stay a global variable till we fix builtin-script.c to stop messing * with it and switch to use the library functions in perf_evlist that came - * from builtin-record.c, i.e. use perf_record_opts, + * from builtin-record.c, i.e. use record_opts, * perf_evlist__prepare_workload, etc instead of fork+exec'in 'perf record', * using pipes, etc. */ @@ -891,7 +879,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) { int err = -ENOMEM; struct perf_evlist *evsel_list; - struct perf_record *rec = &record; + struct record *rec = &record; char errbuf[BUFSIZ]; evsel_list = perf_evlist__new(); @@ -956,7 +944,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) if (perf_evlist__create_maps(evsel_list, &rec->opts.target) < 0) usage_with_options(record_usage, record_options); - if (perf_record_opts__config(&rec->opts)) { + if (record_opts__config(&rec->opts)) { err = -EINVAL; goto out_free_fd; } |