perf/core improvements and fixes:
User visible: - 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: - 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> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJX4Y1JAAoJENZQFvNTUqpAVTMP/3EQ6Riqleasg5m7UU7adyTZ h4Oaq8KT1ON8VmR8gf6czZjzCE2Oiy9d1iUupza5iqau0wLF5IKPLdf9E0P9JA6n KPXgnAwq/ydIPQTSLWRgcDRyk2A61VDBBib/9pKBGK2Rkam4d/Eh3eD4AawyVkHd hUAdVPNTx5m3Xv/keySn/fcHAYaHCSnI1hNa8OMnQHkdkElak3akRzrpVmGHLz8j NAzCutmlBSLFNMVx6Kxa+gR3c0GwMcIMtpq5iTtvtqgf76i6evjjuJeY8hQF4SqJ lWA3pzdhP9lxD81gxbZzP9Vq0G6mifc8q9iJE4pM13NXWhQ6sneI0s2ERlkXCRSS 16Subg4yHp6DP6KRvmsS4kKCeJauHJ5wiWs6JtPPTiZv0V9h7MLKc7QMZIKjhKhO WVb2UUvSCOMgiu+2xLo1P/vq1DoJriM05Q90E+uqVrdy4c7ptiP5nq6vP6e98uD3 SsosnsMjX9UiAqYAYLiRxulsb6F1xhNHHV5Iw15LKyzdCRu1UNLeuOJ14FenBU58 S+gKD0MdVk2qCChh0klbGcleomNgt4hCnPgLfiAwKxj352toxpThkFQ/ZaBRhWKL 12eid79tGz5BPxOHg0pyBX50fE1HCww95DpTQS1r2bqzh1ijecxwY5w/4PVq+ZIP al/4gotCYp9Wv90miLi8 =4bBB -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo-20160920' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core 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>
This commit is contained in:
commit
89f1c2c59c
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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",
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)++;
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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>{
|
||||
|
|
|
@ -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 ']'
|
||||
|
|
|
@ -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[];
|
||||
|
||||
|
|
Loading…
Reference in New Issue