Merge tag 'perf-core-for-mingo-20160920' of git://git.kernel.org/pub/scm/linux/kernel...
authorIngo Molnar <mingo@kernel.org>
Tue, 20 Sep 2016 21:32:02 +0000 (23:32 +0200)
committerIngo Molnar <mingo@kernel.org>
Tue, 20 Sep 2016 21:32:02 +0000 (23:32 +0200)
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

User visible changes:

- Support event group view with hierarchy mode in 'perf top' and 'perf report'
  (Namhyung Kim)

  e.g.:

  $ 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

- Fix the dwarf regs table for x86_64, adding a missing % to the "%di"
  register, noticed with a failing 'perf test bpf' (Arnaldo Carvalho de Melo)

- Fix handling of mmap parameters in the 'perf trace' beautifier in
  architectures that don't have the same mappings as x86_64 (Wang Nan)

- Handle hugetbl mappings in older systems running new kernels (Wang Nan)

- Resolve 'call' operands in 'annotate', that when using /proc/kcore
  were appearing just as hexadecimal addresses, to function names
  (Arnaldo Carvalho de Melo)

- Fix width computation for srcline sort entry (Jiri Olsa)

- Do not ignore call instruction with indirect target in 'annotate'
  (Ravi Bangoria)

- Handle MADV_FREE in the madvise 'trace' beautifier (Wang Nan)

- Fix build of 'perf trace' mman beautifier in !x86_64 (Wang Nan)

Infrastructure changes:

- Add infrastructure for PMU specific configuration, allowing to pass
  config variables directly to the kernel PMU driver, prefixing those
  variables with a '@', part of a larger series to support Coresight (Mathieu Poirier)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
46 files changed:
tools/arch/alpha/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/arc/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/arm/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/arm64/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/frv/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/h8300/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/hexagon/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/ia64/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/m32r/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/microblaze/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/mips/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/mn10300/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/parisc/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/powerpc/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/s390/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/score/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/sh/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/sparc/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/tile/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/x86/include/uapi/asm/mman.h [new file with mode: 0644]
tools/arch/xtensa/include/uapi/asm/mman.h [new file with mode: 0644]
tools/include/uapi/asm-generic/mman-common.h [new file with mode: 0644]
tools/include/uapi/asm-generic/mman.h [new file with mode: 0644]
tools/include/uapi/linux/mman.h [new file with mode: 0644]
tools/perf/Documentation/perf-record.txt
tools/perf/MANIFEST
tools/perf/Makefile.perf
tools/perf/arch/x86/include/dwarf-regs-table.h
tools/perf/builtin-report.c
tools/perf/trace/beauty/mmap.c
tools/perf/ui/browsers/hists.c
tools/perf/ui/hist.c
tools/perf/ui/stdio/hist.c
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/dso.c
tools/perf/util/event.c
tools/perf/util/evsel.h
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/map.c
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.l
tools/perf/util/parse-events.y
tools/perf/util/sort.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 (file)
index 0000000..e38b64c
--- /dev/null
@@ -0,0 +1,47 @@
+#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_FREE      8
+#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
+/* 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
new file mode 100644 (file)
index 0000000..aa3acd2
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_ARC_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..478f699
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_ARM_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..70fd311
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_ARM64_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..5be78ac
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_FRV_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..9d9ac54
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_H8300_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..102f3fa
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_HEXAGON_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..1d6e5ac
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_IA64_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..1c29635
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_M32R_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..005cd50
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_MICROBLAZE_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..c020529
--- /dev/null
@@ -0,0 +1,46 @@
+#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_FREE      8
+#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
+/* 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
new file mode 100644 (file)
index 0000000..c1ea36d
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_MN10300_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..03d8d5b
--- /dev/null
@@ -0,0 +1,47 @@
+#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_FREE      8
+#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
+/* 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
new file mode 100644 (file)
index 0000000..761db43
--- /dev/null
@@ -0,0 +1,15 @@
+#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 <uapi/asm-generic/mman-common.h>
+/* 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
new file mode 100644 (file)
index 0000000..b03dea9
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_S390_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..2f8fb89
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_SCORE_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..26504f6
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H
+#define TOOLS_ARCH_SH_UAPI_ASM_MMAN_FIX_H
+#include <uapi/asm-generic/mman.h>
+/* 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
new file mode 100644 (file)
index 0000000..8640525
--- /dev/null
@@ -0,0 +1,15 @@
+#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 <uapi/asm-generic/mman-common.h>
+/* 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
new file mode 100644 (file)
index 0000000..7116c4b
--- /dev/null
@@ -0,0 +1,15 @@
+#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 <uapi/asm-generic/mman-common.h>
+/* MAP_32BIT is undefined on tile, fix it for perf */
+#define MAP_32BIT      0
+#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 (file)
index 0000000..b73c1af
--- /dev/null
@@ -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 <uapi/asm-generic/mman.h>
+#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 (file)
index 0000000..4453195
--- /dev/null
@@ -0,0 +1,47 @@
+#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_FREE      8
+#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
+/* 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
diff --git a/tools/include/uapi/asm-generic/mman-common.h b/tools/include/uapi/asm-generic/mman-common.h
new file mode 100644 (file)
index 0000000..5827438
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef __ASM_GENERIC_MMAN_COMMON_H
+#define __ASM_GENERIC_MMAN_COMMON_H
+
+/*
+ Author: Michael S. Tsirkin <mst@mellanox.co.il>, 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 (file)
index 0000000..10fa785
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __ASM_GENERIC_MMAN_H
+#define __ASM_GENERIC_MMAN_H
+
+#include <uapi/asm-generic/mman-common.h>
+
+#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 (file)
index 0000000..81d8edf
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _UAPI_LINUX_MMAN_H
+#define _UAPI_LINUX_MMAN_H
+
+#include <uapi/asm/mman.h>
+
+#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 */
index 379a2be..1a24f4d 100644 (file)
@@ -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 .../<pmu>/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
index ff200c6..0bda2cc 100644 (file)
@@ -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
index 828cfd7..d710db1 100644 (file)
@@ -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)
index 39ac7cb..9b5e5cb 100644 (file)
@@ -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",
 };
index 1a07c4c..6e88460 100644 (file)
@@ -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) {
index d0a3a8e..fd710ab 100644 (file)
@@ -1,8 +1,4 @@
-#include <sys/mman.h>
-
-#ifndef PROT_SEM
-#define PROT_SEM 0x8
-#endif
+#include <uapi/linux/mman.h>
 
 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)
 {
@@ -170,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);
index f0611c9..a6d5d24 100644 (file)
@@ -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;
 }
 
@@ -2076,10 +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;
-       }
+
+       hists__reset_column_width(hists);
 }
 
 struct hist_browser *hist_browser__new(struct hists *hists)
index b47fafc..60c4a4d 100644 (file)
@@ -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;
index 9b65f4a..8e1840b 100644 (file)
@@ -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,22 +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)
-{
-       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);
-}
-
 static void fprintf_line(struct hists *hists, struct perf_hpp *hpp,
                         int line, FILE *fp)
 {
@@ -732,7 +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 rb_node *nd;
        size_t ret = 0;
        const char *sep = symbol_conf.field_sep;
@@ -743,8 +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);
+       hists__reset_column_width(hists);
 
        if (symbol_conf.col_width_list_str)
                perf_hpp__set_user_width(symbol_conf.col_width_list_str);
index 7a80c73..aeb5a44 100644 (file)
@@ -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)
 {
        char *endptr, *tok, *name;
 
@@ -82,16 +82,16 @@ static int call__parse(struct ins_operands *ops)
        return ops->target.name == NULL ? -1 : 0;
 
 indirect_call:
-       tok = strchr(endptr, '(');
-       if (tok != NULL) {
-               ops->target.addr = 0;
+       tok = strchr(endptr, '*');
+       if (tok == NULL) {
+               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;
        }
 
-       tok = strchr(endptr, '*');
-       if (tok == NULL)
-               return -1;
-
        ops->target.addr = strtoull(tok + 1, NULL, 16);
        return 0;
 }
@@ -118,7 +118,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, '+');
 
@@ -173,7 +173,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;
 
@@ -194,7 +194,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;
@@ -237,7 +237,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;
 
@@ -304,7 +304,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;
 
@@ -709,7 +709,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);
 
@@ -719,7 +719,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;
 }
 
@@ -761,7 +761,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);
 
@@ -776,7 +777,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);
                }
        }
 
@@ -1148,7 +1149,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)++;
 
index ea44e4f..5bbcec1 100644 (file)
@@ -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);
 };
index 774f6ec..d2c6cdd 100644 (file)
@@ -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;
index 6c30171..2880e22 100644 (file)
@@ -1,5 +1,5 @@
 #include <linux/types.h>
-#include <sys/mman.h>
+#include <uapi/linux/mman.h> /* To get things like MAP_HUGETLB even on older libc headers */
 #include <api/fs/fs.h>
 #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);
index 4d44129..3238060 100644 (file)
@@ -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;
index de15dbc..b02992e 100644 (file)
@@ -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));
@@ -417,6 +419,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;
@@ -2149,6 +2153,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)
 {
@@ -2174,6 +2222,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 +2276,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
@@ -2197,6 +2296,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,
@@ -2208,6 +2351,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
index a002c93..defa957 100644 (file)
@@ -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);
index d51a125..c662fef 100644 (file)
@@ -6,7 +6,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <sys/mman.h>
+#include <uapi/linux/mman.h> /* 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);
index 6c913c3..2eb8b1e 100644 (file)
@@ -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;
                }
index d1edbf8..8d09a97 100644 (file)
@@ -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,
 };
 
index 7a25194..9f43fda 100644 (file)
@@ -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); }
 }
 
 <mem>{
index 5be4a5f..879115f 100644 (file)
@@ -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 <num> PE_VALUE
 %type <num> PE_VALUE_SYM_HW
 %type <num> PE_VALUE_SYM_SW
@@ -63,6 +64,7 @@ static void inc_group_count(struct list_head *list,
 %type <str> PE_MODIFIER_BP
 %type <str> PE_EVENT_NAME
 %type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
+%type <str> PE_DRV_CFG_TERM
 %type <num> value_sym
 %type <head> event_config
 %type <head> 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 ']'
index 28c0524..9505483 100644 (file)
@@ -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[];