Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Add gzip decompression support for kernel module

Now my Archlinux box shows module symbols correctly.

Before:
$ perf report --stdio
Failed to open /tmp/perf-3477.map, continuing without symbols
no symbols found in /usr/bin/date, maybe install a debug package?
No kallsyms or vmlinux with build-id 7b4ea0a49ae2111925857099aaf05c3246ff33e0 was found
[drm] with build id 7b4ea0a49ae2111925857099aaf05c3246ff33e0 not found, continuing without symbols
No kallsyms or vmlinux with build-id edd931629094b660ca9dec09a1b635c8d87aa2ee was found
[jbd2] with build id edd931629094b660ca9dec09a1b635c8d87aa2ee not found, continuing without symbols
No kallsyms or vmlinux with build-id a7b1eada671c34933e5610bb920b2ca4945a82c3 was found
[ext4] with build id a7b1eada671c34933e5610bb920b2ca4945a82c3 not found, continuing without symbols
No kallsyms or vmlinux with build-id d69511fa3e5840e770336ef45b06c83fef8d74e3 was found
[scsi_mod] with build id d69511fa3e5840e770336ef45b06c83fef8d74e3 not found, continuing without symbols
No kallsyms or vmlinux with build-id af0430af13461af058770ee9b87afc07922c2e77 was found
[libata] with build id af0430af13461af058770ee9b87afc07922c2e77 not found, continuing without symbols
No kallsyms or vmlinux with build-id aaeedff8160ce631a5f0333591c6ff291201d29f was found
[libahci] with build id aaeedff8160ce631a5f0333591c6ff291201d29f not found, continuing without symbols
No kallsyms or vmlinux with build-id c57907712becaf662dc4981824bb372c0441d605 was found
[mac80211] with build id c57907712becaf662dc4981824bb372c0441d605 not found, continuing without symbols
No kallsyms or vmlinux with build-id e0589077cc0ec8c3e4c40eb9f2d9e69d236bee8f was found
[iwldvm] with build id e0589077cc0ec8c3e4c40eb9f2d9e69d236bee8f not found, continuing without symbols
No kallsyms or vmlinux with build-id 2d86086bf136bf374a2f029cf85a48194f9b950b was found
[cfg80211] with build id 2d86086bf136bf374a2f029cf85a48194f9b950b not found, continuing without symbols
No kallsyms or vmlinux with build-id 4493c48599bdb3d91d0f8db5150e0be33fdd9221 was found
[iwlwifi] with build id 4493c48599bdb3d91d0f8db5150e0be33fdd9221 not found, continuing without symbols
...
#
# Overhead Command Shared Object Symbol
# ........ ............... ....................... ........................................................
#
0.03% swapper [ext4] [k] 0x000000000000fe2e
0.03% swapper [kernel.kallsyms] [k] account_entity_enqueue
0.03% swapper [ext4] [k] 0x000000000000fc2b
0.03% irq/50-iwlwifi [iwlwifi] [k] 0x000000000000200b
0.03% swapper [kernel.kallsyms] [k] ktime_add_safe
0.03% swapper [kernel.kallsyms] [k] elv_completed_request
0.03% swapper [libata] [k] 0x0000000000003997
0.03% swapper [libahci] [k] 0x0000000000001f25
0.03% swapper [kernel.kallsyms] [k] rb_next
0.03% swapper [kernel.kallsyms] [k] blk_finish_request
0.03% swapper [ext4] [k] 0x0000000000010248
0.00% perf [kernel.kallsyms] [k] native_write_msr_safe

After:
$ perf report --stdio
Failed to open /tmp/perf-3477.map, continuing without symbols
no symbols found in /usr/bin/tr, maybe install a debug package?
...
#
# Overhead Command Shared Object Symbol
# ........ ............... ........................... ......................................................
#

0.04% kworker/u16:3 [ext4] [k] ext4_read_block_bitmap
0.03% kworker/u16:0 [mac80211] [k] ieee80211_sta_reset_beacon_monitor
0.02% irq/50-iwlwifi [mac80211] [k] ieee80211_get_bssid
0.02% firefox [e1000e] [k] __ew32_prepare
0.02% swapper [libahci] [k] ahci_handle_port_interrupt
0.02% emacs libglib-2.0.so.0.4000.0 [.] g_mutex_unlock
0.02% swapper [e1000e] [k] e1000_clean_tx_irq
0.02% dwm [kernel.kallsyms] [k] __schedule
0.02% gnome-terminal- [vdso] [.] __vdso_clock_gettime
0.02% swapper [e1000e] [k] e1000_alloc_rx_buffers
0.02% irq/50-iwlwifi [mac80211] [k] ieee80211_rx
0.01% firefox [vdso] [.] __vdso_gettimeofday
0.01% irq/50-iwlwifi [iwlwifi] [k] iwl_pcie_rxq_restock.part.13

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/87h9yexshi.fsf@sejong.aot.lge.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
e92ce12e c00c48fc

+127 -12
+7
tools/perf/Makefile.perf
··· 66 66 # 67 67 # Define NO_PERF_READ_VDSOX32 if you do not want to build perf-read-vdsox32 68 68 # for reading the x32 mode 32-bit compatibility VDSO in 64-bit mode 69 + # 70 + # Define NO_ZLIB if you do not want to support compressed kernel modules 71 + 69 72 70 73 ifeq ($(srctree),) 71 74 srctree := $(patsubst %/,%,$(dir $(shell pwd))) ··· 585 582 586 583 ifndef NO_LIBNUMA 587 584 BUILTIN_OBJS += $(OUTPUT)bench/numa.o 585 + endif 586 + 587 + ifndef NO_ZLIB 588 + LIB_OBJS += $(OUTPUT)util/zlib.o 588 589 endif 589 590 590 591 ifdef ASCIIDOC8
+13 -2
tools/perf/config/Makefile
··· 200 200 libunwind \ 201 201 stackprotector-all \ 202 202 timerfd \ 203 - libdw-dwarf-unwind 203 + libdw-dwarf-unwind \ 204 + zlib 204 205 205 206 LIB_FEATURE_TESTS = \ 206 207 dwarf \ ··· 215 214 libpython \ 216 215 libslang \ 217 216 libunwind \ 218 - libdw-dwarf-unwind 217 + libdw-dwarf-unwind \ 218 + zlib 219 219 220 220 VF_FEATURE_TESTS = \ 221 221 backtrace \ ··· 604 602 605 603 ifneq ($(filter -lbfd,$(EXTLIBS)),) 606 604 CFLAGS += -DHAVE_LIBBFD_SUPPORT 605 + endif 606 + 607 + ifndef NO_ZLIB 608 + ifeq ($(feature-zlib), 1) 609 + CFLAGS += -DHAVE_ZLIB_SUPPORT 610 + EXTLIBS += -lz 611 + else 612 + NO_ZLIB := 1 613 + endif 607 614 endif 608 615 609 616 ifndef NO_BACKTRACE
+6 -2
tools/perf/config/feature-checks/Makefile
··· 29 29 test-timerfd.bin \ 30 30 test-libdw-dwarf-unwind.bin \ 31 31 test-compile-32.bin \ 32 - test-compile-x32.bin 32 + test-compile-x32.bin \ 33 + test-zlib.bin 33 34 34 35 CC := $(CROSS_COMPILE)gcc -MD 35 36 PKG_CONFIG := $(CROSS_COMPILE)pkg-config ··· 42 41 ############################### 43 42 44 43 test-all.bin: 45 - $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl 44 + $(BUILD) -Werror -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lelf -laudit -I/usr/include/slang -lslang $(shell $(PKG_CONFIG) --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl -lz 46 45 47 46 test-hello.bin: 48 47 $(BUILD) ··· 139 138 140 139 test-compile-x32.bin: 141 140 $(CC) -mx32 -o $(OUTPUT)$@ test-compile.c 141 + 142 + test-zlib.bin: 143 + $(BUILD) -lz 142 144 143 145 -include *.d 144 146
+5
tools/perf/config/feature-checks/test-all.c
··· 93 93 # include "test-sync-compare-and-swap.c" 94 94 #undef main 95 95 96 + #define main main_test_zlib 97 + # include "test-zlib.c" 98 + #undef main 99 + 96 100 int main(int argc, char *argv[]) 97 101 { 98 102 main_test_libpython(); ··· 120 116 main_test_stackprotector_all(); 121 117 main_test_libdw_dwarf_unwind(); 122 118 main_test_sync_compare_and_swap(argc, argv); 119 + main_test_zlib(); 123 120 124 121 return 0; 125 122 }
+9
tools/perf/config/feature-checks/test-zlib.c
··· 1 + #include <zlib.h> 2 + 3 + int main(void) 4 + { 5 + z_stream zs; 6 + 7 + inflateInit(&zs); 8 + return 0; 9 + }
+4 -8
tools/perf/util/dso.c
··· 141 141 return ret; 142 142 } 143 143 144 - static int decompress_dummy(const char *input __maybe_unused, 145 - int output __maybe_unused) 146 - { 147 - return -1; 148 - } 149 - 150 144 static const struct { 151 145 const char *fmt; 152 146 int (*decompress)(const char *input, int output); 153 147 } compressions[] = { 154 - { "gz", decompress_dummy }, 155 - { NULL, }, 148 + #ifdef HAVE_ZLIB_SUPPORT 149 + { "gz", gzip_decompress_to_file }, 150 + #endif 151 + { NULL, NULL }, 156 152 }; 157 153 158 154 bool is_supported_compression(const char *ext)
+5
tools/perf/util/util.h
··· 351 351 352 352 const char *get_filename_for_perf_kvm(void); 353 353 bool find_process(const char *name); 354 + 355 + #ifdef HAVE_ZLIB_SUPPORT 356 + int gzip_decompress_to_file(const char *input, int output_fd); 357 + #endif 358 + 354 359 #endif /* GIT_COMPAT_UTIL_H */
+78
tools/perf/util/zlib.c
··· 1 + #include <stdio.h> 2 + #include <unistd.h> 3 + #include <sys/stat.h> 4 + #include <sys/mman.h> 5 + #include <zlib.h> 6 + 7 + #include "util/util.h" 8 + #include "util/debug.h" 9 + 10 + 11 + #define CHUNK_SIZE 16384 12 + 13 + int gzip_decompress_to_file(const char *input, int output_fd) 14 + { 15 + int ret = Z_STREAM_ERROR; 16 + int input_fd; 17 + void *ptr; 18 + int len; 19 + struct stat stbuf; 20 + unsigned char buf[CHUNK_SIZE]; 21 + z_stream zs = { 22 + .zalloc = Z_NULL, 23 + .zfree = Z_NULL, 24 + .opaque = Z_NULL, 25 + .avail_in = 0, 26 + .next_in = Z_NULL, 27 + }; 28 + 29 + input_fd = open(input, O_RDONLY); 30 + if (input_fd < 0) 31 + return -1; 32 + 33 + if (fstat(input_fd, &stbuf) < 0) 34 + goto out_close; 35 + 36 + ptr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0); 37 + if (ptr == MAP_FAILED) 38 + goto out_close; 39 + 40 + if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK) 41 + goto out_unmap; 42 + 43 + zs.next_in = ptr; 44 + zs.avail_in = stbuf.st_size; 45 + 46 + do { 47 + zs.next_out = buf; 48 + zs.avail_out = CHUNK_SIZE; 49 + 50 + ret = inflate(&zs, Z_NO_FLUSH); 51 + switch (ret) { 52 + case Z_NEED_DICT: 53 + ret = Z_DATA_ERROR; 54 + /* fall through */ 55 + case Z_DATA_ERROR: 56 + case Z_MEM_ERROR: 57 + goto out; 58 + default: 59 + break; 60 + } 61 + 62 + len = CHUNK_SIZE - zs.avail_out; 63 + if (writen(output_fd, buf, len) != len) { 64 + ret = Z_DATA_ERROR; 65 + goto out; 66 + } 67 + 68 + } while (ret != Z_STREAM_END); 69 + 70 + out: 71 + inflateEnd(&zs); 72 + out_unmap: 73 + munmap(ptr, stbuf.st_size); 74 + out_close: 75 + close(input_fd); 76 + 77 + return ret == Z_STREAM_END ? 0 : -1; 78 + }