From f2f4fe4410ac6de96f8561aefeadbb680e5ddc99 Mon Sep 17 00:00:00 2001 From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Date: Fri, 24 Jun 2016 17:23:55 +0530 Subject: [PATCH 01/17] perf annotate: Remove unused hist_entry__annotate function hist_entry__annotate looks part of API but I don't find any caller of this function. Removing it. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Anton Blanchard <anton@ozlabs.org> Cc: Daniel Axtens <dja@axtens.net> Cc: Michael Ellerman <mpe@ellerman.id.au> Link: http://lkml.kernel.org/r/1466769240-12376-2-git-send-email-ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/annotate.c | 5 ----- tools/perf/util/annotate.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7e5a1e8874cee..b2c7ae465465b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1676,11 +1676,6 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map, return 0; } -int hist_entry__annotate(struct hist_entry *he, size_t privsize) -{ - return symbol__annotate(he->ms.sym, he->ms.map, privsize); -} - bool ui__has_annotation(void) { return use_browser == 1 && perf_hpp_list.sym; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 9241f8c2b7e16..82f3781138f90 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -156,8 +156,6 @@ void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize); -int hist_entry__annotate(struct hist_entry *he, size_t privsize); - int symbol__annotate_init(struct map *map, struct symbol *sym); int symbol__annotate_printf(struct symbol *sym, struct map *map, struct perf_evsel *evsel, bool full_paths, From 9f776ba11c8be311a5c23777bc9f3b96498cc6cc Mon Sep 17 00:00:00 2001 From: Neeraj Badlani <neerajbadlani@gmail.com> Date: Mon, 27 Jun 2016 06:59:57 -0700 Subject: [PATCH 02/17] perf tools: Update makefile message for installing slang devel package In case of missing library (libslang), give hint to install library (libslang2-dev), since libslang-dev is not provided by Ubuntu. Signed-off-by: Neeraj Badlani <neerajbadlani@gmail.com> Link: http://lkml.kernel.org/r/1467035997-9100-1-git-send-email-neerajbadlani@gmail.com [ removed excessive 'or' usage ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 534c81176f6cd..bf1a0a0dd0ada 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -482,7 +482,7 @@ endif ifndef NO_SLANG ifneq ($(feature-libslang), 1) - msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev); + msg := $(warning slang not found, disables TUI support. Please install slang-devel, libslang-dev or libslang2-dev); NO_SLANG := 1 else # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h From 6ef9492915b09816c75bb41e7e37b2e507d2f70f Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com> Date: Fri, 24 Jun 2016 17:23:58 +0530 Subject: [PATCH 03/17] perf annotate: Generalize handling of 'ret' instructions Introduce helper to detect 'ret' instructions and use the same in the TUI. A helper is needed since some architectures such as powerpc have more than one return instruction. Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Anton Blanchard <anton@ozlabs.org> Cc: Daniel Axtens <dja@axtens.net> Cc: Michael Ellerman <mpe@ellerman.id.au> Link: http://lkml.kernel.org/r/1466769240-12376-5-git-send-email-ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/ui/browsers/annotate.c | 20 +++++++++----------- tools/perf/util/annotate.c | 10 ++++++++++ tools/perf/util/annotate.h | 1 + 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 0e106bb975251..29dc6d20364e8 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -223,16 +223,14 @@ static void annotate_browser__write(struct ui_browser *browser, void *entry, int } else if (ins__is_call(dl->ins)) { ui_browser__write_graph(browser, SLSMG_RARROW_CHAR); SLsmg_write_char(' '); + } else if (ins__is_ret(dl->ins)) { + ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); + SLsmg_write_char(' '); } else { ui_browser__write_nstring(browser, " ", 2); } } else { - if (strcmp(dl->name, "retq")) { - ui_browser__write_nstring(browser, " ", 2); - } else { - ui_browser__write_graph(browser, SLSMG_LARROW_CHAR); - SLsmg_write_char(' '); - } + ui_browser__write_nstring(browser, " ", 2); } disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset); @@ -843,14 +841,14 @@ static int annotate_browser__run(struct annotate_browser *browser, ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); else if (browser->selection->offset == -1) ui_helpline__puts("Actions are only available for assembly lines."); - else if (!browser->selection->ins) { - if (strcmp(browser->selection->name, "retq")) - goto show_sup_ins; + else if (!browser->selection->ins) + goto show_sup_ins; + else if (ins__is_ret(browser->selection->ins)) goto out; - } else if (!(annotate_browser__jump(browser) || + else if (!(annotate_browser__jump(browser) || annotate_browser__callq(browser, evsel, hbt))) { show_sup_ins: - ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions."); + ui_helpline__puts("Actions are only available for function call/return & jump/branch instructions."); } continue; case 't': diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index b2c7ae465465b..c385fecb9d324 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -354,6 +354,15 @@ static struct ins_ops nop_ops = { .scnprintf = nop__scnprintf, }; +static struct ins_ops ret_ops = { + .scnprintf = ins__raw_scnprintf, +}; + +bool ins__is_ret(const struct ins *ins) +{ + return ins->ops == &ret_ops; +} + static struct ins instructions[] = { { .name = "add", .ops = &mov_ops, }, { .name = "addl", .ops = &mov_ops, }, @@ -444,6 +453,7 @@ static struct ins instructions[] = { { .name = "xadd", .ops = &mov_ops, }, { .name = "xbeginl", .ops = &jump_ops, }, { .name = "xbeginq", .ops = &jump_ops, }, + { .name = "retq", .ops = &ret_ops, }, }; static int ins__key_cmp(const void *name, const void *insp) diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 82f3781138f90..a23084f54128e 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -48,6 +48,7 @@ struct ins { bool ins__is_jump(const struct ins *ins); bool ins__is_call(const struct ins *ins); +bool ins__is_ret(const struct ins *ins); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); struct annotation; From 78f69b5865dbb7cc87fe18fb98212e23b10b5cbd Mon Sep 17 00:00:00 2001 From: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Date: Fri, 24 Jun 2016 17:24:00 +0530 Subject: [PATCH 04/17] perf tools: Add more toolchain triplets Add few more triplets based on Fedora and Ubuntu binutils (cross tools). Before applying patch on x86: ( Install binutils-powerpc64-linux-gnu.x86_64 ) $ perf report -i perf.data.powerpc --vmlinux vmlinux.powerpc \ --objdump powerpc64-linux-gnu-objdump After applying patch on x86: $ perf report -i perf.data.powerpc --vmlinux vmlinux.powerpc I.e. it will find the right objdump from the environment data recorded in the perf.data file + these triplets. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Anton Blanchard <anton@ozlabs.org> Cc: Daniel Axtens <dja@axtens.net> Cc: Michael Ellerman <mpe@ellerman.id.au> Link: http://lkml.kernel.org/r/1466769240-12376-7-git-send-email-ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/arch/common.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index fa090a9eaa388..ee6966812a5a4 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -9,34 +9,44 @@ const char *const arm_triplets[] = { "arm-unknown-linux-", "arm-unknown-linux-gnu-", "arm-unknown-linux-gnueabi-", + "arm-linux-gnu-", + "arm-linux-gnueabihf-", + "arm-none-eabi-", NULL }; const char *const arm64_triplets[] = { "aarch64-linux-android-", + "aarch64-linux-gnu-", NULL }; const char *const powerpc_triplets[] = { "powerpc-unknown-linux-gnu-", "powerpc64-unknown-linux-gnu-", + "powerpc64-linux-gnu-", + "powerpc64le-linux-gnu-", NULL }; const char *const s390_triplets[] = { "s390-ibm-linux-", + "s390x-linux-gnu-", NULL }; const char *const sh_triplets[] = { "sh-unknown-linux-gnu-", "sh64-unknown-linux-gnu-", + "sh-linux-gnu-", + "sh64-linux-gnu-", NULL }; const char *const sparc_triplets[] = { "sparc-unknown-linux-gnu-", "sparc64-unknown-linux-gnu-", + "sparc64-linux-gnu-", NULL }; @@ -49,12 +59,19 @@ const char *const x86_triplets[] = { "i386-pc-linux-gnu-", "i686-linux-android-", "i686-android-linux-", + "x86_64-linux-gnu-", + "i586-linux-gnu-", NULL }; const char *const mips_triplets[] = { "mips-unknown-linux-gnu-", "mipsel-linux-android-", + "mips-linux-gnu-", + "mips64-linux-gnu-", + "mips64el-linux-gnuabi64-", + "mips64-linux-gnuabi64-", + "mipsel-linux-gnu-", NULL }; From f5ce45736b5036e73e7ffa800a1137ad778d186e Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Sat, 25 Jun 2016 01:41:58 +0000 Subject: [PATCH 05/17] perf build: Add libbabeltrace to build-test 'make build-test' doesn't test LIBBABELTRACE=1. It misses a building failure caused by commit 41840d211c51 ("perf config: Move config declarations from util/cache.h to util/config.h"), breaks bisect. Add LIBBABELTRACE=1 to build-test. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466818918-131281-1-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/tests/make | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index cac15d93aea65..51966d92fc829 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -81,6 +81,7 @@ make_no_libbionic := NO_LIBBIONIC=1 make_no_auxtrace := NO_AUXTRACE=1 make_no_libbpf := NO_LIBBPF=1 make_no_libcrypto := NO_LIBCRYPTO=1 +make_with_babeltrace:= LIBBABELTRACE=1 make_tags := tags make_cscope := cscope make_help := help @@ -136,6 +137,7 @@ run += make_no_libaudit run += make_no_libbionic run += make_no_auxtrace run += make_no_libbpf +run += make_with_babeltrace run += make_help run += make_doc run += make_perf_o From f6c12a004c149a7b0ea1332fa715979888dd4695 Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@kernel.org> Date: Fri, 24 Jun 2016 14:40:24 +0200 Subject: [PATCH 06/17] perf data convert: Include config.h header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise some compiler might scream: $ make LIBBABELTRACE_DIR=/opt/libbabeltrace/ LIBBABELTRACE=1 BUILD: Doing 'make -j4' parallel build CC util/data-convert-bt.o util/data-convert-bt.c: In function ‘convert__config’: util/data-convert-bt.c:1299:19: error: implicit declaration of function ‘perf_config_u64’ [-Werror=implicit-function-declaration] c->queue_size = perf_config_u64(var, value); ... Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: He Kuang <hekuang@huawei.com> Cc: Marc Kleine-Budde <mkl@pengutronix.de> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Taeung Song <treeze.taeung@gmail.com> Cc: Wang Nan <wangnan0@huawei.com> Fixes: 41840d211c51 ("perf config: Move config declarations from util/cache.h to util/config.h") Link: http://lkml.kernel.org/r/1466772025-17471-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/data-convert-bt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 4b59879391c07..7b1bc24c382ef 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -26,6 +26,7 @@ #include "evlist.h" #include "evsel.h" #include "machine.h" +#include "config.h" #define pr_N(n, fmt, ...) \ eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) From cda57a8c74aa326cbb1a1e2f7d30f8c76983e70c Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Mon, 27 Jun 2016 10:24:03 +0000 Subject: [PATCH 07/17] perf record: Move mmap setup block to separate function Following commits introduce multiple evlists to record. This patch extracts perf_evlist__mmap_ex() processing to a new function, creates record__mmap() and record__mmap_evlist() to wrap perf_evlist__mmap_ex() and its error processing. They will be improvemented to create mmap for all evlists. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Nilay Vaish <nilayvaish@gmail.com> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1467023052-146749-2-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-record.c | 56 ++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 20 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 81411b14df4ca..7eb8d7d29fbc2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -342,6 +342,40 @@ int auxtrace_record__snapshot_start(struct auxtrace_record *itr __maybe_unused) #endif +static int record__mmap_evlist(struct record *rec, + struct perf_evlist *evlist) +{ + struct record_opts *opts = &rec->opts; + char msg[512]; + + if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, + opts->auxtrace_mmap_pages, + opts->auxtrace_snapshot_mode) < 0) { + if (errno == EPERM) { + pr_err("Permission error mapping pages.\n" + "Consider increasing " + "/proc/sys/kernel/perf_event_mlock_kb,\n" + "or try again with a smaller value of -m/--mmap_pages.\n" + "(current value: %u,%u)\n", + opts->mmap_pages, opts->auxtrace_mmap_pages); + return -errno; + } else { + pr_err("failed to mmap with %d (%s)\n", errno, + strerror_r(errno, msg, sizeof(msg))); + if (errno) + return -errno; + else + return -EINVAL; + } + } + return 0; +} + +static int record__mmap(struct record *rec) +{ + return record__mmap_evlist(rec, rec->evlist); +} + static int record__open(struct record *rec) { char msg[512]; @@ -378,27 +412,9 @@ static int record__open(struct record *rec) goto out; } - if (perf_evlist__mmap_ex(evlist, opts->mmap_pages, false, - opts->auxtrace_mmap_pages, - opts->auxtrace_snapshot_mode) < 0) { - if (errno == EPERM) { - pr_err("Permission error mapping pages.\n" - "Consider increasing " - "/proc/sys/kernel/perf_event_mlock_kb,\n" - "or try again with a smaller value of -m/--mmap_pages.\n" - "(current value: %u,%u)\n", - opts->mmap_pages, opts->auxtrace_mmap_pages); - rc = -errno; - } else { - pr_err("failed to mmap with %d (%s)\n", errno, - strerror_r(errno, msg, sizeof(msg))); - if (errno) - rc = -errno; - else - rc = -EINVAL; - } + rc = record__mmap(rec); + if (rc) goto out; - } session->evlist = evlist; perf_session__set_id_hdr_size(session); From cb21686b7d37776cfd34793f08d6466ce9091a7d Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Mon, 27 Jun 2016 10:24:04 +0000 Subject: [PATCH 08/17] perf record: Prepare reading from multiple evlists in record__mmap_read_all() Following commits introduce new evlists to record. This patch adjusts record__mmap_read_all() and record__mmap_read(): converting original record__mmap_read_all() to record__mmap_read_evlist(), read from one evlist; makes record__mmap_read() reading from specific evlist. record__mmap_read_all() will be improved to read from multiple evlists. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Nilay Vaish <nilayvaish@gmail.com> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1467023052-146749-3-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-record.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 7eb8d7d29fbc2..18e9abc90759a 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -132,9 +132,9 @@ rb_find_range(struct perf_evlist *evlist, return backward_rb_find_range(data, mask, head, start, end); } -static int record__mmap_read(struct record *rec, int idx) +static int record__mmap_read(struct record *rec, struct perf_evlist *evlist, int idx) { - struct perf_mmap *md = &rec->evlist->mmap[idx]; + struct perf_mmap *md = &evlist->mmap[idx]; u64 head = perf_mmap__read_head(md); u64 old = md->prev; u64 end = head, start = old; @@ -143,7 +143,7 @@ static int record__mmap_read(struct record *rec, int idx) void *buf; int rc = 0; - if (rb_find_range(rec->evlist, data, md->mask, head, + if (rb_find_range(evlist, data, md->mask, head, old, &start, &end)) return -1; @@ -157,7 +157,7 @@ static int record__mmap_read(struct record *rec, int idx) WARN_ONCE(1, "failed to keep up with mmap data. (warn only once)\n"); md->prev = head; - perf_evlist__mmap_consume(rec->evlist, idx); + perf_evlist__mmap_consume(evlist, idx); return 0; } @@ -182,7 +182,7 @@ static int record__mmap_read(struct record *rec, int idx) } md->prev = head; - perf_evlist__mmap_consume(rec->evlist, idx); + perf_evlist__mmap_consume(evlist, idx); out: return rc; } @@ -498,17 +498,20 @@ static struct perf_event_header finished_round_event = { .type = PERF_RECORD_FINISHED_ROUND, }; -static int record__mmap_read_all(struct record *rec) +static int record__mmap_read_evlist(struct record *rec, struct perf_evlist *evlist) { u64 bytes_written = rec->bytes_written; int i; int rc = 0; - for (i = 0; i < rec->evlist->nr_mmaps; i++) { - struct auxtrace_mmap *mm = &rec->evlist->mmap[i].auxtrace_mmap; + if (!evlist) + return 0; + + for (i = 0; i < evlist->nr_mmaps; i++) { + struct auxtrace_mmap *mm = &evlist->mmap[i].auxtrace_mmap; - if (rec->evlist->mmap[i].base) { - if (record__mmap_read(rec, i) != 0) { + if (evlist->mmap[i].base) { + if (record__mmap_read(rec, evlist, i) != 0) { rc = -1; goto out; } @@ -532,6 +535,17 @@ static int record__mmap_read_all(struct record *rec) return rc; } +static int record__mmap_read_all(struct record *rec) +{ + int err; + + err = record__mmap_read_evlist(rec, rec->evlist); + if (err) + return err; + + return err; +} + static void record__init_features(struct record *rec) { struct perf_session *session = rec->session; From ee667f947c926eda1b8d6eccd0894bfbed75b6e3 Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Mon, 27 Jun 2016 10:24:05 +0000 Subject: [PATCH 09/17] perf record: Prepare picking perf_event_mmap_page from multiple evlists Following commits introduce new evlists to record. This patch adjusts record__pick_pc() and introduces perf_evlist__pick_pc() to read control page from one specific evlist. record__pick_pc() will be improved to search control page from multiple evlists. Signed-off-by: Wang Nan <wangnan0@huawei.com> Cc: He Kuang <hekuang@huawei.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Nilay Vaish <nilayvaish@gmail.com> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1467023052-146749-4-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-record.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 18e9abc90759a..b2b3b600adf53 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -686,10 +686,21 @@ perf_event__synth_time_conv(const struct perf_event_mmap_page *pc __maybe_unused return 0; } +static const struct perf_event_mmap_page * +perf_evlist__pick_pc(struct perf_evlist *evlist) +{ + if (evlist && evlist->mmap && evlist->mmap[0].base) + return evlist->mmap[0].base; + return NULL; +} + static const struct perf_event_mmap_page *record__pick_pc(struct record *rec) { - if (rec->evlist && rec->evlist->mmap && rec->evlist->mmap[0].base) - return rec->evlist->mmap[0].base; + const struct perf_event_mmap_page *pc; + + pc = perf_evlist__pick_pc(rec->evlist); + if (pc) + return pc; return NULL; } From ed7b630b310775f3b6c0b360ede7a12cd8dff6fe Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Fri, 24 Jun 2016 14:40:25 +0200 Subject: [PATCH 10/17] perf symbols: Use proper dso name for is_regular_file Marc reported use of uninitialized memory: > In commit "403567217d3f perf symbols: Do not read symbols/data from > device files" a check to uninitialzied memory was added. This leads to > the following valgrind output: > > ==24515== Syscall param stat(file_name) points to uninitialised byte(s) > ==24515== at 0x75B26D5: _xstat (in /lib/x86_64-linux-gnu/libc-2.22.so) > ==24515== by 0x4E548D: stat (stat.h:454) > ==24515== by 0x4E548D: is_regular_file (util.c:687) > ==24515== by 0x4A5BEE: dso__load (symbol.c:1435) > ==24515== by 0x4BB1AE: map__load (map.c:289) > ==24515== by 0x4BB1AE: map__find_symbol (map.c:333) > ==24515== by 0x4835B3: thread__find_addr_location (event.c:1300) > ==24515== by 0x4B5342: add_callchain_ip (machine.c:1652) > ==24515== by 0x4B5342: thread__resolve_callchain_sample (machine.c:1906) > ==24515== by 0x4B9E7D: thread__resolve_callchain (machine.c:1958) > ==24515== by 0x441B3E: process_event (builtin-script.c:795) > ==24515== by 0x441B3E: process_sample_event (builtin-script.c:920) > ==24515== by 0x4BEE29: perf_evlist__deliver_sample (session.c:1192) > ==24515== by 0x4BEE29: machines__deliver_event (session.c:1229) > ==24515== by 0x4BF770: perf_session__deliver_event (session.c:1286) > ==24515== by 0x4BF770: ordered_events__deliver_event (session.c:114) > ==24515== by 0x4C1D17: __ordered_events__flush (ordered-events.c:207) > ==24515== by 0x4C1D17: ordered_events__flush.part.3 (ordered-events.c:274) > ==24515== by 0x4BF44C: perf_session__process_user_event (session.c:1325) > ==24515== by 0x4BF44C: perf_session__process_event (session.c:1451) > ==24515== Address 0x807c6a0 is 0 bytes inside a block of size 4,096 alloc'd > ==24515== at 0x4C29C0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==24515== by 0x4A5BCB: dso__load (symbol.c:1421) > ==24515== by 0x4BB1AE: map__load (map.c:289) > ==24515== by 0x4BB1AE: map__find_symbol (map.c:333) > ==24515== by 0x4835B3: thread__find_addr_location (event.c:1300) > ==24515== by 0x4B5342: add_callchain_ip (machine.c:1652) > ==24515== by 0x4B5342: thread__resolve_callchain_sample (machine.c:1906) > ==24515== by 0x4B9E7D: thread__resolve_callchain (machine.c:1958) > ==24515== by 0x441B3E: process_event (builtin-script.c:795) > ==24515== by 0x441B3E: process_sample_event (builtin-script.c:920) > ==24515== by 0x4BEE29: perf_evlist__deliver_sample (session.c:1192) > ==24515== by 0x4BEE29: machines__deliver_event (session.c:1229) > ==24515== by 0x4BF770: perf_session__deliver_event (session.c:1286) > ==24515== by 0x4BF770: ordered_events__deliver_event (session.c:114) > ==24515== by 0x4C1D17: __ordered_events__flush (ordered-events.c:207) > ==24515== by 0x4C1D17: ordered_events__flush.part.3 (ordered-events.c:274) > ==24515== by 0x4BF44C: perf_session__process_user_event (session.c:1325) > ==24515== by 0x4BF44C: perf_session__process_event (session.c:1451) > ==24515== by 0x4C0EAC: __perf_session__process_events (session.c:1804) > ==24515== by 0x4C0EAC: perf_session__process_events (session.c:1858) The reason was a typo that passed global 'name' variable as the is_regular_file argument instead dso->long_name. Reported-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Acked-by: Marc Kleine-Budde <mkl@pengutronix.de> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Wang Nan <wangnan0@huawei.com> Fixes: 403567217d3f ("perf symbols: Do not read symbols/data from device files") Link: http://lkml.kernel.org/r/1466772025-17471-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b044f1a32d163..37e8d20ae03e2 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1430,7 +1430,7 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) * Read the build id if possible. This is required for * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work */ - if (is_regular_file(name) && + if (is_regular_file(dso->long_name) && filename__read_build_id(dso->long_name, build_id, BUILD_ID_SIZE) > 0) dso__set_build_id(dso, build_id); From 069ee5c488d161f539bb897b1bc64b83f9773221 Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:06 +0000 Subject: [PATCH 11/17] perf data ctf: Add value_set_string() helper There are many value_set_##x helper for integer, but only for integer. This patch adds value_set_string() helper to help following commits create string fields. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-2-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/data-convert-bt.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 7b1bc24c382ef..4b68e7b9ee0c8 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -141,6 +141,36 @@ FUNC_VALUE_SET(s64) FUNC_VALUE_SET(u64) __FUNC_VALUE_SET(u64_hex, u64) +static int string_set_value(struct bt_ctf_field *field, const char *string); +static __maybe_unused int +value_set_string(struct ctf_writer *cw, struct bt_ctf_event *event, + const char *name, const char *string) +{ + struct bt_ctf_field_type *type = cw->data.string; + struct bt_ctf_field *field; + int ret = 0; + + field = bt_ctf_field_create(type); + if (!field) { + pr_err("failed to create a field %s\n", name); + return -1; + } + + ret = string_set_value(field, string); + if (ret) { + pr_err("failed to set value %s\n", name); + goto err_put_field; + } + + ret = bt_ctf_event_set_payload(event, name, field); + if (ret) + pr_err("failed to set payload %s\n", name); + +err_put_field: + bt_ctf_field_put(field); + return ret; +} + static struct bt_ctf_field_type* get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field) { From 3275f68e50290acd04612c6af41173fe83fdf4b0 Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:07 +0000 Subject: [PATCH 12/17] perf data ctf: Pass convert options through opts structure Following commits will add new option to 'perf data convert'. All options should be grouped into a structure and passed to low level converter (currently there's only one converter). Introduce data-convert.h and define 'struct perf_data_convert_opts' in it. Pass 'force' through opts. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-3-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-data.c | 9 ++++++--- tools/perf/util/data-convert-bt.c | 5 +++-- tools/perf/util/data-convert-bt.h | 4 +++- tools/perf/util/data-convert.h | 8 ++++++++ 4 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 tools/perf/util/data-convert.h diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index b97bc1518b44a..38111a97d9000 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -3,6 +3,7 @@ #include "perf.h" #include "debug.h" #include <subcmd/parse-options.h> +#include "data-convert.h" #include "data-convert-bt.h" typedef int (*data_cmd_fn_t)(int argc, const char **argv, const char *prefix); @@ -53,14 +54,16 @@ static int cmd_data_convert(int argc, const char **argv, const char *prefix __maybe_unused) { const char *to_ctf = NULL; - bool force = false; + struct perf_data_convert_opts opts = { + .force = false, + }; const struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose"), OPT_STRING('i', "input", &input_name, "file", "input file name"), #ifdef HAVE_LIBBABELTRACE_SUPPORT OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"), #endif - OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), + OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"), OPT_END() }; @@ -78,7 +81,7 @@ static int cmd_data_convert(int argc, const char **argv, if (to_ctf) { #ifdef HAVE_LIBBABELTRACE_SUPPORT - return bt_convert__perf2ctf(input_name, to_ctf, force); + return bt_convert__perf2ctf(input_name, to_ctf, &opts); #else pr_err("The libbabeltrace support is not compiled in.\n"); return -1; diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 4b68e7b9ee0c8..09571b39f58aa 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -1304,13 +1304,14 @@ static int convert__config(const char *var, const char *value, void *cb) return 0; } -int bt_convert__perf2ctf(const char *input, const char *path, bool force) +int bt_convert__perf2ctf(const char *input, const char *path, + struct perf_data_convert_opts *opts) { struct perf_session *session; struct perf_data_file file = { .path = input, .mode = PERF_DATA_MODE_READ, - .force = force, + .force = opts->force, }; struct convert c = { .tool = { diff --git a/tools/perf/util/data-convert-bt.h b/tools/perf/util/data-convert-bt.h index 4c204342a9d83..9a3b587f76c19 100644 --- a/tools/perf/util/data-convert-bt.h +++ b/tools/perf/util/data-convert-bt.h @@ -1,8 +1,10 @@ #ifndef __DATA_CONVERT_BT_H #define __DATA_CONVERT_BT_H +#include "data-convert.h" #ifdef HAVE_LIBBABELTRACE_SUPPORT -int bt_convert__perf2ctf(const char *input_name, const char *to_ctf, bool force); +int bt_convert__perf2ctf(const char *input_name, const char *to_ctf, + struct perf_data_convert_opts *opts); #endif /* HAVE_LIBBABELTRACE_SUPPORT */ #endif /* __DATA_CONVERT_BT_H */ diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h new file mode 100644 index 0000000000000..97cfd36aab6fd --- /dev/null +++ b/tools/perf/util/data-convert.h @@ -0,0 +1,8 @@ +#ifndef __DATA_CONVERT_H +#define __DATA_CONVERT_H + +struct perf_data_convert_opts { + bool force; +}; + +#endif /* __DATA_CONVERT_H */ From f02a6489d1e181c6c2731e80ff37024a130c326a Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:08 +0000 Subject: [PATCH 13/17] perf data ctf: Add 'all' option If 'all' option is selected, 'perf data convert' should convert not only samples, but non-sample events such as comm and fork. Add this option in perf_data_convert_opts. Following commits will add cmdline option to select it. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-4-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-data.c | 1 + tools/perf/util/data-convert.h | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index 38111a97d9000..ddfe3ac4c7f77 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -56,6 +56,7 @@ static int cmd_data_convert(int argc, const char **argv, const char *to_ctf = NULL; struct perf_data_convert_opts opts = { .force = false, + .all = false, }; const struct option options[] = { OPT_INCR('v', "verbose", &verbose, "be more verbose"), diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h index 97cfd36aab6fd..5314962fe95bb 100644 --- a/tools/perf/util/data-convert.h +++ b/tools/perf/util/data-convert.h @@ -3,6 +3,7 @@ struct perf_data_convert_opts { bool force; + bool all; }; #endif /* __DATA_CONVERT_H */ From 8ee4c46c5ec2481dd18098c5604f791ff911d427 Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:09 +0000 Subject: [PATCH 14/17] perf data ctf: Prepare collect non-sample events Following commits are going to allow 'perf data convert' to collect not only samples, but also non-sample events like comm and fork. In this patch we count non-sample events using c.non_sample_count, and prepare to print number of both type of events like: # ~/perf data convert --all --to-ctf ./out.ctf [ perf data convert: Converted 'perf.data' into CTF data './out.ctf' ] [ perf data convert: Converted and wrote 0.846 MB (6508 samples, 686 non-samples) ] Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-5-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/data-convert-bt.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 09571b39f58aa..3b3ac7c143e1b 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -77,6 +77,7 @@ struct convert { u64 events_size; u64 events_count; + u64 non_sample_count; /* Ordered events configured queue size. */ u64 queue_size; @@ -1369,10 +1370,15 @@ int bt_convert__perf2ctf(const char *input, const char *path, file.path, path); fprintf(stderr, - "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n", + "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples", (double) c.events_size / 1024.0 / 1024.0, c.events_count); + if (!c.non_sample_count) + fprintf(stderr, ") ]\n"); + else + fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count); + cleanup_events(session); perf_session__delete(session); ctf_writer__cleanup(cw); From f5a08ceda55bee91f879d2ac19edeb4a8916d04f Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:10 +0000 Subject: [PATCH 15/17] perf data ctf: Generate comm event to CTF output If 'all' is selected, convert comm event to output CTF stream. setup_non_sample_events() is called if non_sample is selected. It creates a comm_class for comm event. Use macros to generate and process_comm_event and add_comm_event. These macros can be reused for other non-sample events. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-6-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/data-convert-bt.c | 110 ++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 3b3ac7c143e1b..5dd62ba07438a 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -69,6 +69,7 @@ struct ctf_writer { }; struct bt_ctf_field_type *array[6]; } data; + struct bt_ctf_event_class *comm_class; }; struct convert { @@ -763,6 +764,57 @@ static int process_sample_event(struct perf_tool *tool, return cs ? 0 : -1; } +#define __NON_SAMPLE_SET_FIELD(_name, _type, _field) \ +do { \ + ret = value_set_##_type(cw, event, #_field, _event->_name._field);\ + if (ret) \ + return -1; \ +} while(0) + +#define __FUNC_PROCESS_NON_SAMPLE(_name, body) \ +static int process_##_name##_event(struct perf_tool *tool, \ + union perf_event *_event, \ + struct perf_sample *sample, \ + struct machine *machine) \ +{ \ + struct convert *c = container_of(tool, struct convert, tool);\ + struct ctf_writer *cw = &c->writer; \ + struct bt_ctf_event_class *event_class = cw->_name##_class;\ + struct bt_ctf_event *event; \ + struct ctf_stream *cs; \ + int ret; \ + \ + c->non_sample_count++; \ + c->events_size += _event->header.size; \ + event = bt_ctf_event_create(event_class); \ + if (!event) { \ + pr_err("Failed to create an CTF event\n"); \ + return -1; \ + } \ + \ + bt_ctf_clock_set_time(cw->clock, sample->time); \ + body \ + cs = ctf_stream(cw, 0); \ + if (cs) { \ + if (is_flush_needed(cs)) \ + ctf_stream__flush(cs); \ + \ + cs->count++; \ + bt_ctf_stream_append_event(cs->stream, event); \ + } \ + bt_ctf_event_put(event); \ + \ + return perf_event__process_##_name(tool, _event, sample, machine);\ +} + +__FUNC_PROCESS_NON_SAMPLE(comm, + __NON_SAMPLE_SET_FIELD(comm, u32, pid); + __NON_SAMPLE_SET_FIELD(comm, u32, tid); + __NON_SAMPLE_SET_FIELD(comm, string, comm); +) +#undef __NON_SAMPLE_SET_FIELD +#undef __FUNC_PROCESS_NON_SAMPLE + /* If dup < 0, add a prefix. Else, add _dupl_X suffix. */ static char *change_name(char *name, char *orig_name, int dup) { @@ -1037,6 +1089,58 @@ static int setup_events(struct ctf_writer *cw, struct perf_session *session) return 0; } +#define __NON_SAMPLE_ADD_FIELD(t, n) \ + do { \ + pr2(" field '%s'\n", #n); \ + if (bt_ctf_event_class_add_field(event_class, cw->data.t, #n)) {\ + pr_err("Failed to add field '%s';\n", #n);\ + return -1; \ + } \ + } while(0) + +#define __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(_name, body) \ +static int add_##_name##_event(struct ctf_writer *cw) \ +{ \ + struct bt_ctf_event_class *event_class; \ + int ret; \ + \ + pr("Adding "#_name" event\n"); \ + event_class = bt_ctf_event_class_create("perf_" #_name);\ + if (!event_class) \ + return -1; \ + body \ + \ + ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);\ + if (ret) { \ + pr("Failed to add event class '"#_name"' into stream.\n");\ + return ret; \ + } \ + \ + cw->_name##_class = event_class; \ + bt_ctf_event_class_put(event_class); \ + return 0; \ +} + +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(comm, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(string, comm); +) + +#undef __NON_SAMPLE_ADD_FIELD +#undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS + +static int setup_non_sample_events(struct ctf_writer *cw, + struct perf_session *session __maybe_unused) +{ + int ret; + + ret = add_comm_event(cw); + if (ret) + return ret; + return 0; +} + static void cleanup_events(struct perf_session *session) { struct perf_evlist *evlist = session->evlist; @@ -1332,6 +1436,9 @@ int bt_convert__perf2ctf(const char *input, const char *path, struct ctf_writer *cw = &c.writer; int err = -1; + if (opts->all) + c.tool.comm = process_comm_event; + perf_config(convert__config, &c); /* CTF writer */ @@ -1356,6 +1463,9 @@ int bt_convert__perf2ctf(const char *input, const char *path, if (setup_events(cw, session)) goto free_session; + if (opts->all && setup_non_sample_events(cw, session)) + goto free_session; + if (setup_streams(cw, session)) goto free_session; From 9e1a7ea19f9f8e3e40c5ad1a5cc3615c1746ae7b Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:11 +0000 Subject: [PATCH 16/17] perf data ctf: Add '--all' option for 'perf data convert' After this patch, 'perf data convert' convert comm events to output CTF stream. Result: # perf record -a sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.378 MB perf.data (73 samples) ] # perf data convert --to-ctf ./out.ctf [ perf data convert: Converted 'perf.data' into CTF data './out.ctf' ] [ perf data convert: Converted and wrote 0.003 MB (73 samples) ] # babeltrace --clock-seconds ./out.ctf/ [10627.402515791] (+?.?????????) cycles:ppp: { cpu_id = 0 }, { perf_ip = 0xFFFFFFFF81065AF4, perf_tid = 0, perf_pid = 0, perf_period = 1 } [10627.402518972] (+0.000003181) cycles:ppp: { cpu_id = 0 }, { perf_ip = 0xFFFFFFFF81065AF4, perf_tid = 0, perf_pid = 0, perf_period = 1 } ... // only sample event is converted # perf data convert --all --to-ctf ./out.ctf [ perf data convert: Converted 'perf.data' into CTF data './out.ctf' ] [ perf data convert: Converted and wrote 0.023 MB (73 samples, 384 non-samples) ] # babeltrace --clock-seconds ./out.ctf/ [ 0.000000000] (+?.?????????) perf_comm: { cpu_id = 0 }, { pid = 1, tid = 1, comm = "init" } [ 0.000000000] (+0.000000000) perf_comm: { cpu_id = 0 }, { pid = 2, tid = 2, comm = "kthreadd" } [ 0.000000000] (+0.000000000) perf_comm: { cpu_id = 0 }, { pid = 3, tid = 3, comm = "ksoftirqd/0" } ... // comm events are converted [10627.402515791] (+10627.402515791) cycles:ppp: { cpu_id = 0 }, { perf_ip = 0xFFFFFFFF81065AF4, perf_tid = 0, perf_pid = 0, perf_period = 1 } [10627.402518972] (+0.000003181) cycles:ppp: { cpu_id = 0 }, { perf_ip = 0xFFFFFFFF81065AF4, perf_tid = 0, perf_pid = 0, perf_period = 1 } ... // samples are also converted Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-7-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-data.txt | 4 ++++ tools/perf/builtin-data.c | 1 + 2 files changed, 5 insertions(+) diff --git a/tools/perf/Documentation/perf-data.txt b/tools/perf/Documentation/perf-data.txt index be8fa1a0a97e4..f0796a47dfa30 100644 --- a/tools/perf/Documentation/perf-data.txt +++ b/tools/perf/Documentation/perf-data.txt @@ -34,6 +34,10 @@ OPTIONS for 'convert' --verbose:: Be more verbose (show counter open errors, etc). +--all:: + Convert all events, including non-sample events (comm, fork, ...), to output. + Default is off, only convert samples. + SEE ALSO -------- linkperf:perf[1] diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index ddfe3ac4c7f77..7ad6e17ac6b36 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -65,6 +65,7 @@ static int cmd_data_convert(int argc, const char **argv, OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"), #endif OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"), + OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"), OPT_END() }; From ebccba3fe0a02f622f80e6be0e8ecb1a9a3ed983 Mon Sep 17 00:00:00 2001 From: Wang Nan <wangnan0@huawei.com> Date: Fri, 24 Jun 2016 11:22:12 +0000 Subject: [PATCH 17/17] perf data ctf: Generate fork and exit events to CTF output If 'all' is selected, convert fork and exit events to output CTF stream. Signed-off-by: Wang Nan <wangnan0@huawei.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: Zefan Li <lizefan@huawei.com> Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1466767332-114472-8-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/data-convert-bt.c | 44 ++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 5dd62ba07438a..4f979bb27b6ce 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -70,6 +70,8 @@ struct ctf_writer { struct bt_ctf_field_type *array[6]; } data; struct bt_ctf_event_class *comm_class; + struct bt_ctf_event_class *exit_class; + struct bt_ctf_event_class *fork_class; }; struct convert { @@ -812,6 +814,21 @@ __FUNC_PROCESS_NON_SAMPLE(comm, __NON_SAMPLE_SET_FIELD(comm, u32, tid); __NON_SAMPLE_SET_FIELD(comm, string, comm); ) +__FUNC_PROCESS_NON_SAMPLE(fork, + __NON_SAMPLE_SET_FIELD(fork, u32, pid); + __NON_SAMPLE_SET_FIELD(fork, u32, ppid); + __NON_SAMPLE_SET_FIELD(fork, u32, tid); + __NON_SAMPLE_SET_FIELD(fork, u32, ptid); + __NON_SAMPLE_SET_FIELD(fork, u64, time); +) + +__FUNC_PROCESS_NON_SAMPLE(exit, + __NON_SAMPLE_SET_FIELD(fork, u32, pid); + __NON_SAMPLE_SET_FIELD(fork, u32, ppid); + __NON_SAMPLE_SET_FIELD(fork, u32, tid); + __NON_SAMPLE_SET_FIELD(fork, u32, ptid); + __NON_SAMPLE_SET_FIELD(fork, u64, time); +) #undef __NON_SAMPLE_SET_FIELD #undef __FUNC_PROCESS_NON_SAMPLE @@ -1127,6 +1144,22 @@ __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(comm, __NON_SAMPLE_ADD_FIELD(string, comm); ) +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(fork, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, ppid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(u32, ptid); + __NON_SAMPLE_ADD_FIELD(u64, time); +) + +__FUNC_ADD_NON_SAMPLE_EVENT_CLASS(exit, + __NON_SAMPLE_ADD_FIELD(u32, pid); + __NON_SAMPLE_ADD_FIELD(u32, ppid); + __NON_SAMPLE_ADD_FIELD(u32, tid); + __NON_SAMPLE_ADD_FIELD(u32, ptid); + __NON_SAMPLE_ADD_FIELD(u64, time); +) + #undef __NON_SAMPLE_ADD_FIELD #undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS @@ -1136,6 +1169,12 @@ static int setup_non_sample_events(struct ctf_writer *cw, int ret; ret = add_comm_event(cw); + if (ret) + return ret; + ret = add_exit_event(cw); + if (ret) + return ret; + ret = add_fork_event(cw); if (ret) return ret; return 0; @@ -1436,8 +1475,11 @@ int bt_convert__perf2ctf(const char *input, const char *path, struct ctf_writer *cw = &c.writer; int err = -1; - if (opts->all) + if (opts->all) { c.tool.comm = process_comm_event; + c.tool.exit = process_exit_event; + c.tool.fork = process_fork_event; + } perf_config(convert__config, &c);