From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760935AbbA3KXN (ORCPT ); Fri, 30 Jan 2015 05:23:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49094 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760827AbbA3KWr (ORCPT ); Fri, 30 Jan 2015 05:22:47 -0500 From: Jiri Olsa To: linux-kernel@vger.kernel.org Cc: Jiri Olsa , Corey Ashford , David Ahern , Frederic Weisbecker , Ingo Molnar , Namhyung Kim , Paul Mackerras , Peter Zijlstra , Arnaldo Carvalho de Melo Subject: [PATCH 3/3] perf tools: Add lzma decompression support for kernel module Date: Fri, 30 Jan 2015 11:22:26 +0100 Message-Id: <1422613346-22077-4-git-send-email-jolsa@kernel.org> In-Reply-To: <1422613346-22077-1-git-send-email-jolsa@kernel.org> References: <1422613346-22077-1-git-send-email-jolsa@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In short, Fedora compresses kernel modules now, and since perf doesn't recognize this, it can't find any symbols from modules. Fedora 21 compresses kernel modules, so we need to recognize it in perf, currently on Fedora 21 we get: $ perf report --stdio No kallsyms or vmlinux with build-id 739edc9776ec741029e6f79af6270f8e2bc4b764 was found [tg3] with build id 739edc9776ec741029e6f79af6270f8e2bc4b764 not found, continuing without symbols No kallsyms or vmlinux with build-id cfd4a7ccf7dd229d8a2f111b5c01635f5687b056 was found [sky2] with build id cfd4a7ccf7dd229d8a2f111b5c01635f5687b056 not found, continuing without symbols No kallsyms or vmlinux with build-id bb534b79b14143d14bba14640dd79a1a04908e51 was found [be2net] with build id bb534b79b14143d14bba14640dd79a1a04908e51 not found, continuing without symbols 24.65% swapper [kernel.kallsyms] [k] cpuidle_enter_state 23.53% swapper [kernel.kallsyms] [k] intel_idle 1.07% swapper [tg3] [k] tg3_read32 0.70% swapper [kernel.kallsyms] [k] nr_iowait_cpu 0.66% beah-rhts-task [unknown] [.] 0x00007f528c6b5fe1 0.64% swapper [kernel.kallsyms] [k] calc_load_exit_idle 0.64% swapper [sky2] [k] sky2_poll With the fix: $ perf report --stdio 27.08% swapper [kernel.kallsyms] [k] intel_idle 21.48% swapper [kernel.kallsyms] [k] cpuidle_enter_state 1.29% kworker/u128:0 [kernel.kallsyms] [k] finish_task_switch 1.27% swapper [tg3] [k] tg3_read32 1.13% swapper [kernel.kallsyms] [k] cpu_startup_entry 0.98% swapper [sky2] [k] sky2_poll 0.83% rcu_sched [kernel.kallsyms] [k] _raw_spin_lock Signed-off-by: Jiri Olsa Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 8 +++- tools/perf/config/Makefile | 9 +++++ tools/perf/util/dso.c | 3 ++ tools/perf/util/lzma.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 4 ++ 5 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 tools/perf/util/lzma.c diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index aa6a50447c32..10ee29bff61a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -67,7 +67,9 @@ include config/utilities.mak # Define NO_PERF_READ_VDSOX32 if you do not want to build perf-read-vdsox32 # for reading the x32 mode 32-bit compatibility VDSO in 64-bit mode # -# Define NO_ZLIB if you do not want to support compressed kernel modules +# Define NO_ZLIB if you do not want to support compressed (gz) kernel modules +# +# Define NO_LZMA if you do not want to support compressed (xz) kernel modules ifeq ($(srctree),) @@ -601,6 +603,10 @@ ifndef NO_ZLIB LIB_OBJS += $(OUTPUT)util/zlib.o endif +ifndef NO_LZMA + LIB_OBJS += $(OUTPUT)util/lzma.o +endif + ifdef ASCIIDOC8 export ASCIIDOC8 endif diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index d49e1ebb3e41..4ecd54ca5b96 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -624,6 +624,15 @@ ifndef NO_ZLIB endif endif +ifndef NO_LZMA + ifeq ($(feature-lzma), 1) + CFLAGS += -DHAVE_LZMA_SUPPORT + EXTLIBS += -llzma + else + NO_LZMA := 1 + endif +endif + ifndef NO_BACKTRACE ifeq ($(feature-backtrace), 1) CFLAGS += -DHAVE_BACKTRACE_SUPPORT diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index c2f7d3b90966..1577b4544da9 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -148,6 +148,9 @@ static const struct { #ifdef HAVE_ZLIB_SUPPORT { "gz", gzip_decompress_to_file }, #endif +#ifdef HAVE_LZMA_SUPPORT + { "xz", lzma_decompress_to_file }, +#endif { NULL, NULL }, }; diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c new file mode 100644 index 000000000000..5629aee4dab4 --- /dev/null +++ b/tools/perf/util/lzma.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include "util.h" +#include "debug.h" + +#define BUFSIZE 8192 + +static const char* lzma_strerror(lzma_ret ret) +{ + switch ((int) ret) { + case LZMA_MEM_ERROR: + return "Memory allocation failed"; + case LZMA_OPTIONS_ERROR: + return "Unsupported decompressor flags"; + case LZMA_FORMAT_ERROR: + return "The input is not in the .xz format"; + case LZMA_DATA_ERROR: + return "Compressed file is corrupt"; + case LZMA_BUF_ERROR: + return "Compressed file is truncated or otherwise corrupt"; + default: + return "Unknown error, possibly a bug"; + } +} + +int lzma_decompress_to_file(const char *input, int output_fd) +{ + lzma_action action = LZMA_RUN; + lzma_stream strm = LZMA_STREAM_INIT; + lzma_ret ret; + + u8 buf_in[BUFSIZE]; + u8 buf_out[BUFSIZE]; + FILE *infile; + + infile = fopen(input, "rb"); + if (!infile) { + pr_err("lzma: fopen failed on %s: '%s'\n", + input, strerror(errno)); + return -1; + } + + ret = lzma_stream_decoder(&strm, UINT64_MAX, LZMA_CONCATENATED); + if (ret != LZMA_OK) { + pr_err("lzma: lzma_stream_decoder failed %s (%d)\n", + lzma_strerror(ret), ret); + return -1; + } + + strm.next_in = NULL; + strm.avail_in = 0; + strm.next_out = buf_out; + strm.avail_out = sizeof(buf_out); + + while (1) { + if (strm.avail_in == 0 && !feof(infile)) { + strm.next_in = buf_in; + strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile); + + if (ferror(infile)) { + pr_err("lzma: read error: %s\n", strerror(errno)); + return -1; + } + + if (feof(infile)) + action = LZMA_FINISH; + } + + ret = lzma_code(&strm, action); + + if (strm.avail_out == 0 || ret == LZMA_STREAM_END) { + ssize_t write_size = sizeof(buf_out) - strm.avail_out; + + if (writen(output_fd, buf_out, write_size) != write_size) { + pr_err("lzma: write error: %s\n", strerror(errno)); + return -1; + } + + strm.next_out = buf_out; + strm.avail_out = sizeof(buf_out); + } + + if (ret != LZMA_OK) { + if (ret == LZMA_STREAM_END) + return 0; + + pr_err("lzma: failed %s\n", lzma_strerror(ret)); + return -1; + } + } + + fclose(infile); + return 0; +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 027a5153495c..28e04bc1557d 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -327,4 +327,8 @@ bool find_process(const char *name); int gzip_decompress_to_file(const char *input, int output_fd); #endif +#ifdef HAVE_LZMA_SUPPORT +int lzma_decompress_to_file(const char *input, int output_fd); +#endif + #endif /* GIT_COMPAT_UTIL_H */ -- 1.9.3