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,
|
Note: If user explicitly sets options which conflict with the params,
|
||||||
the value set by the params will be overridden.
|
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]'
|
- a hardware breakpoint event in the form of '\mem:addr[/len][:access]'
|
||||||
where addr is the address in memory you want to break in.
|
where addr is the address in memory you want to break in.
|
||||||
Access is the memory access type (read, write, execute) it can
|
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/kernel.h
|
||||||
tools/include/linux/list.h
|
tools/include/linux/list.h
|
||||||
tools/include/linux/log2.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.h
|
||||||
tools/include/uapi/linux/bpf_common.h
|
tools/include/uapi/linux/bpf_common.h
|
||||||
tools/include/uapi/linux/hw_breakpoint.h
|
tools/include/uapi/linux/hw_breakpoint.h
|
||||||
|
tools/include/uapi/linux/mman.h
|
||||||
tools/include/uapi/linux/perf_event.h
|
tools/include/uapi/linux/perf_event.h
|
||||||
tools/include/linux/poison.h
|
tools/include/linux/poison.h
|
||||||
tools/include/linux/rbtree.h
|
tools/include/linux/rbtree.h
|
||||||
|
@ -79,4 +82,5 @@ tools/include/linux/types.h
|
||||||
tools/include/linux/err.h
|
tools/include/linux/err.h
|
||||||
tools/include/linux/bitmap.h
|
tools/include/linux/bitmap.h
|
||||||
tools/include/linux/time64.h
|
tools/include/linux/time64.h
|
||||||
|
tools/arch/*/include/uapi/asm/mman.h
|
||||||
tools/arch/*/include/uapi/asm/perf_regs.h
|
tools/arch/*/include/uapi/asm/perf_regs.h
|
||||||
|
|
|
@ -432,6 +432,15 @@ $(PERF_IN): prepare FORCE
|
||||||
@(test -f ../../include/linux/coresight-pmu.h && ( \
|
@(test -f ../../include/linux/coresight-pmu.h && ( \
|
||||||
(diff -B ../include/linux/coresight-pmu.h ../../include/linux/coresight-pmu.h >/dev/null) \
|
(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
|
|| 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
|
$(Q)$(MAKE) $(build)=perf
|
||||||
|
|
||||||
$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
|
$(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[] = {
|
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",
|
"%bp", "%sp", "%r8", "%r9", "%r10", "%r11",
|
||||||
"%r12", "%r13", "%r14", "%r15",
|
"%r12", "%r13", "%r14", "%r15",
|
||||||
};
|
};
|
||||||
|
|
|
@ -935,7 +935,6 @@ repeat:
|
||||||
|
|
||||||
if (symbol_conf.report_hierarchy) {
|
if (symbol_conf.report_hierarchy) {
|
||||||
/* disable incompatible options */
|
/* disable incompatible options */
|
||||||
symbol_conf.event_group = false;
|
|
||||||
symbol_conf.cumulate_callchain = false;
|
symbol_conf.cumulate_callchain = false;
|
||||||
|
|
||||||
if (field_order) {
|
if (field_order) {
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
#include <sys/mman.h>
|
#include <uapi/linux/mman.h>
|
||||||
|
|
||||||
#ifndef PROT_SEM
|
|
||||||
#define PROT_SEM 0x8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
|
static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size,
|
||||||
struct syscall_arg *arg)
|
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
|
#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,
|
static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size,
|
||||||
struct syscall_arg *arg)
|
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
|
#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,
|
static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size,
|
||||||
struct syscall_arg *arg)
|
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
|
#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,
|
static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size,
|
||||||
struct syscall_arg *arg)
|
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(SEQUENTIAL);
|
||||||
P_MADV_BHV(WILLNEED);
|
P_MADV_BHV(WILLNEED);
|
||||||
P_MADV_BHV(DONTNEED);
|
P_MADV_BHV(DONTNEED);
|
||||||
|
P_MADV_BHV(FREE);
|
||||||
P_MADV_BHV(REMOVE);
|
P_MADV_BHV(REMOVE);
|
||||||
P_MADV_BHV(DONTFORK);
|
P_MADV_BHV(DONTFORK);
|
||||||
P_MADV_BHV(DOFORK);
|
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);
|
ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent);
|
||||||
ui_browser__printf(arg->b, "%s", hpp->buf);
|
ui_browser__printf(arg->b, "%s", hpp->buf);
|
||||||
|
|
||||||
advance_hpp(hpp, ret);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2076,10 +2075,10 @@ void hist_browser__init(struct hist_browser *browser,
|
||||||
browser->b.use_navkeypressed = true;
|
browser->b.use_navkeypressed = true;
|
||||||
browser->show_headers = symbol_conf.show_hist_headers;
|
browser->show_headers = symbol_conf.show_hist_headers;
|
||||||
|
|
||||||
hists__for_each_format(hists, fmt) {
|
hists__for_each_format(hists, fmt)
|
||||||
perf_hpp__reset_width(fmt, hists);
|
|
||||||
++browser->b.columns;
|
++browser->b.columns;
|
||||||
}
|
|
||||||
|
hists__reset_column_width(hists);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hist_browser *hist_browser__new(struct hists *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)
|
void perf_hpp__set_user_width(const char *width_list_str)
|
||||||
{
|
{
|
||||||
struct perf_hpp_fmt *fmt;
|
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);
|
return fprintf(fp, "%-.*s", (indent - 2) * HIERARCHY_INDENT, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
|
static int hists__fprintf_hierarchy_headers(struct hists *hists,
|
||||||
const char *sep, FILE *fp)
|
struct perf_hpp *hpp, FILE *fp)
|
||||||
{
|
{
|
||||||
bool first_node, first_col;
|
bool first_node, first_col;
|
||||||
int indent;
|
int indent;
|
||||||
|
@ -538,6 +538,7 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
|
||||||
unsigned header_width = 0;
|
unsigned header_width = 0;
|
||||||
struct perf_hpp_fmt *fmt;
|
struct perf_hpp_fmt *fmt;
|
||||||
struct perf_hpp_list_node *fmt_node;
|
struct perf_hpp_list_node *fmt_node;
|
||||||
|
const char *sep = symbol_conf.field_sep;
|
||||||
|
|
||||||
indent = hists->nr_hpp_node;
|
indent = hists->nr_hpp_node;
|
||||||
|
|
||||||
|
@ -623,22 +624,6 @@ static int print_hierarchy_header(struct hists *hists, struct perf_hpp *hpp,
|
||||||
return 2;
|
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,
|
static void fprintf_line(struct hists *hists, struct perf_hpp *hpp,
|
||||||
int line, FILE *fp)
|
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,
|
int max_cols, float min_pcnt, FILE *fp,
|
||||||
bool use_callchain)
|
bool use_callchain)
|
||||||
{
|
{
|
||||||
struct perf_hpp_fmt *fmt;
|
|
||||||
struct rb_node *nd;
|
struct rb_node *nd;
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
const char *sep = symbol_conf.field_sep;
|
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();
|
init_rem_hits();
|
||||||
|
|
||||||
hists__for_each_format(hists, fmt)
|
hists__reset_column_width(hists);
|
||||||
perf_hpp__reset_width(fmt, hists);
|
|
||||||
|
|
||||||
if (symbol_conf.col_width_list_str)
|
if (symbol_conf.col_width_list_str)
|
||||||
perf_hpp__set_user_width(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);
|
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;
|
char *endptr, *tok, *name;
|
||||||
|
|
||||||
|
@ -82,16 +82,16 @@ static int call__parse(struct ins_operands *ops)
|
||||||
return ops->target.name == NULL ? -1 : 0;
|
return ops->target.name == NULL ? -1 : 0;
|
||||||
|
|
||||||
indirect_call:
|
indirect_call:
|
||||||
tok = strchr(endptr, '(');
|
tok = strchr(endptr, '*');
|
||||||
if (tok != NULL) {
|
if (tok == NULL) {
|
||||||
ops->target.addr = 0;
|
struct symbol *sym = map__find_symbol(map, map->map_ip(map, ops->target.addr));
|
||||||
|
if (sym != NULL)
|
||||||
|
ops->target.name = strdup(sym->name);
|
||||||
|
else
|
||||||
|
ops->target.addr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
tok = strchr(endptr, '*');
|
|
||||||
if (tok == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ops->target.addr = strtoull(tok + 1, NULL, 16);
|
ops->target.addr = strtoull(tok + 1, NULL, 16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ bool ins__is_call(const struct ins *ins)
|
||||||
return ins->ops == &call_ops;
|
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, '+');
|
const char *s = strchr(ops->raw, '+');
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lock__parse(struct ins_operands *ops)
|
static int lock__parse(struct ins_operands *ops, struct map *map)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ static int lock__parse(struct ins_operands *ops)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ops->locked.ins->ops->parse &&
|
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;
|
goto out_free_ops;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -237,7 +237,7 @@ static struct ins_ops lock_ops = {
|
||||||
.scnprintf = lock__scnprintf,
|
.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;
|
char *s = strchr(ops->raw, ','), *target, *comment, prev;
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ static struct ins_ops mov_ops = {
|
||||||
.scnprintf = mov__scnprintf,
|
.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;
|
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);
|
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);
|
dl->ins = ins__find(dl->name);
|
||||||
|
|
||||||
|
@ -719,7 +719,7 @@ static void disasm_line__init_ins(struct disasm_line *dl)
|
||||||
if (!dl->ins->ops)
|
if (!dl->ins->ops)
|
||||||
return;
|
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;
|
dl->ins = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,7 +761,8 @@ out_free_name:
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct disasm_line *disasm_line__new(s64 offset, char *line,
|
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);
|
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)
|
if (disasm_line__parse(dl->line, &dl->name, &dl->ops.raw) < 0)
|
||||||
goto out_free_line;
|
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;
|
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);
|
free(line);
|
||||||
(*line_nr)++;
|
(*line_nr)++;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct ins_operands {
|
||||||
|
|
||||||
struct ins_ops {
|
struct ins_ops {
|
||||||
void (*free)(struct ins_operands *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,
|
int (*scnprintf)(struct ins *ins, char *bf, size_t size,
|
||||||
struct ins_operands *ops);
|
struct ins_operands *ops);
|
||||||
};
|
};
|
||||||
|
|
|
@ -363,6 +363,9 @@ static int __open_dso(struct dso *dso, struct machine *machine)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_regular_file(name))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
fd = do_open(name);
|
fd = do_open(name);
|
||||||
free(name);
|
free(name);
|
||||||
return fd;
|
return fd;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <linux/types.h>
|
#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 <api/fs/fs.h>
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -249,10 +249,8 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
|
||||||
bool truncation = false;
|
bool truncation = false;
|
||||||
unsigned long long timeout = proc_map_timeout * 1000000ULL;
|
unsigned long long timeout = proc_map_timeout * 1000000ULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
#ifdef MAP_HUGETLB
|
|
||||||
const char *hugetlbfs_mnt = hugetlbfs__mountpoint();
|
const char *hugetlbfs_mnt = hugetlbfs__mountpoint();
|
||||||
int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0;
|
int hugetlbfs_mnt_len = hugetlbfs_mnt ? strlen(hugetlbfs_mnt) : 0;
|
||||||
#endif
|
|
||||||
|
|
||||||
if (machine__is_default_guest(machine))
|
if (machine__is_default_guest(machine))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -347,12 +345,11 @@ out:
|
||||||
|
|
||||||
if (!strcmp(execname, ""))
|
if (!strcmp(execname, ""))
|
||||||
strcpy(execname, anonstr);
|
strcpy(execname, anonstr);
|
||||||
#ifdef MAP_HUGETLB
|
|
||||||
if (!strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) {
|
if (!strncmp(execname, hugetlbfs_mnt, hugetlbfs_mnt_len)) {
|
||||||
strcpy(execname, anonstr);
|
strcpy(execname, anonstr);
|
||||||
event->mmap2.flags |= MAP_HUGETLB;
|
event->mmap2.flags |= MAP_HUGETLB;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
size = strlen(execname) + 1;
|
size = strlen(execname) + 1;
|
||||||
memcpy(event->mmap2.filename, execname, size);
|
memcpy(event->mmap2.filename, execname, size);
|
||||||
|
|
|
@ -46,6 +46,7 @@ enum {
|
||||||
PERF_EVSEL__CONFIG_TERM_INHERIT,
|
PERF_EVSEL__CONFIG_TERM_INHERIT,
|
||||||
PERF_EVSEL__CONFIG_TERM_MAX_STACK,
|
PERF_EVSEL__CONFIG_TERM_MAX_STACK,
|
||||||
PERF_EVSEL__CONFIG_TERM_OVERWRITE,
|
PERF_EVSEL__CONFIG_TERM_OVERWRITE,
|
||||||
|
PERF_EVSEL__CONFIG_TERM_DRV_CFG,
|
||||||
PERF_EVSEL__CONFIG_TERM_MAX,
|
PERF_EVSEL__CONFIG_TERM_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ struct perf_evsel_config_term {
|
||||||
u64 freq;
|
u64 freq;
|
||||||
bool time;
|
bool time;
|
||||||
char *callgraph;
|
char *callgraph;
|
||||||
|
char *drv_cfg;
|
||||||
u64 stack_user;
|
u64 stack_user;
|
||||||
int max_stack;
|
int max_stack;
|
||||||
bool inherit;
|
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_LOCAL_WEIGHT, 12);
|
||||||
hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
|
hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
|
||||||
|
|
||||||
if (h->srcline)
|
if (h->srcline) {
|
||||||
hists__new_col_len(hists, HISTC_SRCLINE, strlen(h->srcline));
|
len = MAX(strlen(h->srcline), strlen(sort_srcline.se_header));
|
||||||
|
hists__new_col_len(hists, HISTC_SRCLINE, len);
|
||||||
|
}
|
||||||
|
|
||||||
if (h->srcfile)
|
if (h->srcfile)
|
||||||
hists__new_col_len(hists, HISTC_SRCFILE, strlen(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);
|
INIT_LIST_HEAD(&he->pairs.node);
|
||||||
thread__get(he->thread);
|
thread__get(he->thread);
|
||||||
|
he->hroot_in = RB_ROOT;
|
||||||
|
he->hroot_out = RB_ROOT;
|
||||||
|
|
||||||
if (!symbol_conf.report_hierarchy)
|
if (!symbol_conf.report_hierarchy)
|
||||||
he->leaf = true;
|
he->leaf = true;
|
||||||
|
@ -2149,6 +2153,50 @@ out:
|
||||||
return he;
|
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,
|
static struct hist_entry *hists__find_entry(struct hists *hists,
|
||||||
struct hist_entry *he)
|
struct hist_entry *he)
|
||||||
{
|
{
|
||||||
|
@ -2174,6 +2222,51 @@ static struct hist_entry *hists__find_entry(struct hists *hists,
|
||||||
return NULL;
|
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):
|
* 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 rb_node *nd;
|
||||||
struct hist_entry *pos, *pair;
|
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))
|
if (hists__has(leader, need_collapse))
|
||||||
root = &leader->entries_collapsed;
|
root = &leader->entries_collapsed;
|
||||||
else
|
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
|
* 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,
|
* 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 rb_node *nd;
|
||||||
struct hist_entry *pos, *pair;
|
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))
|
if (hists__has(other, need_collapse))
|
||||||
root = &other->entries_collapsed;
|
root = &other->entries_collapsed;
|
||||||
else
|
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_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__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists);
|
||||||
void perf_hpp__set_user_width(const char *width_list_str);
|
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 u64 (*hpp_field_fn)(struct hist_entry *he);
|
||||||
typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);
|
typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.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 "map.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "strlist.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)
|
static inline int is_anon_memory(const char *filename, u32 flags)
|
||||||
{
|
{
|
||||||
u32 anon_flags = 0;
|
return flags & MAP_HUGETLB ||
|
||||||
|
|
||||||
#ifdef MAP_HUGETLB
|
|
||||||
anon_flags |= MAP_HUGETLB;
|
|
||||||
#endif
|
|
||||||
return flags & anon_flags ||
|
|
||||||
!strcmp(filename, "//anon") ||
|
!strcmp(filename, "//anon") ||
|
||||||
!strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) ||
|
!strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) ||
|
||||||
!strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 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_MAX_STACK] = "max-stack",
|
||||||
[PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
|
[PARSE_EVENTS__TERM_TYPE_OVERWRITE] = "overwrite",
|
||||||
[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
|
[PARSE_EVENTS__TERM_TYPE_NOOVERWRITE] = "no-overwrite",
|
||||||
|
[PARSE_EVENTS__TERM_TYPE_DRV_CFG] = "driver-config",
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool config_term_shrinked;
|
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_term *term,
|
||||||
struct parse_events_error *err)
|
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
|
* Always succeed for sysfs terms, as we dont know
|
||||||
* at this point what type they need to have.
|
* at this point what type they need to have.
|
||||||
|
@ -1134,6 +1136,9 @@ do { \
|
||||||
case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
|
case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
|
||||||
ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1);
|
ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1);
|
||||||
break;
|
break;
|
||||||
|
case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
|
||||||
|
ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ enum {
|
||||||
PARSE_EVENTS__TERM_TYPE_MAX_STACK,
|
PARSE_EVENTS__TERM_TYPE_MAX_STACK,
|
||||||
PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
|
PARSE_EVENTS__TERM_TYPE_NOOVERWRITE,
|
||||||
PARSE_EVENTS__TERM_TYPE_OVERWRITE,
|
PARSE_EVENTS__TERM_TYPE_OVERWRITE,
|
||||||
|
PARSE_EVENTS__TERM_TYPE_DRV_CFG,
|
||||||
__PARSE_EVENTS__TERM_TYPE_NR,
|
__PARSE_EVENTS__TERM_TYPE_NR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,26 @@ static int str(yyscan_t scanner, int token)
|
||||||
return 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) \
|
#define REWIND(__alloc) \
|
||||||
do { \
|
do { \
|
||||||
YYSTYPE *__yylval = parse_events_get_lval(yyscanner); \
|
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]+
|
num_raw_hex [a-fA-F0-9]+
|
||||||
name [a-zA-Z_*?][a-zA-Z0-9_*?.]*
|
name [a-zA-Z_*?][a-zA-Z0-9_*?.]*
|
||||||
name_minus [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() */
|
/* If you add a modifier you need to update check_modifier() */
|
||||||
modifier_event [ukhpPGHSDI]+
|
modifier_event [ukhpPGHSDI]+
|
||||||
modifier_bp [rwx]{1,3}
|
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); }
|
{name_minus} { return str(yyscanner, PE_NAME); }
|
||||||
\[all\] { return PE_ARRAY_ALL; }
|
\[all\] { return PE_ARRAY_ALL; }
|
||||||
"[" { BEGIN(array); return '['; }
|
"[" { BEGIN(array); return '['; }
|
||||||
|
@{drv_cfg_term} { return drv_str(yyscanner, PE_DRV_CFG_TERM); }
|
||||||
}
|
}
|
||||||
|
|
||||||
<mem>{
|
<mem>{
|
||||||
|
|
|
@ -49,6 +49,7 @@ static void inc_group_count(struct list_head *list,
|
||||||
%token PE_ERROR
|
%token PE_ERROR
|
||||||
%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
%token PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
||||||
%token PE_ARRAY_ALL PE_ARRAY_RANGE
|
%token PE_ARRAY_ALL PE_ARRAY_RANGE
|
||||||
|
%token PE_DRV_CFG_TERM
|
||||||
%type <num> PE_VALUE
|
%type <num> PE_VALUE
|
||||||
%type <num> PE_VALUE_SYM_HW
|
%type <num> PE_VALUE_SYM_HW
|
||||||
%type <num> PE_VALUE_SYM_SW
|
%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_MODIFIER_BP
|
||||||
%type <str> PE_EVENT_NAME
|
%type <str> PE_EVENT_NAME
|
||||||
%type <str> PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT
|
%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 <num> value_sym
|
||||||
%type <head> event_config
|
%type <head> event_config
|
||||||
%type <head> opt_event_config
|
%type <head> opt_event_config
|
||||||
|
@ -599,6 +601,15 @@ PE_NAME array '=' PE_VALUE
|
||||||
term->array = $2;
|
term->array = $2;
|
||||||
$$ = term;
|
$$ = 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:
|
||||||
'[' array_terms ']'
|
'[' 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_dso_to;
|
||||||
extern struct sort_entry sort_sym_from;
|
extern struct sort_entry sort_sym_from;
|
||||||
extern struct sort_entry sort_sym_to;
|
extern struct sort_entry sort_sym_to;
|
||||||
|
extern struct sort_entry sort_srcline;
|
||||||
extern enum sort_type sort__first_dimension;
|
extern enum sort_type sort__first_dimension;
|
||||||
extern const char default_mem_sort_order[];
|
extern const char default_mem_sort_order[];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue