Commit 89f1c2c5 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'perf-core-for-mingo-20160920' of...

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 8ee83b2a 3c028a0c
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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
#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 */
#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 */
#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 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
if (symbol_conf.report_hierarchy) {
/* disable incompatible options */
symbol_conf.event_group = false;
symbol_conf.cumulate_callchain = false;
if (field_order) {
......
#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 @@ static int disasm_line__parse(char *line, char **namep, char **rawp)
}
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;
......
#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 @@ int perf_event__synthesize_mmap_events(struct perf_tool *tool,
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 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists,
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[];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment