From 7a023fd239498edd269838784f12888147d970da Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 9 Sep 2016 12:00:08 -0300 Subject: [PATCH 01/22] perf probe: Fix dwarf regs table for x86_64 In 293d5b439483 ("perf probe: Support probing on offline cross-arch binary") DWARF register tables were introduced for many architectures, with the one for the "dx" register being broken for x86_64, which got noticed by the 'perf test bpf' testcase, that has this difference from a successful run to one that fails, with the aforementioned patch: -Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=dx:s32 -Failed to write event: Invalid argument -bpf_probe: failed to apply perf probe eventsFailed to add events selected by BPF +Writing event: p:perf_bpf_probe/func _text+5197232 f_mode=+68(%di):x32 offset=%si:s64 orig=%dx:s32 Add the missing '%' to '%dx' to fix this. Acked-by: Masami Hiramatsu Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Fixes: 293d5b439483 ("perf probe: Support probing on offline cross-arch binary") Link: https://lkml.kernel.org/r/20160909145955.GC32585@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/x86/include/dwarf-regs-table.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/include/dwarf-regs-table.h b/tools/perf/arch/x86/include/dwarf-regs-table.h index 39ac7cbb525b..9b5e5cbb4209 100644 --- a/tools/perf/arch/x86/include/dwarf-regs-table.h +++ b/tools/perf/arch/x86/include/dwarf-regs-table.h @@ -7,7 +7,7 @@ static const char * const x86_32_regstr_tbl[] = { }; static const char * const x86_64_regstr_tbl[] = { - "%ax", "dx", "%cx", "%bx", "%si", "%di", + "%ax", "%dx", "%cx", "%bx", "%si", "%di", "%bp", "%sp", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", }; From d9ea48bc4e7cc297ca1073fa3f90ed80d964b7b4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 12 Sep 2016 15:19:52 +0900 Subject: [PATCH 02/22] perf hists browser: Fix event group display Milian reported that the event group on TUI shows duplicated overhead. This was due to a bug on calculating hpp->buf position. The hpp_advance() was called from __hpp__slsmg_color_printf() on TUI but it's already called from the hpp__call_print_fn macro in __hpp__fmt(). The end result is that the print function returns number of bytes it printed but the buffer advanced twice of the length. This is generally not a problem since it doesn't need to access the buffer again. But with event group, overhead needs to be printed multiple times and hist_entry__snprintf_alignment() tries to fill the space with buffer after it printed. So it (brokenly) showed the last overhead again. The bug was there from the beginning, but I think it's only revealed when the alignment function was added. Reported-by: Milian Wolff Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Jiri Olsa Cc: Peter Zijlstra Fixes: 89fee7094323 ("perf hists: Do column alignment on the format iterator") Link: http://lkml.kernel.org/r/20160912061958.16656-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index f0611c937d4b..35e44b1879e3 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -1097,7 +1097,6 @@ static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent); ui_browser__printf(arg->b, "%s", hpp->buf); - advance_hpp(hpp, ret); return ret; } From f3539c12d8196ce0a1993364d30b3a18908470d1 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 12 Sep 2016 12:54:29 +0000 Subject: [PATCH 03/22] tools include: Add uapi mman.h for each architecture Some mmap related macros have different values for different architectures. This patch introduces uapi mman.h for each architectures. Three headers are cloned from kernel include to tools/include: tools/include/uapi/asm-generic/mman-common.h tools/include/uapi/asm-generic/mman.h tools/include/uapi/linux/mman.h The main part of this patch is generated by following script: macros=`cat $0 | awk 'V==1 {print}; /^# start macro list/ {V=1}'` for arch in `ls tools/arch` do [ -d tools/arch/$arch/include/uapi/asm ] || mkdir -p tools/arch/$arch/include/uapi/asm src=arch/$arch/include/uapi/asm/mman.h target=tools/arch/$arch/include/uapi/asm/mman.h guard="TOOLS_ARCH_"`echo $arch | awk '{print toupper($0)}'`_UAPI_ASM_MMAN_FIX_H echo '#ifndef '$guard > $target echo '#define '$guard >> $target [ -f $src ] && for m in $macros do if grep '#define[ \t]*'$m $src > /dev/null 2>&1 then grep -h '#define[ \t]*'$m $src | sed 's/[ \t]*\/\*.*$//g' >> $target fi done if [ -f $src ] then grep '#include > $target else echo "#include " >> $target fi echo '#endif' >> $target echo "$target" done exit 0 # Following macros are extracted from: # tools/perf/trace/beauty/mmap.c # # start macro list MADV_DODUMP MADV_DOFORK MADV_DONTDUMP MADV_DONTFORK MADV_DONTNEED MADV_HUGEPAGE MADV_HWPOISON MADV_MERGEABLE MADV_NOHUGEPAGE MADV_NORMAL MADV_RANDOM MADV_REMOVE MADV_SEQUENTIAL MADV_SOFT_OFFLINE MADV_UNMERGEABLE MADV_WILLNEED MAP_32BIT MAP_ANONYMOUS MAP_DENYWRITE MAP_EXECUTABLE MAP_FILE MAP_FIXED MAP_GROWSDOWN MAP_HUGETLB MAP_LOCKED MAP_NONBLOCK MAP_NORESERVE MAP_POPULATE MAP_PRIVATE MAP_SHARED MAP_STACK MAP_UNINITIALIZED MREMAP_FIXED MREMAP_MAYMOVE PROT_EXEC PROT_GROWSDOWN PROT_GROWSUP PROT_NONE PROT_READ PROT_SEM PROT_WRITE Signed-off-by: Wang Nan Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1473684871-209320-2-git-send-email-wangnan0@huawei.com [ Added new files to tools/perf/MANIFEST to fix the detached tarball build, add mman.h for ARC ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/alpha/include/uapi/asm/mman.h | 38 ++++++++++ tools/arch/arc/include/uapi/asm/mman.h | 4 + tools/arch/arm/include/uapi/asm/mman.h | 4 + tools/arch/arm64/include/uapi/asm/mman.h | 4 + tools/arch/frv/include/uapi/asm/mman.h | 4 + tools/arch/h8300/include/uapi/asm/mman.h | 4 + tools/arch/hexagon/include/uapi/asm/mman.h | 4 + tools/arch/ia64/include/uapi/asm/mman.h | 4 + tools/arch/m32r/include/uapi/asm/mman.h | 4 + tools/arch/microblaze/include/uapi/asm/mman.h | 4 + tools/arch/mips/include/uapi/asm/mman.h | 39 ++++++++++ tools/arch/mn10300/include/uapi/asm/mman.h | 4 + tools/arch/parisc/include/uapi/asm/mman.h | 38 ++++++++++ tools/arch/powerpc/include/uapi/asm/mman.h | 13 ++++ tools/arch/s390/include/uapi/asm/mman.h | 4 + tools/arch/score/include/uapi/asm/mman.h | 4 + tools/arch/sh/include/uapi/asm/mman.h | 4 + tools/arch/sparc/include/uapi/asm/mman.h | 13 ++++ tools/arch/tile/include/uapi/asm/mman.h | 13 ++++ tools/arch/x86/include/uapi/asm/mman.h | 5 ++ tools/arch/xtensa/include/uapi/asm/mman.h | 38 ++++++++++ tools/include/uapi/asm-generic/mman-common.h | 75 +++++++++++++++++++ tools/include/uapi/asm-generic/mman.h | 22 ++++++ tools/include/uapi/linux/mman.h | 13 ++++ tools/perf/MANIFEST | 4 + 25 files changed, 363 insertions(+) create mode 100644 tools/arch/alpha/include/uapi/asm/mman.h create mode 100644 tools/arch/arc/include/uapi/asm/mman.h create mode 100644 tools/arch/arm/include/uapi/asm/mman.h create mode 100644 tools/arch/arm64/include/uapi/asm/mman.h create mode 100644 tools/arch/frv/include/uapi/asm/mman.h create mode 100644 tools/arch/h8300/include/uapi/asm/mman.h create mode 100644 tools/arch/hexagon/include/uapi/asm/mman.h create mode 100644 tools/arch/ia64/include/uapi/asm/mman.h create mode 100644 tools/arch/m32r/include/uapi/asm/mman.h create mode 100644 tools/arch/microblaze/include/uapi/asm/mman.h create mode 100644 tools/arch/mips/include/uapi/asm/mman.h create mode 100644 tools/arch/mn10300/include/uapi/asm/mman.h create mode 100644 tools/arch/parisc/include/uapi/asm/mman.h create mode 100644 tools/arch/powerpc/include/uapi/asm/mman.h create mode 100644 tools/arch/s390/include/uapi/asm/mman.h create mode 100644 tools/arch/score/include/uapi/asm/mman.h create mode 100644 tools/arch/sh/include/uapi/asm/mman.h create mode 100644 tools/arch/sparc/include/uapi/asm/mman.h create mode 100644 tools/arch/tile/include/uapi/asm/mman.h create mode 100644 tools/arch/x86/include/uapi/asm/mman.h create mode 100644 tools/arch/xtensa/include/uapi/asm/mman.h create mode 100644 tools/include/uapi/asm-generic/mman-common.h create mode 100644 tools/include/uapi/asm-generic/mman.h create mode 100644 tools/include/uapi/linux/mman.h diff --git a/tools/arch/alpha/include/uapi/asm/mman.h b/tools/arch/alpha/include/uapi/asm/mman.h new file mode 100644 index 000000000000..6ed4ad44a289 --- /dev/null +++ b/tools/arch/alpha/include/uapi/asm/mman.h @@ -0,0 +1,38 @@ +#ifndef TOOLS_ARCH_ALPHA_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_ALPHA_UAPI_ASM_MMAN_FIX_H +#define MADV_DODUMP 17 +#define MADV_DOFORK 11 +#define MADV_DONTDUMP 16 +#define MADV_DONTFORK 10 +#define MADV_DONTNEED 6 +#define MADV_HUGEPAGE 14 +#define MADV_MERGEABLE 12 +#define MADV_NOHUGEPAGE 15 +#define MADV_NORMAL 0 +#define MADV_RANDOM 1 +#define MADV_REMOVE 9 +#define MADV_SEQUENTIAL 2 +#define MADV_UNMERGEABLE 13 +#define MADV_WILLNEED 3 +#define MAP_ANONYMOUS 0x10 +#define MAP_DENYWRITE 0x02000 +#define MAP_EXECUTABLE 0x04000 +#define MAP_FILE 0 +#define MAP_FIXED 0x100 +#define MAP_GROWSDOWN 0x01000 +#define MAP_HUGETLB 0x100000 +#define MAP_LOCKED 0x08000 +#define MAP_NONBLOCK 0x40000 +#define MAP_NORESERVE 0x10000 +#define MAP_POPULATE 0x20000 +#define MAP_PRIVATE 0x02 +#define MAP_SHARED 0x01 +#define MAP_STACK 0x80000 +#define PROT_EXEC 0x4 +#define PROT_GROWSDOWN 0x01000000 +#define PROT_GROWSUP 0x02000000 +#define PROT_NONE 0x0 +#define PROT_READ 0x1 +#define PROT_SEM 0x8 +#define PROT_WRITE 0x2 +#endif diff --git a/tools/arch/arc/include/uapi/asm/mman.h b/tools/arch/arc/include/uapi/asm/mman.h new file mode 100644 index 000000000000..f76765dbaafa --- /dev/null +++ b/tools/arch/arc/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/arm/include/uapi/asm/mman.h b/tools/arch/arm/include/uapi/asm/mman.h new file mode 100644 index 000000000000..f2006385e203 --- /dev/null +++ b/tools/arch/arm/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/arm64/include/uapi/asm/mman.h b/tools/arch/arm64/include/uapi/asm/mman.h new file mode 100644 index 000000000000..a7dd975bb33e --- /dev/null +++ b/tools/arch/arm64/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/frv/include/uapi/asm/mman.h b/tools/arch/frv/include/uapi/asm/mman.h new file mode 100644 index 000000000000..99bba054e795 --- /dev/null +++ b/tools/arch/frv/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/h8300/include/uapi/asm/mman.h b/tools/arch/h8300/include/uapi/asm/mman.h new file mode 100644 index 000000000000..df95096c2a7a --- /dev/null +++ b/tools/arch/h8300/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/hexagon/include/uapi/asm/mman.h b/tools/arch/hexagon/include/uapi/asm/mman.h new file mode 100644 index 000000000000..f1adcce90f37 --- /dev/null +++ b/tools/arch/hexagon/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/ia64/include/uapi/asm/mman.h b/tools/arch/ia64/include/uapi/asm/mman.h new file mode 100644 index 000000000000..23420eb30d92 --- /dev/null +++ b/tools/arch/ia64/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/m32r/include/uapi/asm/mman.h b/tools/arch/m32r/include/uapi/asm/mman.h new file mode 100644 index 000000000000..a35ebd68add9 --- /dev/null +++ b/tools/arch/m32r/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/microblaze/include/uapi/asm/mman.h b/tools/arch/microblaze/include/uapi/asm/mman.h new file mode 100644 index 000000000000..75f460abbe58 --- /dev/null +++ b/tools/arch/microblaze/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/mips/include/uapi/asm/mman.h b/tools/arch/mips/include/uapi/asm/mman.h new file mode 100644 index 000000000000..db88fa41e74c --- /dev/null +++ b/tools/arch/mips/include/uapi/asm/mman.h @@ -0,0 +1,39 @@ +#ifndef TOOLS_ARCH_MIPS_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_MIPS_UAPI_ASM_MMAN_FIX_H +#define MADV_DODUMP 17 +#define MADV_DOFORK 11 +#define MADV_DONTDUMP 16 +#define MADV_DONTFORK 10 +#define MADV_DONTNEED 4 +#define MADV_HUGEPAGE 14 +#define MADV_HWPOISON 100 +#define MADV_MERGEABLE 12 +#define MADV_NOHUGEPAGE 15 +#define MADV_NORMAL 0 +#define MADV_RANDOM 1 +#define MADV_REMOVE 9 +#define MADV_SEQUENTIAL 2 +#define MADV_UNMERGEABLE 13 +#define MADV_WILLNEED 3 +#define MAP_ANONYMOUS 0x0800 +#define MAP_DENYWRITE 0x2000 +#define MAP_EXECUTABLE 0x4000 +#define MAP_FILE 0 +#define MAP_FIXED 0x010 +#define MAP_GROWSDOWN 0x1000 +#define MAP_HUGETLB 0x80000 +#define MAP_LOCKED 0x8000 +#define MAP_NONBLOCK 0x20000 +#define MAP_NORESERVE 0x0400 +#define MAP_POPULATE 0x10000 +#define MAP_PRIVATE 0x002 +#define MAP_SHARED 0x001 +#define MAP_STACK 0x40000 +#define PROT_EXEC 0x04 +#define PROT_GROWSDOWN 0x01000000 +#define PROT_GROWSUP 0x02000000 +#define PROT_NONE 0x00 +#define PROT_READ 0x01 +#define PROT_SEM 0x10 +#define PROT_WRITE 0x02 +#endif diff --git a/tools/arch/mn10300/include/uapi/asm/mman.h b/tools/arch/mn10300/include/uapi/asm/mman.h new file mode 100644 index 000000000000..81faa5d1b2dc --- /dev/null +++ b/tools/arch/mn10300/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/parisc/include/uapi/asm/mman.h b/tools/arch/parisc/include/uapi/asm/mman.h new file mode 100644 index 000000000000..c4a9d9f12d55 --- /dev/null +++ b/tools/arch/parisc/include/uapi/asm/mman.h @@ -0,0 +1,38 @@ +#ifndef TOOLS_ARCH_PARISC_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_PARISC_UAPI_ASM_MMAN_FIX_H +#define MADV_DODUMP 70 +#define MADV_DOFORK 11 +#define MADV_DONTDUMP 69 +#define MADV_DONTFORK 10 +#define MADV_DONTNEED 4 +#define MADV_HUGEPAGE 67 +#define MADV_MERGEABLE 65 +#define MADV_NOHUGEPAGE 68 +#define MADV_NORMAL 0 +#define MADV_RANDOM 1 +#define MADV_REMOVE 9 +#define MADV_SEQUENTIAL 2 +#define MADV_UNMERGEABLE 66 +#define MADV_WILLNEED 3 +#define MAP_ANONYMOUS 0x10 +#define MAP_DENYWRITE 0x0800 +#define MAP_EXECUTABLE 0x1000 +#define MAP_FILE 0 +#define MAP_FIXED 0x04 +#define MAP_GROWSDOWN 0x8000 +#define MAP_HUGETLB 0x80000 +#define MAP_LOCKED 0x2000 +#define MAP_NONBLOCK 0x20000 +#define MAP_NORESERVE 0x4000 +#define MAP_POPULATE 0x10000 +#define MAP_PRIVATE 0x02 +#define MAP_SHARED 0x01 +#define MAP_STACK 0x40000 +#define PROT_EXEC 0x4 +#define PROT_GROWSDOWN 0x01000000 +#define PROT_GROWSUP 0x02000000 +#define PROT_NONE 0x0 +#define PROT_READ 0x1 +#define PROT_SEM 0x8 +#define PROT_WRITE 0x2 +#endif diff --git a/tools/arch/powerpc/include/uapi/asm/mman.h b/tools/arch/powerpc/include/uapi/asm/mman.h new file mode 100644 index 000000000000..7a56ab9988dd --- /dev/null +++ b/tools/arch/powerpc/include/uapi/asm/mman.h @@ -0,0 +1,13 @@ +#ifndef TOOLS_ARCH_POWERPC_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_POWERPC_UAPI_ASM_MMAN_FIX_H +#define MAP_DENYWRITE 0x0800 +#define MAP_EXECUTABLE 0x1000 +#define MAP_GROWSDOWN 0x0100 +#define MAP_HUGETLB 0x40000 +#define MAP_LOCKED 0x80 +#define MAP_NONBLOCK 0x10000 +#define MAP_NORESERVE 0x40 +#define MAP_POPULATE 0x8000 +#define MAP_STACK 0x20000 +#include +#endif diff --git a/tools/arch/s390/include/uapi/asm/mman.h b/tools/arch/s390/include/uapi/asm/mman.h new file mode 100644 index 000000000000..fe53b91405d3 --- /dev/null +++ b/tools/arch/s390/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/score/include/uapi/asm/mman.h b/tools/arch/score/include/uapi/asm/mman.h new file mode 100644 index 000000000000..ba1ee9ce9f6a --- /dev/null +++ b/tools/arch/score/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/sh/include/uapi/asm/mman.h b/tools/arch/sh/include/uapi/asm/mman.h new file mode 100644 index 000000000000..5a47d8cff786 --- /dev/null +++ b/tools/arch/sh/include/uapi/asm/mman.h @@ -0,0 +1,4 @@ +#ifndef TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H +#include +#endif diff --git a/tools/arch/sparc/include/uapi/asm/mman.h b/tools/arch/sparc/include/uapi/asm/mman.h new file mode 100644 index 000000000000..b88f3ac9c48a --- /dev/null +++ b/tools/arch/sparc/include/uapi/asm/mman.h @@ -0,0 +1,13 @@ +#ifndef TOOLS_ARCH_SPARC_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_SPARC_UAPI_ASM_MMAN_FIX_H +#define MAP_DENYWRITE 0x0800 +#define MAP_EXECUTABLE 0x1000 +#define MAP_GROWSDOWN 0x0200 +#define MAP_HUGETLB 0x40000 +#define MAP_LOCKED 0x100 +#define MAP_NONBLOCK 0x10000 +#define MAP_NORESERVE 0x40 +#define MAP_POPULATE 0x8000 +#define MAP_STACK 0x20000 +#include +#endif diff --git a/tools/arch/tile/include/uapi/asm/mman.h b/tools/arch/tile/include/uapi/asm/mman.h new file mode 100644 index 000000000000..b0a054f27a22 --- /dev/null +++ b/tools/arch/tile/include/uapi/asm/mman.h @@ -0,0 +1,13 @@ +#ifndef TOOLS_ARCH_TILE_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_TILE_UAPI_ASM_MMAN_FIX_H +#define MAP_DENYWRITE 0x0800 +#define MAP_EXECUTABLE 0x1000 +#define MAP_GROWSDOWN 0x0100 +#define MAP_HUGETLB 0x4000 +#define MAP_LOCKED 0x0200 +#define MAP_NONBLOCK 0x0080 +#define MAP_NORESERVE 0x0400 +#define MAP_POPULATE 0x0040 +#define MAP_STACK MAP_GROWSDOWN +#include +#endif diff --git a/tools/arch/x86/include/uapi/asm/mman.h b/tools/arch/x86/include/uapi/asm/mman.h new file mode 100644 index 000000000000..b73c1af8b1dd --- /dev/null +++ b/tools/arch/x86/include/uapi/asm/mman.h @@ -0,0 +1,5 @@ +#ifndef TOOLS_ARCH_X86_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_X86_UAPI_ASM_MMAN_FIX_H +#define MAP_32BIT 0x40 +#include +#endif diff --git a/tools/arch/xtensa/include/uapi/asm/mman.h b/tools/arch/xtensa/include/uapi/asm/mman.h new file mode 100644 index 000000000000..1c89538bd391 --- /dev/null +++ b/tools/arch/xtensa/include/uapi/asm/mman.h @@ -0,0 +1,38 @@ +#ifndef TOOLS_ARCH_XTENSA_UAPI_ASM_MMAN_FIX_H +#define TOOLS_ARCH_XTENSA_UAPI_ASM_MMAN_FIX_H +#define MADV_DODUMP 17 +#define MADV_DOFORK 11 +#define MADV_DONTDUMP 16 +#define MADV_DONTFORK 10 +#define MADV_DONTNEED 4 +#define MADV_HUGEPAGE 14 +#define MADV_MERGEABLE 12 +#define MADV_NOHUGEPAGE 15 +#define MADV_NORMAL 0 +#define MADV_RANDOM 1 +#define MADV_REMOVE 9 +#define MADV_SEQUENTIAL 2 +#define MADV_UNMERGEABLE 13 +#define MADV_WILLNEED 3 +#define MAP_ANONYMOUS 0x0800 +#define MAP_DENYWRITE 0x2000 +#define MAP_EXECUTABLE 0x4000 +#define MAP_FILE 0 +#define MAP_FIXED 0x010 +#define MAP_GROWSDOWN 0x1000 +#define MAP_HUGETLB 0x80000 +#define MAP_LOCKED 0x8000 +#define MAP_NONBLOCK 0x20000 +#define MAP_NORESERVE 0x0400 +#define MAP_POPULATE 0x10000 +#define MAP_PRIVATE 0x002 +#define MAP_SHARED 0x001 +#define MAP_STACK 0x40000 +#define PROT_EXEC 0x4 +#define PROT_GROWSDOWN 0x01000000 +#define PROT_GROWSUP 0x02000000 +#define PROT_NONE 0x0 +#define PROT_READ 0x1 +#define PROT_SEM 0x10 +#define PROT_WRITE 0x2 +#endif diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h new file mode 100644 index 000000000000..58274382a616 --- /dev/null +++ b/tools/include/uapi/asm-generic/mman-common.h @@ -0,0 +1,75 @@ +#ifndef __ASM_GENERIC_MMAN_COMMON_H +#define __ASM_GENERIC_MMAN_COMMON_H + +/* + Author: Michael S. Tsirkin , Mellanox Technologies Ltd. + Based on: asm-xxx/mman.h +*/ + +#define PROT_READ 0x1 /* page can be read */ +#define PROT_WRITE 0x2 /* page can be written */ +#define PROT_EXEC 0x4 /* page can be executed */ +#define PROT_SEM 0x8 /* page may be used for atomic ops */ +#define PROT_NONE 0x0 /* page can not be accessed */ +#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ +#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ + +#define MAP_SHARED 0x01 /* Share changes */ +#define MAP_PRIVATE 0x02 /* Changes are private */ +#define MAP_TYPE 0x0f /* Mask for type of mapping */ +#define MAP_FIXED 0x10 /* Interpret addr exactly */ +#define MAP_ANONYMOUS 0x20 /* don't use a file */ +#ifdef CONFIG_MMAP_ALLOW_UNINITIALIZED +# define MAP_UNINITIALIZED 0x4000000 /* For anonymous mmap, memory could be uninitialized */ +#else +# define MAP_UNINITIALIZED 0x0 /* Don't support this flag */ +#endif + +/* + * Flags for mlock + */ +#define MLOCK_ONFAULT 0x01 /* Lock pages in range after they are faulted in, do not prefault */ + +#define MS_ASYNC 1 /* sync memory asynchronously */ +#define MS_INVALIDATE 2 /* invalidate the caches */ +#define MS_SYNC 4 /* synchronous memory sync */ + +#define MADV_NORMAL 0 /* no further special treatment */ +#define MADV_RANDOM 1 /* expect random page references */ +#define MADV_SEQUENTIAL 2 /* expect sequential page references */ +#define MADV_WILLNEED 3 /* will need these pages */ +#define MADV_DONTNEED 4 /* don't need these pages */ + +/* common parameters: try to keep these consistent across architectures */ +#define MADV_FREE 8 /* free pages only if memory pressure */ +#define MADV_REMOVE 9 /* remove these pages & resources */ +#define MADV_DONTFORK 10 /* don't inherit across fork */ +#define MADV_DOFORK 11 /* do inherit across fork */ +#define MADV_HWPOISON 100 /* poison a page for testing */ +#define MADV_SOFT_OFFLINE 101 /* soft offline page for testing */ + +#define MADV_MERGEABLE 12 /* KSM may merge identical pages */ +#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */ + +#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */ +#define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */ + +#define MADV_DONTDUMP 16 /* Explicity exclude from the core dump, + overrides the coredump filter bits */ +#define MADV_DODUMP 17 /* Clear the MADV_DONTDUMP flag */ + +/* compatibility flags */ +#define MAP_FILE 0 + +/* + * When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size. + * This gives us 6 bits, which is enough until someone invents 128 bit address + * spaces. + * + * Assume these are all power of twos. + * When 0 use the default page size. + */ +#define MAP_HUGE_SHIFT 26 +#define MAP_HUGE_MASK 0x3f + +#endif /* __ASM_GENERIC_MMAN_COMMON_H */ diff --git a/tools/include/uapi/asm-generic/mman.h b/tools/include/uapi/asm-generic/mman.h new file mode 100644 index 000000000000..10fa7857777f --- /dev/null +++ b/tools/include/uapi/asm-generic/mman.h @@ -0,0 +1,22 @@ +#ifndef __ASM_GENERIC_MMAN_H +#define __ASM_GENERIC_MMAN_H + +#include + +#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ +#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ +#define MAP_LOCKED 0x2000 /* pages are locked */ +#define MAP_NORESERVE 0x4000 /* don't check for reservations */ +#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ +#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ + +/* Bits [26:31] are reserved, see mman-common.h for MAP_HUGETLB usage */ + +#define MCL_CURRENT 1 /* lock all current mappings */ +#define MCL_FUTURE 2 /* lock all future mappings */ +#define MCL_ONFAULT 4 /* lock all pages that are faulted in */ + +#endif /* __ASM_GENERIC_MMAN_H */ diff --git a/tools/include/uapi/linux/mman.h b/tools/include/uapi/linux/mman.h new file mode 100644 index 000000000000..81d8edf11789 --- /dev/null +++ b/tools/include/uapi/linux/mman.h @@ -0,0 +1,13 @@ +#ifndef _UAPI_LINUX_MMAN_H +#define _UAPI_LINUX_MMAN_H + +#include + +#define MREMAP_MAYMOVE 1 +#define MREMAP_FIXED 2 + +#define OVERCOMMIT_GUESS 0 +#define OVERCOMMIT_ALWAYS 1 +#define OVERCOMMIT_NEVER 2 + +#endif /* _UAPI_LINUX_MMAN_H */ diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index ff200c6cb790..0bda2cca2b3a 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST @@ -66,9 +66,12 @@ tools/include/linux/hash.h tools/include/linux/kernel.h tools/include/linux/list.h tools/include/linux/log2.h +tools/include/uapi/asm-generic/mman-common.h +tools/include/uapi/asm-generic/mman.h tools/include/uapi/linux/bpf.h tools/include/uapi/linux/bpf_common.h tools/include/uapi/linux/hw_breakpoint.h +tools/include/uapi/linux/mman.h tools/include/uapi/linux/perf_event.h tools/include/linux/poison.h tools/include/linux/rbtree.h @@ -79,4 +82,5 @@ tools/include/linux/types.h tools/include/linux/err.h tools/include/linux/bitmap.h tools/include/linux/time64.h +tools/arch/*/include/uapi/asm/mman.h tools/arch/*/include/uapi/asm/perf_regs.h From 277cf08f3febd9d0921f4ff1b46fd5d294fe3942 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 Sep 2016 16:27:32 -0300 Subject: [PATCH 04/22] perf trace beauty mmap: Fix defines for non !x86_64 Several defines have different values in different arches, so we can't just define it to the x86_64 value, use uapi/linux/mmap.h that was recently introduced to reliably find those, not using possibly outdated libc headers. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Cc: Zefan Li Link: http://lkml.kernel.org/n/tip-4eajp5yp8i2fuw44n7jmcg5t@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/mmap.c | 71 +--------------------------------- 1 file changed, 1 insertion(+), 70 deletions(-) diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index d0a3a8e402e7..3629b45b8e93 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -1,8 +1,4 @@ -#include - -#ifndef PROT_SEM -#define PROT_SEM 0x8 -#endif +#include static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, struct syscall_arg *arg) @@ -33,31 +29,6 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot -#ifndef MAP_FIXED -#define MAP_FIXED 0x10 -#endif - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS 0x20 -#endif - -#ifndef MAP_32BIT -#define MAP_32BIT 0x40 -#endif - -#ifndef MAP_STACK -#define MAP_STACK 0x20000 -#endif - -#ifndef MAP_HUGETLB -#define MAP_HUGETLB 0x40000 -#endif - -#ifndef MAP_UNINITIALIZED -#define MAP_UNINITIALIZED 0x4000000 -#endif - - static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -95,13 +66,6 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags -#ifndef MREMAP_MAYMOVE -#define MREMAP_MAYMOVE 1 -#endif -#ifndef MREMAP_FIXED -#define MREMAP_FIXED 2 -#endif - static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -125,39 +89,6 @@ static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size, #define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags -#ifndef MADV_HWPOISON -#define MADV_HWPOISON 100 -#endif - -#ifndef MADV_SOFT_OFFLINE -#define MADV_SOFT_OFFLINE 101 -#endif - -#ifndef MADV_MERGEABLE -#define MADV_MERGEABLE 12 -#endif - -#ifndef MADV_UNMERGEABLE -#define MADV_UNMERGEABLE 13 -#endif - -#ifndef MADV_HUGEPAGE -#define MADV_HUGEPAGE 14 -#endif - -#ifndef MADV_NOHUGEPAGE -#define MADV_NOHUGEPAGE 15 -#endif - -#ifndef MADV_DONTDUMP -#define MADV_DONTDUMP 16 -#endif - -#ifndef MADV_DODUMP -#define MADV_DODUMP 17 -#endif - - static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, struct syscall_arg *arg) { From fbef103fad5009827965b10aedbecb1786904f4d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 12 Sep 2016 16:47:57 -0300 Subject: [PATCH 05/22] perf tools: Do hugetlb handling in more systems The csets: 0ac3348e5024 ("perf tools: Recognize hugetlb mapping as anon mapping") d7e404af115b ("perf record: Mark MAP_HUGETLB when synthesizing mmap events") Added code conditional on MAP_HUGETLB, to make it build in older systems where that define wasn't available. Now that we grabbed copies of uapi/linux/mmap.h to have all those definitions in tools/, use it so that we can support building the tools for older systems (without the MAP_HUGETLB define in its libc headers) using new kernels that support such maps. Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Cc: Zefan Li Link: http://lkml.kernel.org/n/tip-wv6oqbfkpxbix4umj2kcfmaz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.c | 7 ++----- tools/perf/util/map.c | 9 ++------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 6c3017139c67..2880e2226fdb 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -1,5 +1,5 @@ #include -#include +#include /* To get things like MAP_HUGETLB even on older libc headers */ #include #include "event.h" #include "debug.h" @@ -249,10 +249,8 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool, bool truncation = false; unsigned long long timeout = proc_map_timeout * 1000000ULL; int rc = 0; -#ifdef MAP_HUGETLB const char *hugetlbfs_mnt = hugetlbfs__mountpoint(); int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0; -#endif if (machine__is_default_guest(machine)) return 0; @@ -347,12 +345,11 @@ out: if (!strcmp(execname, "")) strcpy(execname, anonstr); -#ifdef MAP_HUGETLB + if (!strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) { strcpy(execname, anonstr); event->mmap2.flags |= MAP_HUGETLB; } -#endif size = strlen(execname) + 1; memcpy(event->mmap2.filename, execname, size); diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index d51a1257973b..c662fef95d14 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include /* To get things like MAP_HUGETLB even on older libc headers */ #include "map.h" #include "thread.h" #include "strlist.h" @@ -27,12 +27,7 @@ const char *map_type__name[MAP__NR_TYPES] = { static inline int is_anon_memory(const char *filename, u32 flags) { - u32 anon_flags = 0; - -#ifdef MAP_HUGETLB - anon_flags |= MAP_HUGETLB; -#endif - return flags & anon_flags || + return flags & MAP_HUGETLB || !strcmp(filename, "//anon") || !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) || !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1); From 0a4a7e435f458e996d0f21a9ebc964e0b0d64eba Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Mon, 12 Sep 2016 12:54:31 +0000 Subject: [PATCH 06/22] perf build: Compare mman.h related headers against kernel originals As with other cloned headers, compare the newly introduced mman related headers against their source copy in kernel tree. Signed-off-by: Wang Nan Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1473684871-209320-4-git-send-email-wangnan0@huawei.com [ Added -I to ignore the uapi/ difference ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 828cfd766e31..d710db16b963 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -432,6 +432,15 @@ $(PERF_IN): prepare FORCE @(test -f ../../include/linux/coresight-pmu.h && ( \ (diff -B ../include/linux/coresight-pmu.h ../../include/linux/coresight-pmu.h >/dev/null) \ || echo "Warning: tools/include/linux/coresight-pmu.h differs from kernel" >&2 )) || true + @(test -f ../../include/uapi/asm-generic/mman-common.h && ( \ + (diff -B ../include/uapi/asm-generic/mman-common.h ../../include/uapi/asm-generic/mman-common.h >/dev/null) \ + || echo "Warning: tools/include/uapi/asm-generic/mman-common.h differs from kernel" >&2 )) || true + @(test -f ../../include/uapi/asm-generic/mman.h && ( \ + (diff -B -I "^#include <\(uapi/\)*asm-generic/mman-common.h>$$" ../include/uapi/asm-generic/mman.h ../../include/uapi/asm-generic/mman.h >/dev/null) \ + || echo "Warning: tools/include/uapi/asm-generic/mman.h differs from kernel" >&2 )) || true + @(test -f ../../include/uapi/linux/mman.h && ( \ + (diff -B -I "^#include <\(uapi/\)*asm/mman.h>$$" ../include/uapi/linux/mman.h ../../include/uapi/linux/mman.h >/dev/null) \ + || echo "Warning: tools/include/uapi/linux/mman.h differs from kernel" >&2 )) || true $(Q)$(MAKE) $(build)=perf $(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) From 09034de63e427a86ba96bedf39410eef7c9014a5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Sep 2016 16:45:46 +0900 Subject: [PATCH 07/22] perf hists: Introduce hists__match_hierarchy() The hists__match_hierarchy() is to find matching hist entries in a group. A matching entry has the same values for all sort keys given. With an event group (e.g.: -e "{cycles,instructions}"), a leader event should show other members in a group. So each entry in the leader should be able to find its pair entries which have same values. With hierarchy mode, it needs to search all matching children in a hierarchy. An example output looks like: # Overhead Command / Shared Object / Symbol # ...................... .................................. # 25.74% 27.18% sh 19.96% 24.14% libc-2.24.so 9.55% 14.64% [.] __strcmp_sse2 1.54% 0.00% [.] __tfind 1.07% 1.13% [.] _int_malloc ... In the above example, two overheads are shown - one for the leader and another for the other group member. They were matched since their command, dso and symbol have the same values. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160913074552.13284-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 51 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index de15dbcdcecf..be3f5ce31303 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2174,6 +2174,51 @@ static struct hist_entry *hists__find_entry(struct hists *hists, return NULL; } +static struct hist_entry *hists__find_hierarchy_entry(struct rb_root *root, + struct hist_entry *he) +{ + struct rb_node *n = root->rb_node; + + while (n) { + struct hist_entry *iter; + struct perf_hpp_fmt *fmt; + int64_t cmp = 0; + + iter = rb_entry(n, struct hist_entry, rb_node_in); + perf_hpp_list__for_each_sort_list(he->hpp_list, fmt) { + cmp = fmt->collapse(fmt, iter, he); + if (cmp) + break; + } + + if (cmp < 0) + n = n->rb_left; + else if (cmp > 0) + n = n->rb_right; + else + return iter; + } + + return NULL; +} + +static void hists__match_hierarchy(struct rb_root *leader_root, + struct rb_root *other_root) +{ + struct rb_node *nd; + struct hist_entry *pos, *pair; + + for (nd = rb_first(leader_root); nd; nd = rb_next(nd)) { + pos = rb_entry(nd, struct hist_entry, rb_node_in); + pair = hists__find_hierarchy_entry(other_root, pos); + + if (pair) { + hist_entry__add_pair(pair, pos); + hists__match_hierarchy(&pos->hroot_in, &pair->hroot_in); + } + } +} + /* * Look for pairs to link to the leader buckets (hist_entries): */ @@ -2183,6 +2228,12 @@ void hists__match(struct hists *leader, struct hists *other) struct rb_node *nd; struct hist_entry *pos, *pair; + if (symbol_conf.report_hierarchy) { + /* hierarchy report always collapses entries */ + return hists__match_hierarchy(&leader->entries_collapsed, + &other->entries_collapsed); + } + if (hists__has(leader, need_collapse)) root = &leader->entries_collapsed; else From 9d97b8f512a0dd41819b8e3d9cdc7a59199e1b0c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Sep 2016 16:45:47 +0900 Subject: [PATCH 08/22] perf hists: Introduce hists__link_hierarchy() The hists__link_hierarchy() is to support hierarchy reports with an event group. When it matches the leader event and the other members (using hists__match_hierarchy()), it also needs to link unmatched member entries with a dummy leader event so that it can show up in the output. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160913074552.13284-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 95 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index be3f5ce31303..702ba3a8ead6 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -2149,6 +2149,50 @@ out: return he; } +static struct hist_entry *add_dummy_hierarchy_entry(struct hists *hists, + struct rb_root *root, + struct hist_entry *pair) +{ + struct rb_node **p; + struct rb_node *parent = NULL; + struct hist_entry *he; + struct perf_hpp_fmt *fmt; + + p = &root->rb_node; + while (*p != NULL) { + int64_t cmp = 0; + + parent = *p; + he = rb_entry(parent, struct hist_entry, rb_node_in); + + perf_hpp_list__for_each_sort_list(he->hpp_list, fmt) { + cmp = fmt->collapse(fmt, he, pair); + if (cmp) + break; + } + if (!cmp) + goto out; + + if (cmp < 0) + p = &parent->rb_left; + else + p = &parent->rb_right; + } + + he = hist_entry__new(pair, true); + if (he) { + rb_link_node(&he->rb_node_in, parent, p); + rb_insert_color(&he->rb_node_in, root); + + he->dummy = true; + he->hists = hists; + memset(&he->stat, 0, sizeof(he->stat)); + hists__inc_stats(hists, he); + } +out: + return he; +} + static struct hist_entry *hists__find_entry(struct hists *hists, struct hist_entry *he) { @@ -2248,6 +2292,50 @@ void hists__match(struct hists *leader, struct hists *other) } } +static int hists__link_hierarchy(struct hists *leader_hists, + struct hist_entry *parent, + struct rb_root *leader_root, + struct rb_root *other_root) +{ + struct rb_node *nd; + struct hist_entry *pos, *leader; + + for (nd = rb_first(other_root); nd; nd = rb_next(nd)) { + pos = rb_entry(nd, struct hist_entry, rb_node_in); + + if (hist_entry__has_pairs(pos)) { + bool found = false; + + list_for_each_entry(leader, &pos->pairs.head, pairs.node) { + if (leader->hists == leader_hists) { + found = true; + break; + } + } + if (!found) + return -1; + } else { + leader = add_dummy_hierarchy_entry(leader_hists, + leader_root, pos); + if (leader == NULL) + return -1; + + /* do not point parent in the pos */ + leader->parent_he = parent; + + hist_entry__add_pair(pos, leader); + } + + if (!pos->leaf) { + if (hists__link_hierarchy(leader_hists, leader, + &leader->hroot_in, + &pos->hroot_in) < 0) + return -1; + } + } + return 0; +} + /* * Look for entries in the other hists that are not present in the leader, if * we find them, just add a dummy entry on the leader hists, with period=0, @@ -2259,6 +2347,13 @@ int hists__link(struct hists *leader, struct hists *other) struct rb_node *nd; struct hist_entry *pos, *pair; + if (symbol_conf.report_hierarchy) { + /* hierarchy report always collapses entries */ + return hists__link_hierarchy(leader, NULL, + &leader->entries_collapsed, + &other->entries_collapsed); + } + if (hists__has(other, need_collapse)) root = &other->entries_collapsed; else From d2580c7a5b4e78bffda1e53cfd583e7a2c7383a5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Sep 2016 16:45:48 +0900 Subject: [PATCH 09/22] perf hist: Initialize hierarchy tree explicitly The hroot_in and hroot_out are roots of hierarchy trees of hist entries. But when a hist entry is initialized by copying existing template entry, it sometimes has non-empty tree and copies it incorrectly. This is a problem especially when an event group is used since it creates dummy entries from already-processed entries in other event members. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160913074552.13284-4-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 702ba3a8ead6..37a08f20730a 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -417,6 +417,8 @@ static int hist_entry__init(struct hist_entry *he, } INIT_LIST_HEAD(&he->pairs.node); thread__get(he->thread); + he->hroot_in = RB_ROOT; + he->hroot_out = RB_ROOT; if (!symbol_conf.report_hierarchy) he->leaf = true; From 9a6ad25b5a2026ba1399abc879ec623957867e79 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Sep 2016 16:45:49 +0900 Subject: [PATCH 10/22] perf ui/stdio: Always reset output width for hierarchy When the --hierarchy option is used, each entry has its own hpp_list to show the result. But it is not updating the width of each column for perf-top. The perf-report command has no problem since it resets it during header display. $ sudo perf top --hierarchy --stdio PerfTop: 160 irqs/sec kernel:38.8% exact: 100.0% [4000Hz cycles:pp], (all, 12 CPUs) ---------------------------------------------------------------------- 52.32% perf 24.74% [.] __symbols__insert 5.62% [.] rb_next 5.14% [.] dso__load_sym Move the code into hists__fprintf() so that it can be called always. Also it'd be better to put similar code together. Signed-off-by: Namhyung Kim Tested-by: Arnaldo Carvalho de Melo Cc: Andi Kleen Cc: Jiri Olsa Cc: Peter Zijlstra Fixes: 1b2dbbf41a0f ("perf hists: Use own hpp_list for hierarchy mode") Link: http://lkml.kernel.org/r/20160913074552.13284-5-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/stdio/hist.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 9b65f4a6b35a..18b4fd9342cd 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -628,14 +628,6 @@ hists__fprintf_hierarchy_headers(struct hists *hists, struct perf_hpp *hpp, FILE *fp) { - struct perf_hpp_list_node *fmt_node; - struct perf_hpp_fmt *fmt; - - list_for_each_entry(fmt_node, &hists->hpp_formats, list) { - perf_hpp_list__for_each_format(&fmt_node->hpp, fmt) - perf_hpp__reset_width(fmt, hists); - } - return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp); } @@ -733,6 +725,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, bool use_callchain) { struct perf_hpp_fmt *fmt; + struct perf_hpp_list_node *node; struct rb_node *nd; size_t ret = 0; const char *sep = symbol_conf.field_sep; @@ -745,6 +738,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, hists__for_each_format(hists, fmt) perf_hpp__reset_width(fmt, hists); + /* hierarchy entries have their own hpp list */ + list_for_each_entry(node, &hists->hpp_formats, list) { + perf_hpp_list__for_each_format(&node->hpp, fmt) + perf_hpp__reset_width(fmt, hists); + } if (symbol_conf.col_width_list_str) perf_hpp__set_user_width(symbol_conf.col_width_list_str); From 195bc0f8443d8d564ae95d2e9c19ac0edfd647c3 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Sep 2016 16:45:50 +0900 Subject: [PATCH 11/22] perf ui/stdio: Rename print_hierarchy_header() Now the hists__fprintf_hierarchy_headers() is a simple wrapper passing field separator. Let's do it directly. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160913074552.13284-6-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/stdio/hist.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 18b4fd9342cd..a57131e61fe3 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -528,8 +528,8 @@ static int print_hierarchy_indent(const char *sep, int indent, return fprintf(fp, "%-.*s", (indent - 2) * HIERARCHY_INDENT, line); } -static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, - const char *sep, FILE *fp) +static int hists__fprintf_hierarchy_headers(struct hists *hists, + struct perf_hpp *hpp, FILE *fp) { bool first_node, first_col; int indent; @@ -538,6 +538,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, unsigned header_width = 0; struct perf_hpp_fmt *fmt; struct perf_hpp_list_node *fmt_node; + const char *sep = symbol_conf.field_sep; indent = hists->nr_hpp_node; @@ -623,14 +624,6 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp, return 2; } -static int -hists__fprintf_hierarchy_headers(struct hists *hists, - struct perf_hpp *hpp, - FILE *fp) -{ - return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp); -} - static void fprintf_line(struct hists *hists, struct perf_hpp *hpp, int line, FILE *fp) { From 30d476ae738d1ce33f170dd79398ecd211274df6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 13 Sep 2016 16:45:52 +0900 Subject: [PATCH 12/22] perf report: Enable group view with hierarchy Now that all the missing pieces are implemented, let's enable it. An example output below: $ perf record -e '{cycles,instructions}' make $ perf report --hierarchy --stdio ... # Overhead Command / Shared Object / Symbol # ...................... .................................. # ... 25.74% 27.18% sh 19.96% 24.14% libc-2.24.so 9.55% 14.64% [.] __strcmp_sse2 1.54% 0.00% [.] __tfind 1.07% 1.13% [.] _int_malloc 0.95% 0.00% [.] __strchr_sse2 0.89% 1.39% [.] __tsearch 0.76% 0.00% [.] strlen ... Signed-off-by: Namhyung Kim Requested-by: Andi Kleen Tested-by: Arnaldo Carvalho de Melo Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160913074552.13284-8-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1a07c4cdf6ed..6e88460cd13d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -935,7 +935,6 @@ repeat: if (symbol_conf.report_hierarchy) { /* disable incompatible options */ - symbol_conf.event_group = false; symbol_conf.cumulate_callchain = false; if (field_order) { From dd60fba7324572498d91163e96b1cfe5cd5f7f3b Mon Sep 17 00:00:00 2001 From: Mathieu Poirier Date: Tue, 6 Sep 2016 10:37:15 -0600 Subject: [PATCH 13/22] perf tools: Add infrastructure for PMU specific configuration This patch adds PMU driver specific configuration to the parser infrastructure by preceding any term with the '@' letter. As such doing something like: perf record -e some_event/@cfg1,@cfg2=config/ ... will see 'cfg1' and 'cfg2=config' being added to the list of evsel config terms. Token 'cfg1' and 'cfg2=config' are not processed in user space and are meant to be interpreted by the PMU driver. First the lexer/parser are supplemented with the required definitions to recognise the driver specific configuration. From there they are simply added to the list of event terms. The bulk of the work is done in function "parse_events_add_pmu()" where driver config event terms are added to a new list of driver config terms, which in turn spliced with the event's new driver configuration list. Signed-off-by: Mathieu Poirier Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1473179837-3293-4-git-send-email-mathieu.poirier@linaro.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-record.txt | 12 ++++++++++++ tools/perf/util/evsel.h | 2 ++ tools/perf/util/parse-events.c | 7 ++++++- tools/perf/util/parse-events.h | 1 + tools/perf/util/parse-events.l | 22 ++++++++++++++++++++++ tools/perf/util/parse-events.y | 11 +++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index 379a2bed07c0..1a24f4d64328 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -60,6 +60,18 @@ OPTIONS Note: If user explicitly sets options which conflict with the params, the value set by the params will be overridden. + Also not defined in ...//format/* are PMU driver specific + configuration parameters. Any configuration parameter preceded by + the letter '@' is not interpreted in user space and sent down directly + to the PMU driver. For example: + + perf record -e some_event/@cfg1,@cfg2=config/ ... + + will see 'cfg1' and 'cfg2=config' pushed to the PMU driver associated + with the event for further processing. There is no restriction on + what the configuration parameters are, as long as their semantic is + understood and supported by the PMU driver. + - a hardware breakpoint event in the form of '\mem:addr[/len][:access]' where addr is the address in memory you want to break in. Access is the memory access type (read, write, execute) it can diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 4d44129e050b..323806082c58 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -46,6 +46,7 @@ enum { PERF_EVSEL__CONFIG_TERM_INHERIT, PERF_EVSEL__CONFIG_TERM_MAX_STACK, PERF_EVSEL__CONFIG_TERM_OVERWRITE, + PERF_EVSEL__CONFIG_TERM_DRV_CFG, PERF_EVSEL__CONFIG_TERM_MAX, }; @@ -57,6 +58,7 @@ struct perf_evsel_config_term { u64 freq; bool time; char *callgraph; + char *drv_cfg; u64 stack_user; int max_stack; bool inherit; diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6c913c3914fb..2eb8b1ed4cc8 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -904,6 +904,7 @@ static const char *config_term_names[__PARSE_EVENTS__TERM_TYPE_NR] = { [PARSE_EVENTS__TERM_TYPE_MAX_STACK] = "max-stack", [PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite", [PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite", + [PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config", }; static bool config_term_shrinked; @@ -1034,7 +1035,8 @@ static int config_term_pmu(struct perf_event_attr *attr, struct parse_events_term *term, struct parse_events_error *err) { - if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) + if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER || + term->type_term == PARSE_EVENTS__TERM_TYPE_DRV_CFG) /* * Always succeed for sysfs terms, as we dont know * at this point what type they need to have. @@ -1134,6 +1136,9 @@ do { \ case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1); break; + case PARSE_EVENTS__TERM_TYPE_DRV_CFG: + ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str); + break; default: break; } diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index d1edbf8cc66a..8d09a976fca8 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -71,6 +71,7 @@ enum { PARSE_EVENTS__TERM_TYPE_MAX_STACK, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE, PARSE_EVENTS__TERM_TYPE_OVERWRITE, + PARSE_EVENTS__TERM_TYPE_DRV_CFG, __PARSE_EVENTS__TERM_TYPE_NR, }; diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 7a2519435da0..9f43fda2570f 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -53,6 +53,26 @@ static int str(yyscan_t scanner, int token) return token; } +/* + * This function is called when the parser gets two kind of input: + * + * @cfg1 or @cfg2=config + * + * The leading '@' is stripped off before 'cfg1' and 'cfg2=config' are given to + * bison. In the latter case it is necessary to keep the string intact so that + * the PMU kernel driver can determine what configurable is associated to + * 'config'. + */ +static int drv_str(yyscan_t scanner, int token) +{ + YYSTYPE *yylval = parse_events_get_lval(scanner); + char *text = parse_events_get_text(scanner); + + /* Strip off the '@' */ + yylval->str = strdup(text + 1); + return token; +} + #define REWIND(__alloc) \ do { \ YYSTYPE *__yylval = parse_events_get_lval(yyscanner); \ @@ -124,6 +144,7 @@ num_hex 0x[a-fA-F0-9]+ num_raw_hex [a-fA-F0-9]+ name [a-zA-Z_*?][a-zA-Z0-9_*?.]* name_minus [a-zA-Z_*?][a-zA-Z0-9\-_*?.:]* +drv_cfg_term [a-zA-Z0-9_\.]+(=[a-zA-Z0-9_*?\.:]+)? /* If you add a modifier you need to update check_modifier() */ modifier_event [ukhpPGHSDI]+ modifier_bp [rwx]{1,3} @@ -209,6 +230,7 @@ no-overwrite { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NOOVERWRITE); } {name_minus} { return str(yyscanner, PE_NAME); } \[all\] { return PE_ARRAY_ALL; } "[" { BEGIN(array); return '['; } +@{drv_cfg_term} { return drv_str(yyscanner, PE_DRV_CFG_TERM); } } { diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 5be4a5f216d6..879115f93edc 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -49,6 +49,7 @@ static void inc_group_count(struct list_head *list, %token PE_ERROR %token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT %token PE_ARRAY_ALL PE_ARRAY_RANGE +%token PE_DRV_CFG_TERM %type PE_VALUE %type PE_VALUE_SYM_HW %type PE_VALUE_SYM_SW @@ -63,6 +64,7 @@ static void inc_group_count(struct list_head *list, %type PE_MODIFIER_BP %type PE_EVENT_NAME %type PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT +%type PE_DRV_CFG_TERM %type value_sym %type event_config %type opt_event_config @@ -599,6 +601,15 @@ PE_NAME array '=' PE_VALUE term->array = $2; $$ = term; } +| +PE_DRV_CFG_TERM +{ + struct parse_events_term *term; + + ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, + $1, $1, &@1, NULL)); + $$ = term; +} array: '[' array_terms ']' From f752e90e9c00da2a1994e2e1b1a04505b46a6a4c Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Wed, 14 Sep 2016 10:57:28 +0000 Subject: [PATCH 14/22] perf trace beauty mmap: Add missing MADV_FREE tools/perf/trace/beauty/mmap.c forgets to check MADV_FREE. This patch fixes it. Signed-off-by: Wang Nan Cc: Naveen N. Rao Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1473850649-83389-2-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/mmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index 3629b45b8e93..fd710ab33684 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c @@ -101,6 +101,7 @@ static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, P_MADV_BHV(SEQUENTIAL); P_MADV_BHV(WILLNEED); P_MADV_BHV(DONTNEED); + P_MADV_BHV(FREE); P_MADV_BHV(REMOVE); P_MADV_BHV(DONTFORK); P_MADV_BHV(DOFORK); From f82b77462b8680b84e8cce955b05a6629cb44b36 Mon Sep 17 00:00:00 2001 From: Wang Nan Date: Wed, 14 Sep 2016 10:57:29 +0000 Subject: [PATCH 15/22] tools include: Add mman macros needed by perf for all arch Some macros required by tools/perf/trace/beauty/mmap.c is not support for all architectures. For example, MAP_32BIT is defined on x86 only, alpha doesn't define MADV_HWPOISON and MADV_SOFT_OFFLINE. This patch regenerates mman.h for each arch, defines these missing macros for perf. For missing MADV_*, fall back to asm-generic/mman-common because they are in a 'case ...' statement. For flags, define it to 0. Following is the script to generate this patch: macros=`cat $0 | awk 'V==1 {print}; /^# start macro list/ {V=1}'` rm `find ./tools/arch/ -name mman.h` for arch in `ls tools/arch` do [ -d tools/arch/$arch/include/uapi/asm ] || mkdir -p tools/arch/$arch/include/uapi/asm src=arch/$arch/include/uapi/asm/mman.h target=tools/arch/$arch/include/uapi/asm/mman.h.tmp real_target=tools/arch/$arch/include/uapi/asm/mman.h guard="TOOLS_ARCH_"`echo $arch | awk '{print toupper($0)}'`_UAPI_ASM_MMAN_FIX_H rm -f $target [ -f $src ] && for m in $macros do if grep '#define[ \t]*'$m $src > /dev/null 2>&1 then grep -h '#define[ \t]*'$m $src | sed 's/[ \t]*\/\*.*$//g' >> $target fi done if [ -f $src ] then grep '#include > $target else echo "#include " >> $target fi touch $real_target for m in $macros do if cat << EOF | gcc -Itools/arch/$arch/include -Itools/arch/$arch/include/uapi -Iinclude/ -Iinclude/uapi -E - | grep $m > /dev/null 2>&1 #include #include $m EOF then echo "Fixing $m for $arch" echo "/* $m is undefined on $arch, fix it for perf */" >> $target if echo $m | grep '^MADV_' > /dev/null 2>&1 then grep -h '#define[ \t]*'$m include/uapi/asm-generic/mman-common.h | sed 's/[ \t]*\/\*.*$//g' >> $target else echo "#define $m 0" >> $target fi fi done real_target=tools/arch/$arch/include/uapi/asm/mman.h echo '#ifndef '$guard > $real_target echo '#define '$guard >> $real_target cat $target | sed 's|asm-generic|uapi/asm-generic|g' >> $real_target echo '#endif' >> $real_target rm $target echo "$real_target" done exit 0 # Following macros are extracted from: # tools/perf/trace/beauty/mmap.c # # start macro list MADV_DODUMP MADV_DOFORK MADV_DONTDUMP MADV_DONTFORK MADV_DONTNEED MADV_FREE MADV_HUGEPAGE MADV_HWPOISON MADV_MERGEABLE MADV_NOHUGEPAGE MADV_NORMAL MADV_RANDOM MADV_REMOVE MADV_SEQUENTIAL MADV_SOFT_OFFLINE MADV_UNMERGEABLE MADV_WILLNEED MAP_32BIT MAP_ANONYMOUS MAP_DENYWRITE MAP_EXECUTABLE MAP_FILE MAP_FIXED MAP_GROWSDOWN MAP_HUGETLB MAP_LOCKED MAP_NONBLOCK MAP_NORESERVE MAP_POPULATE MAP_PRIVATE MAP_SHARED MAP_STACK MAP_UNINITIALIZED MREMAP_FIXED MREMAP_MAYMOVE PROT_EXEC PROT_GROWSDOWN PROT_GROWSUP PROT_NONE PROT_READ PROT_SEM PROT_WRITE Signed-off-by: Wang Nan Tested-by: Kim Phillips Tested-by: Naveen N. Rao Cc: Ravi Bangoria Cc: Zefan Li Cc: pi3orama@163.com Fixes: 277cf08f3feb ("perf trace beauty mmap: Fix defines for non !x86_64") Link: http://lkml.kernel.org/r/1473850649-83389-3-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/alpha/include/uapi/asm/mman.h | 9 +++++++++ tools/arch/arc/include/uapi/asm/mman.h | 2 ++ tools/arch/arm/include/uapi/asm/mman.h | 2 ++ tools/arch/arm64/include/uapi/asm/mman.h | 2 ++ tools/arch/frv/include/uapi/asm/mman.h | 2 ++ tools/arch/h8300/include/uapi/asm/mman.h | 2 ++ tools/arch/hexagon/include/uapi/asm/mman.h | 2 ++ tools/arch/ia64/include/uapi/asm/mman.h | 2 ++ tools/arch/m32r/include/uapi/asm/mman.h | 2 ++ tools/arch/microblaze/include/uapi/asm/mman.h | 2 ++ tools/arch/mips/include/uapi/asm/mman.h | 7 +++++++ tools/arch/mn10300/include/uapi/asm/mman.h | 2 ++ tools/arch/parisc/include/uapi/asm/mman.h | 9 +++++++++ tools/arch/powerpc/include/uapi/asm/mman.h | 2 ++ tools/arch/s390/include/uapi/asm/mman.h | 2 ++ tools/arch/score/include/uapi/asm/mman.h | 2 ++ tools/arch/sh/include/uapi/asm/mman.h | 2 ++ tools/arch/sparc/include/uapi/asm/mman.h | 2 ++ tools/arch/tile/include/uapi/asm/mman.h | 2 ++ tools/arch/xtensa/include/uapi/asm/mman.h | 9 +++++++++ 20 files changed, 66 insertions(+) diff --git a/tools/arch/alpha/include/uapi/asm/mman.h b/tools/arch/alpha/include/uapi/asm/mman.h index 6ed4ad44a289..e38b64c82b97 100644 --- a/tools/arch/alpha/include/uapi/asm/mman.h +++ b/tools/arch/alpha/include/uapi/asm/mman.h @@ -5,6 +5,7 @@ #define MADV_DONTDUMP 16 #define MADV_DONTFORK 10 #define MADV_DONTNEED 6 +#define MADV_FREE 8 #define MADV_HUGEPAGE 14 #define MADV_MERGEABLE 12 #define MADV_NOHUGEPAGE 15 @@ -35,4 +36,12 @@ #define PROT_READ 0x1 #define PROT_SEM 0x8 #define PROT_WRITE 0x2 +/* MADV_HWPOISON is undefined on alpha, fix it for perf */ +#define MADV_HWPOISON 100 +/* MADV_SOFT_OFFLINE is undefined on alpha, fix it for perf */ +#define MADV_SOFT_OFFLINE 101 +/* MAP_32BIT is undefined on alpha, fix it for perf */ +#define MAP_32BIT 0 +/* MAP_UNINITIALIZED is undefined on alpha, fix it for perf */ +#define MAP_UNINITIALIZED 0 #endif diff --git a/tools/arch/arc/include/uapi/asm/mman.h b/tools/arch/arc/include/uapi/asm/mman.h index f76765dbaafa..aa3acd2aa9af 100644 --- a/tools/arch/arc/include/uapi/asm/mman.h +++ b/tools/arch/arc/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on arc, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/arm/include/uapi/asm/mman.h b/tools/arch/arm/include/uapi/asm/mman.h index f2006385e203..478f699f56fd 100644 --- a/tools/arch/arm/include/uapi/asm/mman.h +++ b/tools/arch/arm/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on arm, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/arm64/include/uapi/asm/mman.h b/tools/arch/arm64/include/uapi/asm/mman.h index a7dd975bb33e..70fd3113710a 100644 --- a/tools/arch/arm64/include/uapi/asm/mman.h +++ b/tools/arch/arm64/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on arm64, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/frv/include/uapi/asm/mman.h b/tools/arch/frv/include/uapi/asm/mman.h index 99bba054e795..5be78ac12464 100644 --- a/tools/arch/frv/include/uapi/asm/mman.h +++ b/tools/arch/frv/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on frv, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/h8300/include/uapi/asm/mman.h b/tools/arch/h8300/include/uapi/asm/mman.h index df95096c2a7a..9d9ac54d3c5a 100644 --- a/tools/arch/h8300/include/uapi/asm/mman.h +++ b/tools/arch/h8300/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on h8300, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/hexagon/include/uapi/asm/mman.h b/tools/arch/hexagon/include/uapi/asm/mman.h index f1adcce90f37..102f3fae6085 100644 --- a/tools/arch/hexagon/include/uapi/asm/mman.h +++ b/tools/arch/hexagon/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on hexagon, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/ia64/include/uapi/asm/mman.h b/tools/arch/ia64/include/uapi/asm/mman.h index 23420eb30d92..1d6e5ac6442d 100644 --- a/tools/arch/ia64/include/uapi/asm/mman.h +++ b/tools/arch/ia64/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on ia64, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/m32r/include/uapi/asm/mman.h b/tools/arch/m32r/include/uapi/asm/mman.h index a35ebd68add9..1c29635bb73b 100644 --- a/tools/arch/m32r/include/uapi/asm/mman.h +++ b/tools/arch/m32r/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on m32r, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/microblaze/include/uapi/asm/mman.h b/tools/arch/microblaze/include/uapi/asm/mman.h index 75f460abbe58..005cd50b50e1 100644 --- a/tools/arch/microblaze/include/uapi/asm/mman.h +++ b/tools/arch/microblaze/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on microblaze, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/mips/include/uapi/asm/mman.h b/tools/arch/mips/include/uapi/asm/mman.h index db88fa41e74c..c02052965d50 100644 --- a/tools/arch/mips/include/uapi/asm/mman.h +++ b/tools/arch/mips/include/uapi/asm/mman.h @@ -5,6 +5,7 @@ #define MADV_DONTDUMP 16 #define MADV_DONTFORK 10 #define MADV_DONTNEED 4 +#define MADV_FREE 8 #define MADV_HUGEPAGE 14 #define MADV_HWPOISON 100 #define MADV_MERGEABLE 12 @@ -36,4 +37,10 @@ #define PROT_READ 0x01 #define PROT_SEM 0x10 #define PROT_WRITE 0x02 +/* MADV_SOFT_OFFLINE is undefined on mips, fix it for perf */ +#define MADV_SOFT_OFFLINE 101 +/* MAP_32BIT is undefined on mips, fix it for perf */ +#define MAP_32BIT 0 +/* MAP_UNINITIALIZED is undefined on mips, fix it for perf */ +#define MAP_UNINITIALIZED 0 #endif diff --git a/tools/arch/mn10300/include/uapi/asm/mman.h b/tools/arch/mn10300/include/uapi/asm/mman.h index 81faa5d1b2dc..c1ea36d83acc 100644 --- a/tools/arch/mn10300/include/uapi/asm/mman.h +++ b/tools/arch/mn10300/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on mn10300, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/parisc/include/uapi/asm/mman.h b/tools/arch/parisc/include/uapi/asm/mman.h index c4a9d9f12d55..03d8d5b7ae7f 100644 --- a/tools/arch/parisc/include/uapi/asm/mman.h +++ b/tools/arch/parisc/include/uapi/asm/mman.h @@ -5,6 +5,7 @@ #define MADV_DONTDUMP 69 #define MADV_DONTFORK 10 #define MADV_DONTNEED 4 +#define MADV_FREE 8 #define MADV_HUGEPAGE 67 #define MADV_MERGEABLE 65 #define MADV_NOHUGEPAGE 68 @@ -35,4 +36,12 @@ #define PROT_READ 0x1 #define PROT_SEM 0x8 #define PROT_WRITE 0x2 +/* MADV_HWPOISON is undefined on parisc, fix it for perf */ +#define MADV_HWPOISON 100 +/* MADV_SOFT_OFFLINE is undefined on parisc, fix it for perf */ +#define MADV_SOFT_OFFLINE 101 +/* MAP_32BIT is undefined on parisc, fix it for perf */ +#define MAP_32BIT 0 +/* MAP_UNINITIALIZED is undefined on parisc, fix it for perf */ +#define MAP_UNINITIALIZED 0 #endif diff --git a/tools/arch/powerpc/include/uapi/asm/mman.h b/tools/arch/powerpc/include/uapi/asm/mman.h index 7a56ab9988dd..761db43172fe 100644 --- a/tools/arch/powerpc/include/uapi/asm/mman.h +++ b/tools/arch/powerpc/include/uapi/asm/mman.h @@ -10,4 +10,6 @@ #define MAP_POPULATE 0x8000 #define MAP_STACK 0x20000 #include +/* MAP_32BIT is undefined on powerpc, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/s390/include/uapi/asm/mman.h b/tools/arch/s390/include/uapi/asm/mman.h index fe53b91405d3..b03dea9e1f56 100644 --- a/tools/arch/s390/include/uapi/asm/mman.h +++ b/tools/arch/s390/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on s390, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/score/include/uapi/asm/mman.h b/tools/arch/score/include/uapi/asm/mman.h index ba1ee9ce9f6a..2f8fb89944fd 100644 --- a/tools/arch/score/include/uapi/asm/mman.h +++ b/tools/arch/score/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on score, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/sh/include/uapi/asm/mman.h b/tools/arch/sh/include/uapi/asm/mman.h index 5a47d8cff786..26504f6f060e 100644 --- a/tools/arch/sh/include/uapi/asm/mman.h +++ b/tools/arch/sh/include/uapi/asm/mman.h @@ -1,4 +1,6 @@ #ifndef TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H #define TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H #include +/* MAP_32BIT is undefined on sh, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/sparc/include/uapi/asm/mman.h b/tools/arch/sparc/include/uapi/asm/mman.h index b88f3ac9c48a..8640525de991 100644 --- a/tools/arch/sparc/include/uapi/asm/mman.h +++ b/tools/arch/sparc/include/uapi/asm/mman.h @@ -10,4 +10,6 @@ #define MAP_POPULATE 0x8000 #define MAP_STACK 0x20000 #include +/* MAP_32BIT is undefined on sparc, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/tile/include/uapi/asm/mman.h b/tools/arch/tile/include/uapi/asm/mman.h index b0a054f27a22..7116c4b928b3 100644 --- a/tools/arch/tile/include/uapi/asm/mman.h +++ b/tools/arch/tile/include/uapi/asm/mman.h @@ -10,4 +10,6 @@ #define MAP_POPULATE 0x0040 #define MAP_STACK MAP_GROWSDOWN #include +/* MAP_32BIT is undefined on tile, fix it for perf */ +#define MAP_32BIT 0 #endif diff --git a/tools/arch/xtensa/include/uapi/asm/mman.h b/tools/arch/xtensa/include/uapi/asm/mman.h index 1c89538bd391..4453195c450c 100644 --- a/tools/arch/xtensa/include/uapi/asm/mman.h +++ b/tools/arch/xtensa/include/uapi/asm/mman.h @@ -5,6 +5,7 @@ #define MADV_DONTDUMP 16 #define MADV_DONTFORK 10 #define MADV_DONTNEED 4 +#define MADV_FREE 8 #define MADV_HUGEPAGE 14 #define MADV_MERGEABLE 12 #define MADV_NOHUGEPAGE 15 @@ -35,4 +36,12 @@ #define PROT_READ 0x1 #define PROT_SEM 0x10 #define PROT_WRITE 0x2 +/* MADV_HWPOISON is undefined on xtensa, fix it for perf */ +#define MADV_HWPOISON 100 +/* MADV_SOFT_OFFLINE is undefined on xtensa, fix it for perf */ +#define MADV_SOFT_OFFLINE 101 +/* MAP_32BIT is undefined on xtensa, fix it for perf */ +#define MAP_32BIT 0 +/* MAP_UNINITIALIZED is undefined on xtensa, fix it for perf */ +#define MAP_UNINITIALIZED 0 #endif From f666ac0dab5afaf6ebed2c361251581bfccc4003 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 19 Sep 2016 15:10:10 +0200 Subject: [PATCH 16/22] perf hists: Fix width computation for srcline sort entry Adding header size to width computation for srcline sort entry, because it's possible to get empty data with ':0' which set width of 2 which is lower than width needed to display column header. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: David Ahern Cc: Don Zickus Cc: Joe Mario Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1474290610-23241-62-git-send-email-jolsa@kernel.org [ Added declaration to sort.h ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/hist.c | 6 ++++-- tools/perf/util/sort.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 37a08f20730a..b02992efb513 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -177,8 +177,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12); hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12); - if (h->srcline) - hists__new_col_len(hists, HISTC_SRCLINE, strlen(h->srcline)); + if (h->srcline) { + len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header)); + hists__new_col_len(hists, HISTC_SRCLINE, len); + } if (h->srcfile) hists__new_col_len(hists, HISTC_SRCFILE, strlen(h->srcfile)); diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index 28c0524c8702..9505483cb95c 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -40,6 +40,7 @@ extern struct sort_entry sort_dso_from; extern struct sort_entry sort_dso_to; extern struct sort_entry sort_sym_from; extern struct sort_entry sort_sym_to; +extern struct sort_entry sort_srcline; extern enum sort_type sort__first_dimension; extern const char default_mem_sort_order[]; From 88a7fcf961a27fbd248e3c914fc9df8327f7cdbb Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Fri, 19 Aug 2016 18:29:35 +0530 Subject: [PATCH 17/22] perf annotate: Do not ignore call instruction with indirect target Do not ignore call instruction with indirect target when its already identified as a call. This is an extension of commit e8ea1561952b ("perf annotate: Use raw form for register indirect call instructions") to generalize annotation for all instructions with indirect calls. This is needed for certain powerpc call instructions that use address in a register (such as bctrl, btarl, ...). Apart from that, when kcore is used to disassemble function, all call instructions were ignored. This patch will fix it as a side effect by not ignoring them. For example, Before (with kcore): mov %r13,%rdi callq 0xffffffff811a7e70 ^ jmpq 64 mov %gs:0x7ef41a6e(%rip),%al After (with kcore): mov %r13,%rdi > callq 0xffffffff811a7e70 ^ jmpq 64 mov %gs:0x7ef41a6e(%rip),%al Suggested-by: Michael Ellerman [Suggested about 'bctrl' instruction] Signed-off-by: Ravi Bangoria Cc: Alexander Shishkin Cc: Chris Riyder Cc: Hemant Kumar Cc: Jiri Olsa Cc: Markus Trippelsdorf Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Pawel Moll Cc: Peter Zijlstra Cc: Russell King Cc: Taeung Song Link: http://lkml.kernel.org/r/1471611578-11255-5-git-send-email-ravi.bangoria@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7a80c7362a03..60e915f392a6 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -82,16 +82,12 @@ static int call__parse(struct ins_operands *ops) return ops->target.name == NULL ? -1 : 0; indirect_call: - tok = strchr(endptr, '('); - if (tok != NULL) { + tok = strchr(endptr, '*'); + if (tok == NULL) { ops->target.addr = 0; return 0; } - tok = strchr(endptr, '*'); - if (tok == NULL) - return -1; - ops->target.addr = strtoull(tok + 1, NULL, 16); return 0; } From bff5c3061374c37ed1262131eb333f714e5bcdf8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Sep 2016 17:18:16 -0300 Subject: [PATCH 18/22] perf annotate: Pass the symbol's map/dso to the instruction parsers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that things like: → callq 0xffffffff993e3230 found while disassembling /proc/kcore can be beautified by later patches, that will resolve that address to a function, looking it up in /proc/kallsyms. Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Chris Riyder Cc: David Ahern Cc: Hemant Kumar Cc: Jiri Olsa Cc: Markus Trippelsdorf Cc: Masami Hiramatsu Cc: Michael Ellerman Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Pawel Moll Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Russell King Cc: Taeung Song Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-p76myuke4j7gplg54amaklxk@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 23 ++++++++++++----------- tools/perf/util/annotate.h | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 60e915f392a6..aef841706dff 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -54,7 +54,7 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, return ins__raw_scnprintf(ins, bf, size, ops); } -static int call__parse(struct ins_operands *ops) +static int call__parse(struct ins_operands *ops, struct map *map __maybe_unused) { char *endptr, *tok, *name; @@ -114,7 +114,7 @@ bool ins__is_call(const struct ins *ins) return ins->ops == &call_ops; } -static int jump__parse(struct ins_operands *ops) +static int jump__parse(struct ins_operands *ops, struct map *map __maybe_unused) { const char *s = strchr(ops->raw, '+'); @@ -169,7 +169,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) return 0; } -static int lock__parse(struct ins_operands *ops) +static int lock__parse(struct ins_operands *ops, struct map *map) { char *name; @@ -190,7 +190,7 @@ static int lock__parse(struct ins_operands *ops) return 0; if (ops->locked.ins->ops->parse && - ops->locked.ins->ops->parse(ops->locked.ops) < 0) + ops->locked.ins->ops->parse(ops->locked.ops, map) < 0) goto out_free_ops; return 0; @@ -233,7 +233,7 @@ static struct ins_ops lock_ops = { .scnprintf = lock__scnprintf, }; -static int mov__parse(struct ins_operands *ops) +static int mov__parse(struct ins_operands *ops, struct map *map __maybe_unused) { char *s = strchr(ops->raw, ','), *target, *comment, prev; @@ -300,7 +300,7 @@ static struct ins_ops mov_ops = { .scnprintf = mov__scnprintf, }; -static int dec__parse(struct ins_operands *ops) +static int dec__parse(struct ins_operands *ops, struct map *map __maybe_unused) { char *target, *comment, *s, prev; @@ -705,7 +705,7 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 ip) return symbol__inc_addr_samples(he->ms.sym, he->ms.map, evidx, ip); } -static void disasm_line__init_ins(struct disasm_line *dl) +static void disasm_line__init_ins(struct disasm_line *dl, struct map *map) { dl->ins = ins__find(dl->name); @@ -715,7 +715,7 @@ static void disasm_line__init_ins(struct disasm_line *dl) if (!dl->ins->ops) return; - if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops) < 0) + if (dl->ins->ops->parse && dl->ins->ops->parse(&dl->ops, map) < 0) dl->ins = NULL; } @@ -757,7 +757,8 @@ out_free_name: } static struct disasm_line *disasm_line__new(s64 offset, char *line, - size_t privsize, int line_nr) + size_t privsize, int line_nr, + struct map *map) { struct disasm_line *dl = zalloc(sizeof(*dl) + privsize); @@ -772,7 +773,7 @@ static struct disasm_line *disasm_line__new(s64 offset, char *line, if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0) goto out_free_line; - disasm_line__init_ins(dl); + disasm_line__init_ins(dl, map); } } @@ -1144,7 +1145,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, parsed_line = tmp2 + 1; } - dl = disasm_line__new(offset, parsed_line, privsize, *line_nr); + dl = disasm_line__new(offset, parsed_line, privsize, *line_nr, map); free(line); (*line_nr)++; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index ea44e4ff19c6..5bbcec173b82 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -36,7 +36,7 @@ struct ins_operands { struct ins_ops { void (*free)(struct ins_operands *ops); - int (*parse)(struct ins_operands *ops); + int (*parse)(struct ins_operands *ops, struct map *map); int (*scnprintf)(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); }; From 5f62d4fd3593bc5bb33c75238cc1d6bf0b34fac9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 19 Sep 2016 17:26:11 -0300 Subject: [PATCH 19/22] perf annotate: Resolve 'call' operands to function names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this patch the '_raw_spin_lock_irqsave' and 'update_rq_clock' operands were appearing just as hexadecimal numbers: update_blocked_averages /proc/kcore │ push %r12 │ push %rbx │ and $0xfffffffffffffff0,%rsp │ sub $0x40,%rsp │ add -0x662cac00(,%rdi,8),%rax │ mov %rax,%rbx │ mov %rax,%rdi │ mov %rax,0x38(%rsp) │ → callq _raw_spin_lock_irqsave │ mov %rbx,%rdi │ mov %rax,0x30(%rsp) │ → callq update_rq_clock │ mov 0x8d0(%rbx),%rax │ lea 0x8d0(%rbx),%r11 To check that all is right one can always use the 'o' hotkey and see the original objdump -dS output, that for this case is: update_blocked_averages /proc/kcore │ffffffff990d5489: push %r12 │ffffffff990d548b: push %rbx │ffffffff990d548c: and $0xfffffffffffffff0,%rsp │ffffffff990d5490: sub $0x40,%rsp │ffffffff990d5494: add -0x662cac00(,%rdi,8),%rax │ffffffff990d549c: mov %rax,%rbx │ffffffff990d549f: mov %rax,%rdi │ffffffff990d54a2: mov %rax,0x38(%rsp) │ffffffff990d54a7: → callq 0xffffffff997eb7a0 │ffffffff990d54ac: mov %rbx,%rdi │ffffffff990d54af: mov %rax,0x30(%rsp) │ffffffff990d54b4: → callq 0xffffffff990c7720 │ffffffff990d54b9: mov 0x8d0(%rbx),%rax │ffffffff990d54c0: lea 0x8d0(%rbx),%r11 Use the 'h' hotkey to see a list of available hotkeys. More work needed to cover operands for other instructions, such as 'mov', that can resolve variable names, etc. Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Chris Riyder Cc: David Ahern Cc: Hemant Kumar Cc: Jiri Olsa Cc: Markus Trippelsdorf Cc: Masami Hiramatsu Cc: Michael Ellerman Cc: Namhyung Kim Cc: Naveen N. Rao Cc: Pawel Moll Cc: Peter Zijlstra Cc: Ravi Bangoria Cc: Russell King Cc: Taeung Song Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-xqgtw9mzmzcjgwkis9kiiv1p@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index aef841706dff..aeb5a441bd74 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -54,7 +54,7 @@ int ins__scnprintf(struct ins *ins, char *bf, size_t size, return ins__raw_scnprintf(ins, bf, size, ops); } -static int call__parse(struct ins_operands *ops, struct map *map __maybe_unused) +static int call__parse(struct ins_operands *ops, struct map *map) { char *endptr, *tok, *name; @@ -84,7 +84,11 @@ static int call__parse(struct ins_operands *ops, struct map *map __maybe_unused) indirect_call: tok = strchr(endptr, '*'); if (tok == NULL) { - ops->target.addr = 0; + struct symbol *sym = map__find_symbol(map, map->map_ip(map, ops->target.addr)); + if (sym != NULL) + ops->target.name = strdup(sym->name); + else + ops->target.addr = 0; return 0; } From 5ff3e7a224d40f9dd73625b91377787034a8b35e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 20 Sep 2016 14:30:23 +0900 Subject: [PATCH 20/22] perf ui/tui: Reset output width for hierarchy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When --hierarchy option is used, each entry has its own hpp_list to show the result. But it missed to update width of each column. Before: - 46.29% 48.12% netctl-auto + 31.44% 29.25% [kernel.vmlinux] + 8.52% 11.55% libc-2.22.so + 5.19% 6.91% bash + 10.75% 11.83% wpa_cli + 8.25% 2.23% swapper + 6.45% 5.40% tr + 4.81% 8.09% awk + 4.15% 2.85% firefox + 3.86% 2.53% sh After: - 46.29% 48.12% netctl-auto + 31.44% 29.25% [kernel.vmlinux] + 8.52% 11.55% libc-2.22.so + 5.19% 6.91% bash + 10.75% 11.83% wpa_cli + 8.25% 2.23% swapper + 6.45% 5.40% tr + 4.81% 8.09% awk + 4.15% 2.85% firefox + 3.86% 2.53% sh Committer note: Full testing instructions: 1) Record with an event group: $ perf record -e '{cycles,instructions}' make -j4 2) Use report in hierarchy mode, to get a few expanded trees on the same screen, use --percent-limit: $ perf report --hierarchy --percent-limit 0.5 Samples: 103K of event 'anon group { cycles:u, instructions:u }', Event count (approx.): 57317631725 Overhead Command / Shared Object / Symbol ◆ - 58.89% 55.12% cc1 ▒ - 50.26% 48.10% cc1 ▒ 3.61% 5.13% [.] _cpp_lex_token ▒ 2.58% 0.78% [.] ht_lookup_with_hash ▒ 1.31% 1.30% [.] ggc_internal_alloc ▒ 1.08% 2.25% [.] get_combined_adhoc_loc ▒ 1.01% 1.95% [.] ira_init ▒ 0.96% 1.78% [.] linemap_position_for_column ▒ 0.65% 1.01% [.] cpp_get_token_with_location ▒ - 7.52% 6.58% libc-2.23.so ▒ 1.70% 1.78% [.] _int_malloc ▒ 0.69% 0.75% [.] _int_free ▒ 0.67% 0.42% [.] malloc_consolidate ▒ - 0.58% 0.42% ld-2.23.so ▒ no entry >= 0.50% ▒ - 0.52% 0.03% [kernel.vmlinux] ▒ no entry >= 0.50% ▒ Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Andi Kleen Cc: Peter Zijlstra Fixes: 1b2dbbf41a0f ("perf hists: Use own hpp_list for hierarchy mode") Link: http://lkml.kernel.org/r/20160920053025.13989-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 35e44b1879e3..49db16334814 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2067,6 +2067,7 @@ void hist_browser__init(struct hist_browser *browser, struct hists *hists) { struct perf_hpp_fmt *fmt; + struct perf_hpp_list_node *node; browser->hists = hists; browser->b.refresh = hist_browser__refresh; @@ -2079,6 +2080,11 @@ void hist_browser__init(struct hist_browser *browser, perf_hpp__reset_width(fmt, hists); ++browser->b.columns; } + /* hierarchy entries have their own hpp list */ + list_for_each_entry(node, &hists->hpp_formats, list) { + perf_hpp_list__for_each_format(&node->hpp, fmt) + perf_hpp__reset_width(fmt, hists); + } } struct hist_browser *hist_browser__new(struct hists *hists) From e3b60bc93d81e0542ac433df226b8de8b963533e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 20 Sep 2016 14:30:24 +0900 Subject: [PATCH 21/22] perf hists: Factor out hists__reset_column_width() The stdio and tui has same code to reset hpp format column width. Factor it out as a new function. Suggested-and-Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160920053025.13989-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 12 +++--------- tools/perf/ui/hist.c | 15 +++++++++++++++ tools/perf/ui/stdio/hist.c | 10 +--------- tools/perf/util/hist.h | 1 + 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 49db16334814..a6d5d248b8fb 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -2067,7 +2067,6 @@ void hist_browser__init(struct hist_browser *browser, struct hists *hists) { struct perf_hpp_fmt *fmt; - struct perf_hpp_list_node *node; browser->hists = hists; browser->b.refresh = hist_browser__refresh; @@ -2076,15 +2075,10 @@ void hist_browser__init(struct hist_browser *browser, browser->b.use_navkeypressed = true; browser->show_headers = symbol_conf.show_hist_headers; - hists__for_each_format(hists, fmt) { - perf_hpp__reset_width(fmt, hists); + hists__for_each_format(hists, fmt) ++browser->b.columns; - } - /* hierarchy entries have their own hpp list */ - list_for_each_entry(node, &hists->hpp_formats, list) { - perf_hpp_list__for_each_format(&node->hpp, fmt) - perf_hpp__reset_width(fmt, hists); - } + + hists__reset_column_width(hists); } struct hist_browser *hist_browser__new(struct hists *hists) diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index b47fafc8ee2a..60c4a4d08374 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -699,6 +699,21 @@ void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists) } } +void hists__reset_column_width(struct hists *hists) +{ + struct perf_hpp_fmt *fmt; + struct perf_hpp_list_node *node; + + hists__for_each_format(hists, fmt) + perf_hpp__reset_width(fmt, hists); + + /* hierarchy entries have their own hpp list */ + list_for_each_entry(node, &hists->hpp_formats, list) { + perf_hpp_list__for_each_format(&node->hpp, fmt) + perf_hpp__reset_width(fmt, hists); + } +} + void perf_hpp__set_user_width(const char *width_list_str) { struct perf_hpp_fmt *fmt; diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index a57131e61fe3..8e1840bff29d 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -717,8 +717,6 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, int max_cols, float min_pcnt, FILE *fp, bool use_callchain) { - struct perf_hpp_fmt *fmt; - struct perf_hpp_list_node *node; struct rb_node *nd; size_t ret = 0; const char *sep = symbol_conf.field_sep; @@ -729,13 +727,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, init_rem_hits(); - hists__for_each_format(hists, fmt) - perf_hpp__reset_width(fmt, hists); - /* hierarchy entries have their own hpp list */ - list_for_each_entry(node, &hists->hpp_formats, list) { - perf_hpp_list__for_each_format(&node->hpp, fmt) - perf_hpp__reset_width(fmt, hists); - } + hists__reset_column_width(hists); if (symbol_conf.col_width_list_str) perf_hpp__set_user_width(symbol_conf.col_width_list_str); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a002c93fe422..defa957f27df 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -368,6 +368,7 @@ static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format, void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists); void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists); void perf_hpp__set_user_width(const char *width_list_str); +void hists__reset_column_width(struct hists *hists); typedef u64 (*hpp_field_fn)(struct hist_entry *he); typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front); From 3c028a0cb5b71f47d523bc8ad2c597cb257f41fb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 20 Sep 2016 18:12:45 +0200 Subject: [PATCH 22/22] perf symbols: Do not open device files The dso__read_binary_type_filename gets the dso's file name to open. We need to check it for regular file before trying to open it, otherwise we might get stuck with device file. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: David Ahern Cc: Don Zickus Cc: Joe Mario Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20160920161245.GA8995@krava Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 774f6ec884d5..d2c6cdd9d42b 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -363,6 +363,9 @@ static int __open_dso(struct dso *dso, struct machine *machine) return -EINVAL; } + if (!is_regular_file(name)) + return -EINVAL; + fd = do_open(name); free(name); return fd;