Commit afb71193 authored by Ingo Molnar's avatar Ingo Molnar

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

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

perf/core improvements and fixes:

 * Reset SIGTERM handler in workload child process, fix from David Ahern.

 * Handle death by SIGTERM in 'perf record', fix from David Ahern.

 * Fix printing of perf_event_paranoid message, from David Ahern.

 * Handle realloc failures in 'perf kvm', from David Ahern.

 * Fix divide by 0 in variance, from David Ahern.

 * Save parent pid in thread struct, from David Ahern.

 * Handle JITed code in shared memory, from Andi Kleen.

 * Makefile reorganization, prep work for Kconfig patches, from Jiri Olsa.

 * Fixes for 'perf diff', from Jiri Olsa.

 * Add automated make test suite, from Jiri Olsa.

 * 'perf tests' fixes from Jiri Olsa.

 * Remove some unused struct members, from Jiri Olsa.

 * Add missing liblk.a dependency for python/perf.so, fix from Jiri Olsa.

 * Respect CROSS_COMPILE in liblk.a, from Rabin Vincent.

 * Expand definition of sysfs format attribute, from Michael Ellerman.

 * No need to do locking when adding hists in perf report, only 'top'
   needs that, from Namhyung Kim.

 * Sorting improvements, from Namhyung Kim.

 * Fix alignment of symbol column in in the hists browser (top, report)
   when -v is given, from NAmhyung Kim.

 * Add --percent-limit option to 'top' and 'report', from Namhyung Kim.

 * Fix 'perf top' -E option behavior, from Namhyung Kim.

 * Fix bug in isupper() and islower(), from Sukadev Bhattiprolu.

 * Fix compile errors in bp_signal 'perf test', from Sukadev Bhattiprolu.

 * Make Power7 CPI stack events available in sysfs, from Sukadev Bhattiprolu.
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parents c0ffaf36 c3c44709
...@@ -27,14 +27,36 @@ Description: Generic performance monitoring events ...@@ -27,14 +27,36 @@ Description: Generic performance monitoring events
"basename". "basename".
What: /sys/devices/cpu/events/PM_LD_MISS_L1 What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
/sys/devices/cpu/events/PM_LD_REF_L1
/sys/devices/cpu/events/PM_CYC
/sys/devices/cpu/events/PM_BRU_FIN /sys/devices/cpu/events/PM_BRU_FIN
/sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
/sys/devices/cpu/events/PM_BRU_MPRED /sys/devices/cpu/events/PM_BRU_MPRED
/sys/devices/cpu/events/PM_INST_CMPL
/sys/devices/cpu/events/PM_CMPLU_STALL /sys/devices/cpu/events/PM_CMPLU_STALL
/sys/devices/cpu/events/PM_CMPLU_STALL_BRU
/sys/devices/cpu/events/PM_CMPLU_STALL_DCACHE_MISS
/sys/devices/cpu/events/PM_CMPLU_STALL_DFU
/sys/devices/cpu/events/PM_CMPLU_STALL_DIV
/sys/devices/cpu/events/PM_CMPLU_STALL_ERAT_MISS
/sys/devices/cpu/events/PM_CMPLU_STALL_FXU
/sys/devices/cpu/events/PM_CMPLU_STALL_IFU
/sys/devices/cpu/events/PM_CMPLU_STALL_LSU
/sys/devices/cpu/events/PM_CMPLU_STALL_REJECT
/sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR
/sys/devices/cpu/events/PM_CMPLU_STALL_SCALAR_LONG
/sys/devices/cpu/events/PM_CMPLU_STALL_STORE
/sys/devices/cpu/events/PM_CMPLU_STALL_THRD
/sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR
/sys/devices/cpu/events/PM_CMPLU_STALL_VECTOR_LONG
/sys/devices/cpu/events/PM_CYC
/sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED
/sys/devices/cpu/events/PM_GCT_NOSLOT_BR_MPRED_IC_MISS
/sys/devices/cpu/events/PM_GCT_NOSLOT_CYC
/sys/devices/cpu/events/PM_GCT_NOSLOT_IC_MISS
/sys/devices/cpu/events/PM_GRP_CMPL
/sys/devices/cpu/events/PM_INST_CMPL
/sys/devices/cpu/events/PM_LD_MISS_L1
/sys/devices/cpu/events/PM_LD_REF_L1
/sys/devices/cpu/events/PM_RUN_CYC
/sys/devices/cpu/events/PM_RUN_INST_CMPL
Date: 2013/01/08 Date: 2013/01/08
......
...@@ -9,6 +9,12 @@ Description: ...@@ -9,6 +9,12 @@ Description:
we want to export, so that userspace can deal with sane we want to export, so that userspace can deal with sane
name/value pairs. name/value pairs.
Userspace must be prepared for the possibility that attributes
define overlapping bit ranges. For example:
attr1 = 'config:0-23'
attr2 = 'config:0-7'
attr3 = 'config:12-35'
Example: 'config1:1,6-10,44' Example: 'config1:1,6-10,44'
Defines contents of attribute that occupies bits 1,6-10,44 of Defines contents of attribute that occupies bits 1,6-10,44 of
perf_event_attr::config1. perf_event_attr::config1.
...@@ -62,6 +62,29 @@ ...@@ -62,6 +62,29 @@
#define PME_PM_BRU_FIN 0x10068 #define PME_PM_BRU_FIN 0x10068
#define PME_PM_BRU_MPRED 0x400f6 #define PME_PM_BRU_MPRED 0x400f6
#define PME_PM_CMPLU_STALL_FXU 0x20014
#define PME_PM_CMPLU_STALL_DIV 0x40014
#define PME_PM_CMPLU_STALL_SCALAR 0x40012
#define PME_PM_CMPLU_STALL_SCALAR_LONG 0x20018
#define PME_PM_CMPLU_STALL_VECTOR 0x2001c
#define PME_PM_CMPLU_STALL_VECTOR_LONG 0x4004a
#define PME_PM_CMPLU_STALL_LSU 0x20012
#define PME_PM_CMPLU_STALL_REJECT 0x40016
#define PME_PM_CMPLU_STALL_ERAT_MISS 0x40018
#define PME_PM_CMPLU_STALL_DCACHE_MISS 0x20016
#define PME_PM_CMPLU_STALL_STORE 0x2004a
#define PME_PM_CMPLU_STALL_THRD 0x1001c
#define PME_PM_CMPLU_STALL_IFU 0x4004c
#define PME_PM_CMPLU_STALL_BRU 0x4004e
#define PME_PM_GCT_NOSLOT_IC_MISS 0x2001a
#define PME_PM_GCT_NOSLOT_BR_MPRED 0x4001a
#define PME_PM_GCT_NOSLOT_BR_MPRED_IC_MISS 0x4001c
#define PME_PM_GRP_CMPL 0x30004
#define PME_PM_1PLUS_PPC_CMPL 0x100f2
#define PME_PM_CMPLU_STALL_DFU 0x2003c
#define PME_PM_RUN_CYC 0x200f4
#define PME_PM_RUN_INST_CMPL 0x400fa
/* /*
* Layout of constraint bits: * Layout of constraint bits:
* 6666555555555544444444443333333333222222222211111111110000000000 * 6666555555555544444444443333333333222222222211111111110000000000
...@@ -393,6 +416,31 @@ POWER_EVENT_ATTR(LD_MISS_L1, LD_MISS_L1); ...@@ -393,6 +416,31 @@ POWER_EVENT_ATTR(LD_MISS_L1, LD_MISS_L1);
POWER_EVENT_ATTR(BRU_FIN, BRU_FIN) POWER_EVENT_ATTR(BRU_FIN, BRU_FIN)
POWER_EVENT_ATTR(BRU_MPRED, BRU_MPRED); POWER_EVENT_ATTR(BRU_MPRED, BRU_MPRED);
POWER_EVENT_ATTR(CMPLU_STALL_FXU, CMPLU_STALL_FXU);
POWER_EVENT_ATTR(CMPLU_STALL_DIV, CMPLU_STALL_DIV);
POWER_EVENT_ATTR(CMPLU_STALL_SCALAR, CMPLU_STALL_SCALAR);
POWER_EVENT_ATTR(CMPLU_STALL_SCALAR_LONG, CMPLU_STALL_SCALAR_LONG);
POWER_EVENT_ATTR(CMPLU_STALL_VECTOR, CMPLU_STALL_VECTOR);
POWER_EVENT_ATTR(CMPLU_STALL_VECTOR_LONG, CMPLU_STALL_VECTOR_LONG);
POWER_EVENT_ATTR(CMPLU_STALL_LSU, CMPLU_STALL_LSU);
POWER_EVENT_ATTR(CMPLU_STALL_REJECT, CMPLU_STALL_REJECT);
POWER_EVENT_ATTR(CMPLU_STALL_ERAT_MISS, CMPLU_STALL_ERAT_MISS);
POWER_EVENT_ATTR(CMPLU_STALL_DCACHE_MISS, CMPLU_STALL_DCACHE_MISS);
POWER_EVENT_ATTR(CMPLU_STALL_STORE, CMPLU_STALL_STORE);
POWER_EVENT_ATTR(CMPLU_STALL_THRD, CMPLU_STALL_THRD);
POWER_EVENT_ATTR(CMPLU_STALL_IFU, CMPLU_STALL_IFU);
POWER_EVENT_ATTR(CMPLU_STALL_BRU, CMPLU_STALL_BRU);
POWER_EVENT_ATTR(GCT_NOSLOT_IC_MISS, GCT_NOSLOT_IC_MISS);
POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED, GCT_NOSLOT_BR_MPRED);
POWER_EVENT_ATTR(GCT_NOSLOT_BR_MPRED_IC_MISS, GCT_NOSLOT_BR_MPRED_IC_MISS);
POWER_EVENT_ATTR(GRP_CMPL, GRP_CMPL);
POWER_EVENT_ATTR(1PLUS_PPC_CMPL, 1PLUS_PPC_CMPL);
POWER_EVENT_ATTR(CMPLU_STALL_DFU, CMPLU_STALL_DFU);
POWER_EVENT_ATTR(RUN_CYC, RUN_CYC);
POWER_EVENT_ATTR(RUN_INST_CMPL, RUN_INST_CMPL);
static struct attribute *power7_events_attr[] = { static struct attribute *power7_events_attr[] = {
GENERIC_EVENT_PTR(CYC), GENERIC_EVENT_PTR(CYC),
GENERIC_EVENT_PTR(GCT_NOSLOT_CYC), GENERIC_EVENT_PTR(GCT_NOSLOT_CYC),
...@@ -411,6 +459,31 @@ static struct attribute *power7_events_attr[] = { ...@@ -411,6 +459,31 @@ static struct attribute *power7_events_attr[] = {
POWER_EVENT_PTR(LD_MISS_L1), POWER_EVENT_PTR(LD_MISS_L1),
POWER_EVENT_PTR(BRU_FIN), POWER_EVENT_PTR(BRU_FIN),
POWER_EVENT_PTR(BRU_MPRED), POWER_EVENT_PTR(BRU_MPRED),
POWER_EVENT_PTR(CMPLU_STALL_FXU),
POWER_EVENT_PTR(CMPLU_STALL_DIV),
POWER_EVENT_PTR(CMPLU_STALL_SCALAR),
POWER_EVENT_PTR(CMPLU_STALL_SCALAR_LONG),
POWER_EVENT_PTR(CMPLU_STALL_VECTOR),
POWER_EVENT_PTR(CMPLU_STALL_VECTOR_LONG),
POWER_EVENT_PTR(CMPLU_STALL_LSU),
POWER_EVENT_PTR(CMPLU_STALL_REJECT),
POWER_EVENT_PTR(CMPLU_STALL_ERAT_MISS),
POWER_EVENT_PTR(CMPLU_STALL_DCACHE_MISS),
POWER_EVENT_PTR(CMPLU_STALL_STORE),
POWER_EVENT_PTR(CMPLU_STALL_THRD),
POWER_EVENT_PTR(CMPLU_STALL_IFU),
POWER_EVENT_PTR(CMPLU_STALL_BRU),
POWER_EVENT_PTR(GCT_NOSLOT_IC_MISS),
POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED),
POWER_EVENT_PTR(GCT_NOSLOT_BR_MPRED_IC_MISS),
POWER_EVENT_PTR(GRP_CMPL),
POWER_EVENT_PTR(1PLUS_PPC_CMPL),
POWER_EVENT_PTR(CMPLU_STALL_DFU),
POWER_EVENT_PTR(RUN_CYC),
POWER_EVENT_PTR(RUN_INST_CMPL),
NULL NULL
}; };
......
include ../../scripts/Makefile.include include ../../scripts/Makefile.include
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
# guard against environment variables # guard against environment variables
LIB_H= LIB_H=
LIB_OBJS= LIB_OBJS=
......
...@@ -13,7 +13,7 @@ SYNOPSIS ...@@ -13,7 +13,7 @@ SYNOPSIS
DESCRIPTION DESCRIPTION
----------- -----------
This command runs runs perf-buildid-list --with-hits, and collects the files This command runs runs perf-buildid-list --with-hits, and collects the files
with the buildids found so that analisys of perf.data contents can be possible with the buildids found so that analysis of perf.data contents can be possible
on another machine. on another machine.
......
...@@ -210,6 +210,10 @@ OPTIONS ...@@ -210,6 +210,10 @@ OPTIONS
Demangle symbol names to human readable form. It's enabled by default, Demangle symbol names to human readable form. It's enabled by default,
disable with --no-demangle. disable with --no-demangle.
--percent-limit::
Do not show entries which have an overhead under that percent.
(Default: 0).
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-stat[1], linkperf:perf-annotate[1] linkperf:perf-stat[1], linkperf:perf-annotate[1]
...@@ -155,6 +155,10 @@ Default is to monitor all CPUS. ...@@ -155,6 +155,10 @@ Default is to monitor all CPUS.
Default: fractal,0.5,callee. Default: fractal,0.5,callee.
--percent-limit::
Do not show entries which have an overhead under that percent.
(Default: 0).
INTERACTIVE PROMPTING KEYS INTERACTIVE PROMPTING KEYS
-------------------------- --------------------------
......
...@@ -51,189 +51,63 @@ include config/utilities.mak ...@@ -51,189 +51,63 @@ include config/utilities.mak
# Define NO_BACKTRACE if you do not want stack backtrace debug feature # Define NO_BACKTRACE if you do not want stack backtrace debug feature
# #
# Define NO_LIBNUMA if you do not want numa perf benchmark # Define NO_LIBNUMA if you do not want numa perf benchmark
#
# Define NO_LIBAUDIT if you do not want libaudit support
#
# Define NO_LIBBIONIC if you do not want bionic support
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE ifeq ($(srctree),)
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) srctree := $(patsubst %/,%,$(dir $(shell pwd)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
uname_M := $(shell uname -m 2>/dev/null || echo not) #$(info Determined 'srctree' to be $(srctree))
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
NO_PERF_REGS := 1
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
override ARCH := x86
NO_PERF_REGS := 0
LIBUNWIND_LIBS = -lunwind -lunwind-x86
endif
ifeq ($(ARCH),x86_64)
override ARCH := x86
IS_X86_64 := 0
ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
endif
ifeq (${IS_X86_64}, 1)
RAW_ARCH := x86_64
ARCH_CFLAGS := -DARCH_X86_64
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
endif
NO_PERF_REGS := 0
LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
endif
# Treat warnings as errors unless directed not to
ifneq ($(WERROR),0)
CFLAGS_WERROR := -Werror
endif
ifeq ("$(origin DEBUG)", "command line")
PERF_DEBUG = $(DEBUG)
endif
ifndef PERF_DEBUG
CFLAGS_OPTIMIZE = -O6
endif endif
ifdef PARSER_DEBUG ifneq ($(objtree),)
PARSER_DEBUG_BISON := -t #$(info Determined 'objtree' to be $(objtree))
PARSER_DEBUG_FLEX := -d
PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
endif endif
ifdef NO_NEWT ifneq ($(OUTPUT),)
NO_SLANG=1 #$(info Determined 'OUTPUT' to be $(OUTPUT))
endif endif
CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS) $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
EXTLIBS = -lpthread -lrt -lelf -lm @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip
# Among the variables below, these:
# perfexecdir
# template_dir
# mandir
# infodir
# htmldir
# ETC_PERFCONFIG (but not sysconfdir)
# can be specified as a relative path some/where/else;
# this is interpreted as relative to $(prefix) and "perf" at
# runtime figures out where they are based on the path to the executable.
# This can help installing the suite in a relocatable way.
# Make the path relative to DESTDIR, not to prefix
ifndef DESTDIR
prefix = $(HOME)
endif
bindir_relative = bin
bindir = $(prefix)/$(bindir_relative)
mandir = share/man
infodir = share/info
perfexecdir = libexec/perf-core
sharedir = $(prefix)/share
template_dir = share/perf-core/templates
htmldir = share/doc/perf-doc
ifeq ($(prefix),/usr)
sysconfdir = /etc
ETC_PERFCONFIG = $(sysconfdir)/perfconfig
else
sysconfdir = $(prefix)/etc
ETC_PERFCONFIG = etc/perfconfig
endif
lib = lib
export prefix bindir sharedir sysconfdir CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
RM = rm -f RM = rm -f
MKDIR = mkdir MKDIR = mkdir
FIND = find FIND = find
INSTALL = install INSTALL = install
FLEX = flex FLEX = flex
BISON= bison BISON = bison
STRIP = strip
# sparse is architecture-neutral, which means that we need to tell it
# explicitly what architecture to check for. Fix this up for yours..
SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),tags)
-include config/feature-tests.mak
ifeq ($(call get-executable,$(FLEX)),)
dummy := $(error Error: $(FLEX) is missing on this system, please install it)
endif
ifeq ($(call get-executable,$(BISON)),)
dummy := $(error Error: $(BISON) is missing on this system, please install it)
endif
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) LK_DIR = $(srctree)/tools/lib/lk/
CFLAGS := $(CFLAGS) -fstack-protector-all TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
endif
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y) # include config/Makefile by default and rule out
CFLAGS := $(CFLAGS) -Wstack-protector # non-config cases
endif config := 1
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y) NON_CONFIG_TARGETS := clean TAGS tags cscope help
CFLAGS := $(CFLAGS) -Wvolatile-register-var
endif
ifndef PERF_DEBUG ifdef MAKECMDGOALS
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y) ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2 config := 0
endif
endif endif
### --- END CONFIGURATION SECTION ---
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
#$(info Determined 'srctree' to be $(srctree))
endif endif
ifneq ($(objtree),) ifeq ($(config),1)
#$(info Determined 'objtree' to be $(objtree)) include config/Makefile
endif endif
ifneq ($(OUTPUT),) export prefix bindir sharedir sysconfdir
#$(info Determined 'OUTPUT' to be $(OUTPUT))
endif
BASIC_CFLAGS = \ # sparse is architecture-neutral, which means that we need to tell it
-Iutil/include \ # explicitly what architecture to check for. Fix this up for yours..
-Iarch/$(ARCH)/include \ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
$(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
-I$(srctree)/arch/$(ARCH)/include/uapi \
-I$(srctree)/arch/$(ARCH)/include \
$(if $(objtree),-I$(objtree)/include/generated/uapi) \
-I$(srctree)/include/uapi \
-I$(srctree)/include \
-I$(OUTPUT)util \
-Iutil \
-I. \
-I$(TRACE_EVENT_DIR) \
-I../lib/ \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
BASIC_LDFLAGS =
ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
BIONIC := 1
EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
BASIC_CFLAGS += -I.
endif
endif # MAKECMDGOALS != tags
endif # MAKECMDGOALS != clean
# Guard against environment variables # Guard against environment variables
BUILTIN_OBJS = BUILTIN_OBJS =
...@@ -247,20 +121,17 @@ SCRIPT_SH += perf-archive.sh ...@@ -247,20 +121,17 @@ SCRIPT_SH += perf-archive.sh
grep-libs = $(filter -l%,$(1)) grep-libs = $(filter -l%,$(1))
strip-libs = $(filter-out -l%,$(1)) strip-libs = $(filter-out -l%,$(1))
LK_DIR = ../lib/lk/
TRACE_EVENT_DIR = ../lib/traceevent/
LK_PATH=$(LK_DIR) LK_PATH=$(LK_DIR)
ifneq ($(OUTPUT),) ifneq ($(OUTPUT),)
TE_PATH=$(OUTPUT) TE_PATH=$(OUTPUT)
ifneq ($(subdir),) ifneq ($(subdir),)
LK_PATH=$(OUTPUT)$(LK_DIR) LK_PATH=$(OUTPUT)$(LK_DIR)
else else
LK_PATH=$(OUTPUT) LK_PATH=$(OUTPUT)
endif endif
else else
TE_PATH=$(TRACE_EVENT_DIR) TE_PATH=$(TRACE_EVENT_DIR)
endif endif
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
...@@ -278,10 +149,10 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP ...@@ -278,10 +149,10 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
$(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
--quiet build_ext; \ --quiet build_ext; \
mkdir -p $(OUTPUT)python && \ mkdir -p $(OUTPUT)python && \
cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/ cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
...@@ -296,8 +167,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) ...@@ -296,8 +167,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
# #
PROGRAMS += $(OUTPUT)perf PROGRAMS += $(OUTPUT)perf
LANG_BINDINGS =
# what 'all' will build and 'install' will install, in perfexecdir # what 'all' will build and 'install' will install, in perfexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
...@@ -306,10 +175,10 @@ OTHER_PROGRAMS = $(OUTPUT)perf ...@@ -306,10 +175,10 @@ OTHER_PROGRAMS = $(OUTPUT)perf
# Set paths to tools early so that they can be used for version tests. # Set paths to tools early so that they can be used for version tests.
ifndef SHELL_PATH ifndef SHELL_PATH
SHELL_PATH = /bin/sh SHELL_PATH = /bin/sh
endif endif
ifndef PERL_PATH ifndef PERL_PATH
PERL_PATH = /usr/bin/perl PERL_PATH = /usr/bin/perl
endif endif
export PERL_PATH export PERL_PATH
...@@ -557,79 +426,14 @@ BUILTIN_OBJS += $(OUTPUT)builtin-mem.o ...@@ -557,79 +426,14 @@ BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT) PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
#
# Platform specific tweaks
#
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(MAKECMDGOALS),tags)
# We choose to avoid "if .. else if .. else .. endif endif" # We choose to avoid "if .. else if .. else .. endif endif"
# because maintaining the nesting to match is a pain. If # because maintaining the nesting to match is a pain. If
# we had "elif" things would have been much nicer... # we had "elif" things would have been much nicer...
ifdef NO_LIBELF
NO_DWARF := 1
NO_DEMANGLE := 1
NO_LIBUNWIND := 1
else
FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
LIBC_SUPPORT := 1
endif
ifeq ($(BIONIC),1)
LIBC_SUPPORT := 1
endif
ifeq ($(LIBC_SUPPORT),1)
msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
NO_LIBELF := 1
NO_DWARF := 1
NO_DEMANGLE := 1
else
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
endif
else
# for linking with debug library, run like:
# make DEBUG=1 LIBDW_DIR=/opt/libdw/
ifdef LIBDW_DIR
LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
endif
FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
NO_DWARF := 1
endif # Dwarf support
endif # SOURCE_LIBELF
endif # NO_LIBELF
# There's only x86 (both 32 and 64) support for CFI unwind so far
ifneq ($(ARCH),x86)
NO_LIBUNWIND := 1
endif
ifndef NO_LIBUNWIND
# for linking with debug library, run like:
# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
ifdef LIBUNWIND_DIR
LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
endif
FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
NO_LIBUNWIND := 1
endif # Libunwind support
endif # NO_LIBUNWIND
-include arch/$(ARCH)/Makefile -include arch/$(ARCH)/Makefile
ifneq ($(OUTPUT),) ifneq ($(OUTPUT),)
BASIC_CFLAGS += -I$(OUTPUT) CFLAGS += -I$(OUTPUT)
endif endif
ifdef NO_LIBELF ifdef NO_LIBELF
...@@ -647,281 +451,74 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS)) ...@@ -647,281 +451,74 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
LIB_OBJS += $(OUTPUT)util/symbol-minimal.o LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
else # NO_LIBELF else # NO_LIBELF
BASIC_CFLAGS += -DLIBELF_SUPPORT
FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
BASIC_CFLAGS += -DLIBELF_MMAP
endif
ifndef NO_DWARF ifndef NO_DWARF
ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) LIB_OBJS += $(OUTPUT)util/probe-finder.o
msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
else
BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
EXTLIBS += -lelf -ldw
LIB_OBJS += $(OUTPUT)util/probe-finder.o
LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
endif # PERF_HAVE_DWARF_REGS
endif # NO_DWARF endif # NO_DWARF
endif # NO_LIBELF endif # NO_LIBELF
ifndef NO_LIBUNWIND ifndef NO_LIBUNWIND
BASIC_CFLAGS += -DLIBUNWIND_SUPPORT LIB_OBJS += $(OUTPUT)util/unwind.o
EXTLIBS += $(LIBUNWIND_LIBS)
BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
LIB_OBJS += $(OUTPUT)util/unwind.o
endif endif
ifndef NO_LIBAUDIT ifndef NO_LIBAUDIT
FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
else
BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
EXTLIBS += -laudit
endif
endif endif
ifndef NO_SLANG ifndef NO_SLANG
FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang LIB_OBJS += $(OUTPUT)ui/browser.o
ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y) LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev); LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
else LIB_OBJS += $(OUTPUT)ui/browsers/map.o
# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
BASIC_CFLAGS += -I/usr/include/slang LIB_OBJS += $(OUTPUT)ui/tui/setup.o
BASIC_CFLAGS += -DSLANG_SUPPORT LIB_OBJS += $(OUTPUT)ui/tui/util.o
EXTLIBS += -lslang LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
LIB_OBJS += $(OUTPUT)ui/browser.o LIB_OBJS += $(OUTPUT)ui/tui/progress.o
LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o LIB_H += ui/browser.h
LIB_OBJS += $(OUTPUT)ui/browsers/hists.o LIB_H += ui/browsers/map.h
LIB_OBJS += $(OUTPUT)ui/browsers/map.o LIB_H += ui/keysyms.h
LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o LIB_H += ui/libslang.h
LIB_OBJS += $(OUTPUT)ui/tui/setup.o
LIB_OBJS += $(OUTPUT)ui/tui/util.o
LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
LIB_OBJS += $(OUTPUT)ui/tui/progress.o
LIB_H += ui/browser.h
LIB_H += ui/browsers/map.h
LIB_H += ui/keysyms.h
LIB_H += ui/libslang.h
endif
endif endif
ifndef NO_GTK2 ifndef NO_GTK2
FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y) LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
else LIB_OBJS += $(OUTPUT)ui/gtk/util.o
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y) LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
endif LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
BASIC_CFLAGS += -DGTK2_SUPPORT
BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
LIB_OBJS += $(OUTPUT)ui/gtk/util.o
LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
endif
endif endif
ifdef NO_LIBPERL ifndef NO_LIBPERL
BASIC_CFLAGS += -DNO_LIBPERL LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
else LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
BASIC_CFLAGS += -DNO_LIBPERL
else
ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
EXTLIBS += $(PERL_EMBED_LIBADD)
LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
endif
endif endif
disable-python = $(eval $(disable-python_code)) ifndef NO_LIBPYTHON
define disable-python_code LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
BASIC_CFLAGS += -DNO_LIBPYTHON LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
$(if $(1),$(warning No $(1) was found))
$(warning Python support will not be built)
endef
override PYTHON := \
$(call get-executable-or-default,PYTHON,python)
ifndef PYTHON
$(call disable-python,python interpreter)
else
PYTHON_WORD := $(call shell-wordify,$(PYTHON))
ifdef NO_LIBPYTHON
$(call disable-python)
else
override PYTHON_CONFIG := \
$(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
ifndef PYTHON_CONFIG
$(call disable-python,python-config tool)
else
PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
$(call disable-python,Python.h (for Python 2.x))
else
ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
$(warning Python 3 is not yet supported; please set)
$(warning PYTHON and/or PYTHON_CONFIG appropriately.)
$(warning If you also have Python 2 installed, then)
$(warning try something like:)
$(warning $(and ,))
$(warning $(and ,) make PYTHON=python2)
$(warning $(and ,))
$(warning Otherwise, disable Python support entirely:)
$(warning $(and ,))
$(warning $(and ,) make NO_LIBPYTHON=1)
$(warning $(and ,))
$(error $(and ,))
else
ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
EXTLIBS += $(PYTHON_EMBED_LIBADD)
LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
LANG_BINDINGS += $(OUTPUT)python/perf.so
endif
endif
endif
endif
endif
ifdef NO_DEMANGLE
BASIC_CFLAGS += -DNO_DEMANGLE
else
ifdef HAVE_CPLUS_DEMANGLE
EXTLIBS += -liberty
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
else
FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
ifeq ($(has_bfd),y)
EXTLIBS += -lbfd
else
FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
ifeq ($(has_bfd_iberty),y)
EXTLIBS += -lbfd -liberty
else
FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
ifeq ($(has_bfd_iberty_z),y)
EXTLIBS += -lbfd -liberty -lz
else
FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
ifeq ($(has_cplus_demangle),y)
EXTLIBS += -liberty
BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
else
msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
BASIC_CFLAGS += -DNO_DEMANGLE
endif
endif
endif
endif
endif
endif endif
ifeq ($(NO_PERF_REGS),0) ifeq ($(NO_PERF_REGS),0)
ifeq ($(ARCH),x86) ifeq ($(ARCH),x86)
LIB_H += arch/x86/include/perf_regs.h LIB_H += arch/x86/include/perf_regs.h
endif endif
BASIC_CFLAGS += -DHAVE_PERF_REGS
endif
ifndef NO_STRLCPY
ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
BASIC_CFLAGS += -DHAVE_STRLCPY
endif
endif
ifndef NO_ON_EXIT
ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
BASIC_CFLAGS += -DHAVE_ON_EXIT
endif
endif
ifndef NO_BACKTRACE
ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
BASIC_CFLAGS += -DBACKTRACE_SUPPORT
endif
endif endif
ifndef NO_LIBNUMA ifndef NO_LIBNUMA
FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma BUILTIN_OBJS += $(OUTPUT)bench/numa.o
ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
else
BASIC_CFLAGS += -DLIBNUMA_SUPPORT
BUILTIN_OBJS += $(OUTPUT)bench/numa.o
EXTLIBS += -lnuma
endif
endif endif
ifdef ASCIIDOC8 ifdef ASCIIDOC8
export ASCIIDOC8 export ASCIIDOC8
endif endif
endif # MAKECMDGOALS != tags
endif # MAKECMDGOALS != clean
# Shell quote (do not use $(call) to accommodate ancient setups);
ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
bindir_SQ = $(subst ','\'',$(bindir))
bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
mandir_SQ = $(subst ','\'',$(mandir))
infodir_SQ = $(subst ','\'',$(infodir))
perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
template_dir_SQ = $(subst ','\'',$(template_dir))
htmldir_SQ = $(subst ','\'',$(htmldir))
prefix_SQ = $(subst ','\'',$(prefix))
sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
ALL_CFLAGS += $(BASIC_CFLAGS)
ALL_CFLAGS += $(ARCH_CFLAGS)
ALL_LDFLAGS += $(BASIC_LDFLAGS)
export INSTALL SHELL_PATH export INSTALL SHELL_PATH
### Build rules ### Build rules
SHELL = $(SHELL_PATH) SHELL = $(SHELL_PATH)
...@@ -939,20 +536,20 @@ strip: $(PROGRAMS) $(OUTPUT)perf ...@@ -939,20 +536,20 @@ strip: $(PROGRAMS) $(OUTPUT)perf
$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \ $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \ '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
$(ALL_CFLAGS) -c $(filter %.c,$^) -o $@ $(CFLAGS) -c $(filter %.c,$^) -o $@
$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
$(BUILTIN_OBJS) $(LIBS) -o $@ $(BUILTIN_OBJS) $(LIBS) -o $@
$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \ '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
'-DPERF_MAN_PATH="$(mandir_SQ)"' \ '-DPERF_MAN_PATH="$(mandir_SQ)"' \
'-DPERF_INFO_PATH="$(infodir_SQ)"' $< '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \ '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
'-DPERF_MAN_PATH="$(mandir_SQ)"' \ '-DPERF_MAN_PATH="$(mandir_SQ)"' \
'-DPERF_INFO_PATH="$(infodir_SQ)"' $< '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
...@@ -977,77 +574,77 @@ $(OUTPUT)perf.o perf.spec \ ...@@ -977,77 +574,77 @@ $(OUTPUT)perf.o perf.spec \
# over the general rule for .o # over the general rule for .o
$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -w $< $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $<
$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $< $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $< $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $< $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
$(OUTPUT)%.o: %.S $(OUTPUT)%.o: %.S
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
$(OUTPUT)%.s: %.S $(OUTPUT)%.s: %.S
$(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $< $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
'-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
'-DPREFIX="$(prefix_SQ)"' \ '-DPREFIX="$(prefix_SQ)"' \
$< $<
$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
'-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \ '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
$< $<
$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
-DPYTHONPATH='"$(OUTPUT)python"' \ -DPYTHONPATH='"$(OUTPUT)python"' \
-DPYTHON='"$(PYTHON_WORD)"' \ -DPYTHON='"$(PYTHON_WORD)"' \
$< $<
$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
$(OUTPUT)perf-%: %.o $(PERFLIBS) $(OUTPUT)perf-%: %.o $(PERFLIBS)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
...@@ -1134,7 +731,7 @@ cscope: ...@@ -1134,7 +731,7 @@ cscope:
$(FIND) . -name '*.[hcS]' -print | xargs cscope -b $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
### Detect prefix changes ### Detect prefix changes
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS $(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
...@@ -1155,7 +752,7 @@ check: $(OUTPUT)common-cmds.h ...@@ -1155,7 +752,7 @@ check: $(OUTPUT)common-cmds.h
then \ then \
for i in *.c */*.c; \ for i in *.c */*.c; \
do \ do \
sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \ sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
done; \ done; \
else \ else \
exit 1; \ exit 1; \
...@@ -1163,13 +760,6 @@ check: $(OUTPUT)common-cmds.h ...@@ -1163,13 +760,6 @@ check: $(OUTPUT)common-cmds.h
### Installation rules ### Installation rules
ifneq ($(filter /%,$(firstword $(perfexecdir))),)
perfexec_instdir = $(perfexecdir)
else
perfexec_instdir = $(prefix)/$(perfexecdir)
endif
perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
install-bin: all install-bin: all
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
......
...@@ -323,13 +323,20 @@ static void hists__baseline_only(struct hists *hists) ...@@ -323,13 +323,20 @@ static void hists__baseline_only(struct hists *hists)
static void hists__precompute(struct hists *hists) static void hists__precompute(struct hists *hists)
{ {
struct rb_node *next = rb_first(&hists->entries); struct rb_root *root;
struct rb_node *next;
if (sort__need_collapse)
root = &hists->entries_collapsed;
else
root = hists->entries_in;
next = rb_first(root);
while (next != NULL) { while (next != NULL) {
struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
struct hist_entry *pair = hist_entry__next_pair(he); struct hist_entry *pair = hist_entry__next_pair(he);
next = rb_next(&he->rb_node); next = rb_next(&he->rb_node_in);
if (!pair) if (!pair)
continue; continue;
...@@ -457,7 +464,7 @@ static void hists__process(struct hists *old, struct hists *new) ...@@ -457,7 +464,7 @@ static void hists__process(struct hists *old, struct hists *new)
hists__output_resort(new); hists__output_resort(new);
} }
hists__fprintf(new, true, 0, 0, stdout); hists__fprintf(new, true, 0, 0, 0, stdout);
} }
static int __cmd_diff(void) static int __cmd_diff(void)
...@@ -611,9 +618,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -611,9 +618,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
setup_pager(); setup_pager();
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", NULL); sort__setup_elide(NULL);
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", NULL);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", NULL);
return __cmd_diff(); return __cmd_diff();
} }
...@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key) ...@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key)
static bool kvm_event_expand(struct kvm_event *event, int vcpu_id) static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
{ {
int old_max_vcpu = event->max_vcpu; int old_max_vcpu = event->max_vcpu;
void *prev;
if (vcpu_id < event->max_vcpu) if (vcpu_id < event->max_vcpu)
return true; return true;
...@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id) ...@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
while (event->max_vcpu <= vcpu_id) while (event->max_vcpu <= vcpu_id)
event->max_vcpu += DEFAULT_VCPU_NUM; event->max_vcpu += DEFAULT_VCPU_NUM;
prev = event->vcpu;
event->vcpu = realloc(event->vcpu, event->vcpu = realloc(event->vcpu,
event->max_vcpu * sizeof(*event->vcpu)); event->max_vcpu * sizeof(*event->vcpu));
if (!event->vcpu) { if (!event->vcpu) {
free(prev);
pr_err("Not enough memory\n"); pr_err("Not enough memory\n");
return false; return false;
} }
......
...@@ -198,7 +198,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg) ...@@ -198,7 +198,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
return; return;
signal(signr, SIG_DFL); signal(signr, SIG_DFL);
kill(getpid(), signr);
} }
static bool perf_evlist__equal(struct perf_evlist *evlist, static bool perf_evlist__equal(struct perf_evlist *evlist,
...@@ -404,6 +403,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv) ...@@ -404,6 +403,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
signal(SIGCHLD, sig_handler); signal(SIGCHLD, sig_handler);
signal(SIGINT, sig_handler); signal(SIGINT, sig_handler);
signal(SIGUSR1, sig_handler); signal(SIGUSR1, sig_handler);
signal(SIGTERM, sig_handler);
if (!output_name) { if (!output_name) {
if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode)) if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
......
...@@ -52,6 +52,7 @@ struct perf_report { ...@@ -52,6 +52,7 @@ struct perf_report {
symbol_filter_t annotate_init; symbol_filter_t annotate_init;
const char *cpu_list; const char *cpu_list;
const char *symbol_filter_str; const char *symbol_filter_str;
float min_percent;
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
}; };
...@@ -61,6 +62,11 @@ static int perf_report_config(const char *var, const char *value, void *cb) ...@@ -61,6 +62,11 @@ static int perf_report_config(const char *var, const char *value, void *cb)
symbol_conf.event_group = perf_config_bool(var, value); symbol_conf.event_group = perf_config_bool(var, value);
return 0; return 0;
} }
if (!strcmp(var, "report.percent-limit")) {
struct perf_report *rep = cb;
rep->min_percent = strtof(value, NULL);
return 0;
}
return perf_default_config(var, value, cb); return perf_default_config(var, value, cb);
} }
...@@ -187,6 +193,9 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, ...@@ -187,6 +193,9 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
for (i = 0; i < sample->branch_stack->nr; i++) { for (i = 0; i < sample->branch_stack->nr; i++) {
if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym)) if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
continue; continue;
err = -ENOMEM;
/* /*
* The report shows the percentage of total branches captured * The report shows the percentage of total branches captured
* and not events sampled. Thus we use a pseudo period of 1. * and not events sampled. Thus we use a pseudo period of 1.
...@@ -195,7 +204,6 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, ...@@ -195,7 +204,6 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
&bi[i], 1, 1); &bi[i], 1, 1);
if (he) { if (he) {
struct annotation *notes; struct annotation *notes;
err = -ENOMEM;
bx = he->branch_info; bx = he->branch_info;
if (bx->from.sym && use_browser == 1 && sort__has_sym) { if (bx->from.sym && use_browser == 1 && sort__has_sym) {
notes = symbol__annotation(bx->from.sym); notes = symbol__annotation(bx->from.sym);
...@@ -226,11 +234,12 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool, ...@@ -226,11 +234,12 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
} }
evsel->hists.stats.total_period += 1; evsel->hists.stats.total_period += 1;
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
err = 0;
} else } else
return -ENOMEM; goto out;
} }
err = 0;
out: out:
free(bi);
return err; return err;
} }
...@@ -294,6 +303,7 @@ static int process_sample_event(struct perf_tool *tool, ...@@ -294,6 +303,7 @@ static int process_sample_event(struct perf_tool *tool,
{ {
struct perf_report *rep = container_of(tool, struct perf_report, tool); struct perf_report *rep = container_of(tool, struct perf_report, tool);
struct addr_location al; struct addr_location al;
int ret;
if (perf_event__preprocess_sample(event, machine, &al, sample, if (perf_event__preprocess_sample(event, machine, &al, sample,
rep->annotate_init) < 0) { rep->annotate_init) < 0) {
...@@ -308,28 +318,25 @@ static int process_sample_event(struct perf_tool *tool, ...@@ -308,28 +318,25 @@ static int process_sample_event(struct perf_tool *tool,
if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
return 0; return 0;
if (sort__branch_mode == 1) { if (sort__mode == SORT_MODE__BRANCH) {
if (perf_report__add_branch_hist_entry(tool, &al, sample, ret = perf_report__add_branch_hist_entry(tool, &al, sample,
evsel, machine)) { evsel, machine);
if (ret < 0)
pr_debug("problem adding lbr entry, skipping event\n"); pr_debug("problem adding lbr entry, skipping event\n");
return -1;
}
} else if (rep->mem_mode == 1) { } else if (rep->mem_mode == 1) {
if (perf_report__add_mem_hist_entry(tool, &al, sample, ret = perf_report__add_mem_hist_entry(tool, &al, sample,
evsel, machine, event)) { evsel, machine, event);
if (ret < 0)
pr_debug("problem adding mem entry, skipping event\n"); pr_debug("problem adding mem entry, skipping event\n");
return -1;
}
} else { } else {
if (al.map != NULL) if (al.map != NULL)
al.map->dso->hit = 1; al.map->dso->hit = 1;
if (perf_evsel__add_hist_entry(evsel, &al, sample, machine)) { ret = perf_evsel__add_hist_entry(evsel, &al, sample, machine);
if (ret < 0)
pr_debug("problem incrementing symbol period, skipping event\n"); pr_debug("problem incrementing symbol period, skipping event\n");
return -1;
}
} }
return 0; return ret;
} }
static int process_read_event(struct perf_tool *tool, static int process_read_event(struct perf_tool *tool,
...@@ -384,7 +391,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) ...@@ -384,7 +391,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
} }
} }
if (sort__branch_mode == 1) { if (sort__mode == SORT_MODE__BRANCH) {
if (!self->fd_pipe && if (!self->fd_pipe &&
!(sample_type & PERF_SAMPLE_BRANCH_STACK)) { !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
ui__error("Selected -b but no branch data. " ui__error("Selected -b but no branch data. "
...@@ -455,7 +462,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, ...@@ -455,7 +462,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
continue; continue;
hists__fprintf_nr_sample_events(rep, hists, evname, stdout); hists__fprintf_nr_sample_events(rep, hists, evname, stdout);
hists__fprintf(hists, true, 0, 0, stdout); hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
fprintf(stdout, "\n\n"); fprintf(stdout, "\n\n");
} }
...@@ -574,8 +581,8 @@ static int __cmd_report(struct perf_report *rep) ...@@ -574,8 +581,8 @@ static int __cmd_report(struct perf_report *rep)
if (use_browser > 0) { if (use_browser > 0) {
if (use_browser == 1) { if (use_browser == 1) {
ret = perf_evlist__tui_browse_hists(session->evlist, ret = perf_evlist__tui_browse_hists(session->evlist,
help, help, NULL,
NULL, rep->min_percent,
&session->header.env); &session->header.env);
/* /*
* Usually "ret" is the last pressed key, and we only * Usually "ret" is the last pressed key, and we only
...@@ -586,7 +593,7 @@ static int __cmd_report(struct perf_report *rep) ...@@ -586,7 +593,7 @@ static int __cmd_report(struct perf_report *rep)
} else if (use_browser == 2) { } else if (use_browser == 2) {
perf_evlist__gtk_browse_hists(session->evlist, help, perf_evlist__gtk_browse_hists(session->evlist, help,
NULL); NULL, rep->min_percent);
} }
} else } else
perf_evlist__tty_browse_hists(session->evlist, rep, help); perf_evlist__tty_browse_hists(session->evlist, rep, help);
...@@ -691,7 +698,19 @@ static int ...@@ -691,7 +698,19 @@ static int
parse_branch_mode(const struct option *opt __maybe_unused, parse_branch_mode(const struct option *opt __maybe_unused,
const char *str __maybe_unused, int unset) const char *str __maybe_unused, int unset)
{ {
sort__branch_mode = !unset; int *branch_mode = opt->value;
*branch_mode = !unset;
return 0;
}
static int
parse_percent_limit(const struct option *opt, const char *str,
int unset __maybe_unused)
{
struct perf_report *rep = opt->value;
rep->min_percent = strtof(str, NULL);
return 0; return 0;
} }
...@@ -700,6 +719,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -700,6 +719,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
struct perf_session *session; struct perf_session *session;
struct stat st; struct stat st;
bool has_br_stack = false; bool has_br_stack = false;
int branch_mode = -1;
int ret = -1; int ret = -1;
char callchain_default_opt[] = "fractal,0.5,callee"; char callchain_default_opt[] = "fractal,0.5,callee";
const char * const report_usage[] = { const char * const report_usage[] = {
...@@ -796,17 +816,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -796,17 +816,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
"Show a column with the sum of periods"), "Show a column with the sum of periods"),
OPT_BOOLEAN(0, "group", &symbol_conf.event_group, OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
"Show event group information together"), "Show event group information together"),
OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "", OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
"use branch records for histogram filling", parse_branch_mode), "use branch records for histogram filling", parse_branch_mode),
OPT_STRING(0, "objdump", &objdump_path, "path", OPT_STRING(0, "objdump", &objdump_path, "path",
"objdump binary to use for disassembly and annotations"), "objdump binary to use for disassembly and annotations"),
OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
"Disable symbol demangling"), "Disable symbol demangling"),
OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
OPT_CALLBACK(0, "percent-limit", &report, "percent",
"Don't show entries under that percent", parse_percent_limit),
OPT_END() OPT_END()
}; };
perf_config(perf_report_config, NULL); perf_config(perf_report_config, &report);
argc = parse_options(argc, argv, options, report_usage, 0); argc = parse_options(argc, argv, options, report_usage, 0);
...@@ -846,11 +868,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -846,11 +868,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
has_br_stack = perf_header__has_feat(&session->header, has_br_stack = perf_header__has_feat(&session->header,
HEADER_BRANCH_STACK); HEADER_BRANCH_STACK);
if (sort__branch_mode == -1 && has_br_stack) if (branch_mode == -1 && has_br_stack)
sort__branch_mode = 1; sort__mode = SORT_MODE__BRANCH;
/* sort__branch_mode could be 0 if --no-branch-stack */ /* sort__mode could be NORMAL if --no-branch-stack */
if (sort__branch_mode == 1) { if (sort__mode == SORT_MODE__BRANCH) {
/* /*
* if no sort_order is provided, then specify * if no sort_order is provided, then specify
* branch-mode specific order * branch-mode specific order
...@@ -861,10 +883,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -861,10 +883,12 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
} }
if (report.mem_mode) { if (report.mem_mode) {
if (sort__branch_mode == 1) { if (sort__mode == SORT_MODE__BRANCH) {
fprintf(stderr, "branch and mem mode incompatible\n"); fprintf(stderr, "branch and mem mode incompatible\n");
goto error; goto error;
} }
sort__mode = SORT_MODE__MEMORY;
/* /*
* if no sort_order is provided, then specify * if no sort_order is provided, then specify
* branch-mode specific order * branch-mode specific order
...@@ -929,25 +953,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -929,25 +953,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
report.symbol_filter_str = argv[0]; report.symbol_filter_str = argv[0];
} }
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); sort__setup_elide(stdout);
if (sort__branch_mode == 1) {
sort_entry__setup_elide(&sort_dso_from, symbol_conf.dso_from_list, "dso_from", stdout);
sort_entry__setup_elide(&sort_dso_to, symbol_conf.dso_to_list, "dso_to", stdout);
sort_entry__setup_elide(&sort_sym_from, symbol_conf.sym_from_list, "sym_from", stdout);
sort_entry__setup_elide(&sort_sym_to, symbol_conf.sym_to_list, "sym_to", stdout);
} else {
if (report.mem_mode) {
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "symbol_daddr", stdout);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso_daddr", stdout);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "mem", stdout);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "local_weight", stdout);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "tlb", stdout);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "snoop", stdout);
}
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
}
ret = __cmd_report(&report); ret = __cmd_report(&report);
if (ret == K_SWITCH_INPUT_DATA) { if (ret == K_SWITCH_INPUT_DATA) {
......
...@@ -70,10 +70,11 @@ ...@@ -70,10 +70,11 @@
static volatile int done; static volatile int done;
#define HEADER_LINE_NR 5
static void perf_top__update_print_entries(struct perf_top *top) static void perf_top__update_print_entries(struct perf_top *top)
{ {
if (top->print_entries > 9) top->print_entries = top->winsize.ws_row - HEADER_LINE_NR;
top->print_entries -= 9;
} }
static void perf_top__sig_winch(int sig __maybe_unused, static void perf_top__sig_winch(int sig __maybe_unused,
...@@ -82,13 +83,6 @@ static void perf_top__sig_winch(int sig __maybe_unused, ...@@ -82,13 +83,6 @@ static void perf_top__sig_winch(int sig __maybe_unused,
struct perf_top *top = arg; struct perf_top *top = arg;
get_term_dimensions(&top->winsize); get_term_dimensions(&top->winsize);
if (!top->print_entries
|| (top->print_entries+4) > top->winsize.ws_row) {
top->print_entries = top->winsize.ws_row;
} else {
top->print_entries += 4;
top->winsize.ws_row = top->print_entries;
}
perf_top__update_print_entries(top); perf_top__update_print_entries(top);
} }
...@@ -251,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, ...@@ -251,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
{ {
struct hist_entry *he; struct hist_entry *he;
pthread_mutex_lock(&evsel->hists.lock);
he = __hists__add_entry(&evsel->hists, al, NULL, sample->period, he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
sample->weight); sample->weight);
pthread_mutex_unlock(&evsel->hists.lock);
if (he == NULL) if (he == NULL)
return NULL; return NULL;
...@@ -290,16 +287,17 @@ static void perf_top__print_sym_table(struct perf_top *top) ...@@ -290,16 +287,17 @@ static void perf_top__print_sym_table(struct perf_top *top)
return; return;
} }
hists__collapse_resort_threaded(&top->sym_evsel->hists); hists__collapse_resort(&top->sym_evsel->hists);
hists__output_resort_threaded(&top->sym_evsel->hists); hists__output_resort(&top->sym_evsel->hists);
hists__decay_entries_threaded(&top->sym_evsel->hists, hists__decay_entries(&top->sym_evsel->hists,
top->hide_user_symbols, top->hide_user_symbols,
top->hide_kernel_symbols); top->hide_kernel_symbols);
hists__output_recalc_col_len(&top->sym_evsel->hists, hists__output_recalc_col_len(&top->sym_evsel->hists,
top->winsize.ws_row - 3); top->print_entries - printed);
putchar('\n'); putchar('\n');
hists__fprintf(&top->sym_evsel->hists, false, hists__fprintf(&top->sym_evsel->hists, false,
top->winsize.ws_row - 4 - printed, win_width, stdout); top->print_entries - printed, win_width,
top->min_percent, stdout);
} }
static void prompt_integer(int *target, const char *msg) static void prompt_integer(int *target, const char *msg)
...@@ -477,7 +475,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c) ...@@ -477,7 +475,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
perf_top__sig_winch(SIGWINCH, NULL, top); perf_top__sig_winch(SIGWINCH, NULL, top);
sigaction(SIGWINCH, &act, NULL); sigaction(SIGWINCH, &act, NULL);
} else { } else {
perf_top__sig_winch(SIGWINCH, NULL, top);
signal(SIGWINCH, SIG_DFL); signal(SIGWINCH, SIG_DFL);
} }
break; break;
...@@ -556,11 +553,11 @@ static void perf_top__sort_new_samples(void *arg) ...@@ -556,11 +553,11 @@ static void perf_top__sort_new_samples(void *arg)
if (t->evlist->selected != NULL) if (t->evlist->selected != NULL)
t->sym_evsel = t->evlist->selected; t->sym_evsel = t->evlist->selected;
hists__collapse_resort_threaded(&t->sym_evsel->hists); hists__collapse_resort(&t->sym_evsel->hists);
hists__output_resort_threaded(&t->sym_evsel->hists); hists__output_resort(&t->sym_evsel->hists);
hists__decay_entries_threaded(&t->sym_evsel->hists, hists__decay_entries(&t->sym_evsel->hists,
t->hide_user_symbols, t->hide_user_symbols,
t->hide_kernel_symbols); t->hide_kernel_symbols);
} }
static void *display_thread_tui(void *arg) static void *display_thread_tui(void *arg)
...@@ -584,7 +581,7 @@ static void *display_thread_tui(void *arg) ...@@ -584,7 +581,7 @@ static void *display_thread_tui(void *arg)
list_for_each_entry(pos, &top->evlist->entries, node) list_for_each_entry(pos, &top->evlist->entries, node)
pos->hists.uid_filter_str = top->record_opts.target.uid_str; pos->hists.uid_filter_str = top->record_opts.target.uid_str;
perf_evlist__tui_browse_hists(top->evlist, help, &hbt, perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
&top->session->header.env); &top->session->header.env);
done = 1; done = 1;
...@@ -794,7 +791,7 @@ static void perf_event__process_sample(struct perf_tool *tool, ...@@ -794,7 +791,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
return; return;
} }
if (top->sort_has_symbols) if (sort__has_sym)
perf_top__record_precise_ip(top, he, evsel->idx, ip); perf_top__record_precise_ip(top, he, evsel->idx, ip);
} }
...@@ -912,9 +909,9 @@ static int perf_top__start_counters(struct perf_top *top) ...@@ -912,9 +909,9 @@ static int perf_top__start_counters(struct perf_top *top)
return -1; return -1;
} }
static int perf_top__setup_sample_type(struct perf_top *top) static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
{ {
if (!top->sort_has_symbols) { if (!sort__has_sym) {
if (symbol_conf.use_callchain) { if (symbol_conf.use_callchain) {
ui__error("Selected -g but \"sym\" not present in --sort/-s."); ui__error("Selected -g but \"sym\" not present in --sort/-s.");
return -EINVAL; return -EINVAL;
...@@ -1025,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset) ...@@ -1025,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
return record_parse_callchain_opt(opt, arg, unset); return record_parse_callchain_opt(opt, arg, unset);
} }
static int
parse_percent_limit(const struct option *opt, const char *arg,
int unset __maybe_unused)
{
struct perf_top *top = opt->value;
top->min_percent = strtof(arg, NULL);
return 0;
}
int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
{ {
int status; int status;
...@@ -1110,6 +1117,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1110,6 +1117,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
"Specify disassembler style (e.g. -M intel for intel syntax)"), "Specify disassembler style (e.g. -M intel for intel syntax)"),
OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"),
OPT_CALLBACK(0, "percent-limit", &top, "percent",
"Don't show entries under that percent", parse_percent_limit),
OPT_END() OPT_END()
}; };
const char * const top_usage[] = { const char * const top_usage[] = {
...@@ -1133,6 +1142,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1133,6 +1142,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (setup_sorting() < 0) if (setup_sorting() < 0)
usage_with_options(top_usage, options); usage_with_options(top_usage, options);
/* display thread wants entries to be collapsed in a different tree */
sort__need_collapse = 1;
if (top.use_stdio) if (top.use_stdio)
use_browser = 0; use_browser = 0;
else if (top.use_tui) else if (top.use_tui)
...@@ -1200,15 +1212,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -1200,15 +1212,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
if (symbol__init() < 0) if (symbol__init() < 0)
return -1; return -1;
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout); sort__setup_elide(stdout);
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
/*
* Avoid annotation data structures overhead when symbols aren't on the
* sort list.
*/
top.sort_has_symbols = sort_sym.list.next != NULL;
get_term_dimensions(&top.winsize); get_term_dimensions(&top.winsize);
if (top.print_entries == 0) { if (top.print_entries == 0) {
......
uname_M := $(shell uname -m 2>/dev/null || echo not)
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/arm.*/arm/ -e s/sa110/arm/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
-e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
NO_PERF_REGS := 1
CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
override ARCH := x86
NO_PERF_REGS := 0
LIBUNWIND_LIBS = -lunwind -lunwind-x86
endif
ifeq ($(ARCH),x86_64)
override ARCH := x86
IS_X86_64 := 0
ifeq (, $(findstring m32,$(CFLAGS)))
IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
endif
ifeq (${IS_X86_64}, 1)
RAW_ARCH := x86_64
CFLAGS += -DARCH_X86_64
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
endif
NO_PERF_REGS := 0
LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
endif
ifeq ($(NO_PERF_REGS),0)
CFLAGS += -DHAVE_PERF_REGS
endif
ifeq ($(src-perf),)
src-perf := $(srctree)/tools/perf
endif
ifeq ($(obj-perf),)
obj-perf := $(objtree)
endif
ifneq ($(obj-perf),)
obj-perf := $(abspath $(obj-perf))/
endif
# include ARCH specific config
-include $(src-perf)/arch/$(ARCH)/Makefile
include $(src-perf)/config/feature-tests.mak
include $(src-perf)/config/utilities.mak
ifeq ($(call get-executable,$(FLEX)),)
dummy := $(error Error: $(FLEX) is missing on this system, please install it)
endif
ifeq ($(call get-executable,$(BISON)),)
dummy := $(error Error: $(BISON) is missing on this system, please install it)
endif
# Treat warnings as errors unless directed not to
ifneq ($(WERROR),0)
CFLAGS += -Werror
endif
ifeq ("$(origin DEBUG)", "command line")
PERF_DEBUG = $(DEBUG)
endif
ifndef PERF_DEBUG
CFLAGS += -O6
endif
ifdef PARSER_DEBUG
PARSER_DEBUG_BISON := -t
PARSER_DEBUG_FLEX := -d
CFLAGS += -DPARSER_DEBUG
endif
CFLAGS += -fno-omit-frame-pointer
CFLAGS += -ggdb3
CFLAGS += -funwind-tables
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -std=gnu99
EXTLIBS = -lpthread -lrt -lelf -lm
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
CFLAGS += -fstack-protector-all
endif
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
CFLAGS += -Wstack-protector
endif
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
CFLAGS += -Wvolatile-register-var
endif
ifndef PERF_DEBUG
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
CFLAGS += -D_FORTIFY_SOURCE=2
endif
endif
CFLAGS += -I$(src-perf)/util/include
CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi
CFLAGS += -I$(srctree)/arch/$(ARCH)/include
CFLAGS += -I$(srctree)/include/uapi
CFLAGS += -I$(srctree)/include
# $(obj-perf) for generated common-cmds.h
# $(obj-perf)/util for generated bison/flex headers
ifneq ($(OUTPUT),)
CFLAGS += -I$(obj-perf)/util
CFLAGS += -I$(obj-perf)
endif
CFLAGS += -I$(src-perf)/util
CFLAGS += -I$(src-perf)
CFLAGS += -I$(TRACE_EVENT_DIR)
CFLAGS += -I$(srctree)/tools/lib/
CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
ifndef NO_BIONIC
ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
BIONIC := 1
EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
endif
endif # NO_BIONIC
ifdef NO_LIBELF
NO_DWARF := 1
NO_DEMANGLE := 1
NO_LIBUNWIND := 1
else
FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
LIBC_SUPPORT := 1
endif
ifeq ($(BIONIC),1)
LIBC_SUPPORT := 1
endif
ifeq ($(LIBC_SUPPORT),1)
msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
NO_LIBELF := 1
NO_DWARF := 1
NO_DEMANGLE := 1
else
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
endif
else
# for linking with debug library, run like:
# make DEBUG=1 LIBDW_DIR=/opt/libdw/
ifdef LIBDW_DIR
LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
endif
FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
NO_DWARF := 1
endif # Dwarf support
endif # SOURCE_LIBELF
endif # NO_LIBELF
ifndef NO_LIBELF
CFLAGS += -DLIBELF_SUPPORT
FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
CFLAGS += -DLIBELF_MMAP
endif
# include ARCH specific config
-include $(src-perf)/arch/$(ARCH)/Makefile
ifndef NO_DWARF
ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
NO_DWARF := 1
else
CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
LDFLAGS += $(LIBDW_LDFLAGS)
EXTLIBS += -lelf -ldw
endif # PERF_HAVE_DWARF_REGS
endif # NO_DWARF
endif # NO_LIBELF
ifndef NO_LIBELF
CFLAGS += -DLIBELF_SUPPORT
FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
CFLAGS += -DLIBELF_MMAP
endif # try-cc
endif # NO_LIBELF
# There's only x86 (both 32 and 64) support for CFI unwind so far
ifneq ($(ARCH),x86)
NO_LIBUNWIND := 1
endif
ifndef NO_LIBUNWIND
# for linking with debug library, run like:
# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
ifdef LIBUNWIND_DIR
LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
endif
FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
NO_LIBUNWIND := 1
endif # Libunwind support
endif # NO_LIBUNWIND
ifndef NO_LIBUNWIND
CFLAGS += -DLIBUNWIND_SUPPORT
EXTLIBS += $(LIBUNWIND_LIBS)
CFLAGS += $(LIBUNWIND_CFLAGS)
LDFLAGS += $(LIBUNWIND_LDFLAGS)
endif # NO_LIBUNWIND
ifndef NO_LIBAUDIT
FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
NO_LIBAUDIT := 1
else
CFLAGS += -DLIBAUDIT_SUPPORT
EXTLIBS += -laudit
endif
endif
ifdef NO_NEWT
NO_SLANG=1
endif
ifndef NO_SLANG
FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
NO_SLANG := 1
else
# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
CFLAGS += -I/usr/include/slang
CFLAGS += -DSLANG_SUPPORT
EXTLIBS += -lslang
endif
endif
ifndef NO_GTK2
FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
NO_GTK2 := 1
else
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
CFLAGS += -DHAVE_GTK_INFO_BAR
endif
CFLAGS += -DGTK2_SUPPORT
CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
endif
endif
grep-libs = $(filter -l%,$(1))
strip-libs = $(filter-out -l%,$(1))
ifdef NO_LIBPERL
CFLAGS += -DNO_LIBPERL
else
PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
CFLAGS += -DNO_LIBPERL
NO_LIBPERL := 1
else
LDFLAGS += $(PERL_EMBED_LDFLAGS)
EXTLIBS += $(PERL_EMBED_LIBADD)
endif
endif
disable-python = $(eval $(disable-python_code))
define disable-python_code
CFLAGS += -DNO_LIBPYTHON
$(if $(1),$(warning No $(1) was found))
$(warning Python support will not be built)
NO_LIBPYTHON := 1
endef
override PYTHON := \
$(call get-executable-or-default,PYTHON,python)
ifndef PYTHON
$(call disable-python,python interpreter)
else
PYTHON_WORD := $(call shell-wordify,$(PYTHON))
ifdef NO_LIBPYTHON
$(call disable-python)
else
override PYTHON_CONFIG := \
$(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
ifndef PYTHON_CONFIG
$(call disable-python,python-config tool)
else
PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
$(call disable-python,Python.h (for Python 2.x))
else
ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
$(warning Python 3 is not yet supported; please set)
$(warning PYTHON and/or PYTHON_CONFIG appropriately.)
$(warning If you also have Python 2 installed, then)
$(warning try something like:)
$(warning $(and ,))
$(warning $(and ,) make PYTHON=python2)
$(warning $(and ,))
$(warning Otherwise, disable Python support entirely:)
$(warning $(and ,))
$(warning $(and ,) make NO_LIBPYTHON=1)
$(warning $(and ,))
$(error $(and ,))
else
LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
EXTLIBS += $(PYTHON_EMBED_LIBADD)
LANG_BINDINGS += $(obj-perf)python/perf.so
endif
endif
endif
endif
endif
ifdef NO_DEMANGLE
CFLAGS += -DNO_DEMANGLE
else
ifdef HAVE_CPLUS_DEMANGLE
EXTLIBS += -liberty
CFLAGS += -DHAVE_CPLUS_DEMANGLE
else
FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
ifeq ($(has_bfd),y)
EXTLIBS += -lbfd
else
FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
ifeq ($(has_bfd_iberty),y)
EXTLIBS += -lbfd -liberty
else
FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
ifeq ($(has_bfd_iberty_z),y)
EXTLIBS += -lbfd -liberty -lz
else
FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
ifeq ($(has_cplus_demangle),y)
EXTLIBS += -liberty
CFLAGS += -DHAVE_CPLUS_DEMANGLE
else
msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
CFLAGS += -DNO_DEMANGLE
endif
endif
endif
endif
endif
endif
ifndef NO_STRLCPY
ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
CFLAGS += -DHAVE_STRLCPY
endif
endif
ifndef NO_ON_EXIT
ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
CFLAGS += -DHAVE_ON_EXIT
endif
endif
ifndef NO_BACKTRACE
ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
CFLAGS += -DBACKTRACE_SUPPORT
endif
endif
ifndef NO_LIBNUMA
FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
NO_LIBNUMA := 1
else
CFLAGS += -DLIBNUMA_SUPPORT
EXTLIBS += -lnuma
endif
endif
# Among the variables below, these:
# perfexecdir
# template_dir
# mandir
# infodir
# htmldir
# ETC_PERFCONFIG (but not sysconfdir)
# can be specified as a relative path some/where/else;
# this is interpreted as relative to $(prefix) and "perf" at
# runtime figures out where they are based on the path to the executable.
# This can help installing the suite in a relocatable way.
# Make the path relative to DESTDIR, not to prefix
ifndef DESTDIR
prefix = $(HOME)
endif
bindir_relative = bin
bindir = $(prefix)/$(bindir_relative)
mandir = share/man
infodir = share/info
perfexecdir = libexec/perf-core
sharedir = $(prefix)/share
template_dir = share/perf-core/templates
htmldir = share/doc/perf-doc
ifeq ($(prefix),/usr)
sysconfdir = /etc
ETC_PERFCONFIG = $(sysconfdir)/perfconfig
else
sysconfdir = $(prefix)/etc
ETC_PERFCONFIG = etc/perfconfig
endif
lib = lib
# Shell quote (do not use $(call) to accommodate ancient setups);
ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
bindir_SQ = $(subst ','\'',$(bindir))
mandir_SQ = $(subst ','\'',$(mandir))
infodir_SQ = $(subst ','\'',$(infodir))
perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
template_dir_SQ = $(subst ','\'',$(template_dir))
htmldir_SQ = $(subst ','\'',$(htmldir))
prefix_SQ = $(subst ','\'',$(prefix))
sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
ifneq ($(filter /%,$(firstword $(perfexecdir))),)
perfexec_instdir = $(perfexecdir)
else
perfexec_instdir = $(prefix)/$(perfexecdir)
endif
perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
...@@ -27,8 +27,8 @@ watermark=0 ...@@ -27,8 +27,8 @@ watermark=0
precise_ip=0 precise_ip=0
mmap_data=0 mmap_data=0
sample_id_all=1 sample_id_all=1
exclude_host=0 exclude_host=0|1
exclude_guest=1 exclude_guest=0|1
exclude_callchain_kernel=0 exclude_callchain_kernel=0
exclude_callchain_user=0 exclude_callchain_user=0
wakeup_events=0 wakeup_events=0
......
...@@ -27,8 +27,8 @@ watermark=0 ...@@ -27,8 +27,8 @@ watermark=0
precise_ip=0 precise_ip=0
mmap_data=0 mmap_data=0
sample_id_all=0 sample_id_all=0
exclude_host=0 exclude_host=0|1
exclude_guest=1 exclude_guest=0|1
exclude_callchain_kernel=0 exclude_callchain_kernel=0
exclude_callchain_user=0 exclude_callchain_user=0
wakeup_events=0 wakeup_events=0
......
...@@ -4,5 +4,8 @@ args = -d kill >/dev/null 2>&1 ...@@ -4,5 +4,8 @@ args = -d kill >/dev/null 2>&1
[event:base-record] [event:base-record]
sample_period=4000 sample_period=4000
sample_type=271
# sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
# PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC
sample_type=33039
mmap_data=1 mmap_data=1
...@@ -4,6 +4,12 @@ ...@@ -4,6 +4,12 @@
* (git://github.com/deater/perf_event_tests) * (git://github.com/deater/perf_event_tests)
*/ */
/*
* Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
* 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
*/
#define __SANE_USERSPACE_TYPES__
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
......
...@@ -3,6 +3,12 @@ ...@@ -3,6 +3,12 @@
* perf_event_tests (git://github.com/deater/perf_event_tests) * perf_event_tests (git://github.com/deater/perf_event_tests)
*/ */
/*
* Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
* 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
*/
#define __SANE_USERSPACE_TYPES__
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
......
...@@ -70,7 +70,7 @@ static struct test { ...@@ -70,7 +70,7 @@ static struct test {
.func = test__attr, .func = test__attr,
}, },
{ {
.desc = "Test matching and linking mutliple hists", .desc = "Test matching and linking multiple hists",
.func = test__hists_link, .func = test__hists_link,
}, },
{ {
......
PERF := .
MK := Makefile
# standard single make variable specified
make_clean_all := clean all
make_python_perf_so := python/perf.so
make_debug := DEBUG=1
make_no_libperl := NO_LIBPERL=1
make_no_libpython := NO_LIBPYTHON=1
make_no_scripts := NO_LIBPYTHON=1 NO_LIBPERL=1
make_no_newt := NO_NEWT=1
make_no_slang := NO_SLANG=1
make_no_gtk2 := NO_GTK2=1
make_no_ui := NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
make_no_demangle := NO_DEMANGLE=1
make_no_libelf := NO_LIBELF=1
make_no_libunwind := NO_LIBUNWIND=1
make_no_backtrace := NO_BACKTRACE=1
make_no_libnuma := NO_LIBNUMA=1
make_no_libaudit := NO_LIBAUDIT=1
make_no_libbionic := NO_LIBBIONIC=1
make_tags := tags
make_cscope := cscope
make_help := help
make_doc := doc
make_perf_o := perf.o
make_util_map_o := util/map.o
# all the NO_* variable combined
make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
# $(run) contains all available tests
run := make_pure
run += make_clean_all
run += make_python_perf_so
run += make_debug
run += make_no_libperl
run += make_no_libpython
run += make_no_scripts
run += make_no_newt
run += make_no_slang
run += make_no_gtk2
run += make_no_ui
run += make_no_demangle
run += make_no_libelf
run += make_no_libunwind
run += make_no_backtrace
run += make_no_libnuma
run += make_no_libaudit
run += make_no_libbionic
run += make_tags
run += make_cscope
run += make_help
run += make_doc
run += make_perf_o
run += make_util_map_o
run += make_minimal
# $(run_O) contains same portion of $(run) tests with '_O' attached
# to distinguish O=... tests
run_O := $(addsuffix _O,$(run))
# disable some tests for O=...
run_O := $(filter-out make_python_perf_so_O,$(run_O))
# define test for each compile as 'test_NAME' variable
# with the test itself as a value
test_make_tags = test -f tags
test_make_cscope = test -f cscope.out
test_make_tags_O := $(test_make_tags)
test_make_cscope_O := $(test_make_cscope)
test_ok := true
test_make_help := $(test_ok)
test_make_doc := $(test_ok)
test_make_help_O := $(test_ok)
test_make_doc_O := $(test_ok)
test_make_python_perf_so := test -f $(PERF)/python/perf.so
test_make_perf_o := test -f $(PERF)/perf.o
test_make_util_map_o := test -f $(PERF)/util/map.o
# Kbuild tests only
#test_make_python_perf_so_O := test -f $$TMP/tools/perf/python/perf.so
#test_make_perf_o_O := test -f $$TMP/tools/perf/perf.o
#test_make_util_map_o_O := test -f $$TMP/tools/perf/util/map.o
test_make_perf_o_O := true
test_make_util_map_o_O := true
test_default = test -x $(PERF)/perf
test = $(if $(test_$1),$(test_$1),$(test_default))
test_default_O = test -x $$TMP/perf
test_O = $(if $(test_$1),$(test_$1),$(test_default_O))
all:
ifdef DEBUG
d := $(info run $(run))
d := $(info run_O $(run_O))
endif
MAKEFLAGS := --no-print-directory
clean := @(cd $(PERF); make -s -f $(MK) clean >/dev/null)
$(run):
$(call clean)
@cmd="cd $(PERF) && make -f $(MK) $($@)"; \
echo "- $@: $$cmd" && echo $$cmd > $@ && \
( eval $$cmd ) >> $@ 2>&1; \
echo " test: $(call test,$@)"; \
$(call test,$@) && \
rm -f $@
$(run_O):
$(call clean)
@TMP=$$(mktemp -d); \
cmd="cd $(PERF) && make -f $(MK) $($(patsubst %_O,%,$@)) O=$$TMP"; \
echo "- $@: $$cmd" && echo $$cmd > $@ && \
( eval $$cmd ) >> $@ 2>&1 && \
echo " test: $(call test_O,$@)"; \
$(call test_O,$@) && \
rm -f $@ && \
rm -rf $$TMP
all: $(run) $(run_O)
@echo OK
out: $(run_O)
@echo OK
.PHONY: all $(run) $(run_O) clean
...@@ -25,7 +25,8 @@ struct hist_browser { ...@@ -25,7 +25,8 @@ struct hist_browser {
struct map_symbol *selection; struct map_symbol *selection;
int print_seq; int print_seq;
bool show_dso; bool show_dso;
bool has_symbols; float min_pcnt;
u64 nr_pcnt_entries;
}; };
extern void hist_browser__init_hpp(void); extern void hist_browser__init_hpp(void);
...@@ -309,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser) ...@@ -309,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
"Or reduce the sampling frequency."); "Or reduce the sampling frequency.");
} }
static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
static int hist_browser__run(struct hist_browser *browser, const char *ev_name, static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
struct hist_browser_timer *hbt) struct hist_browser_timer *hbt)
{ {
...@@ -318,6 +321,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, ...@@ -318,6 +321,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
browser->b.entries = &browser->hists->entries; browser->b.entries = &browser->hists->entries;
browser->b.nr_entries = browser->hists->nr_entries; browser->b.nr_entries = browser->hists->nr_entries;
if (browser->min_pcnt)
browser->b.nr_entries = browser->nr_pcnt_entries;
hist_browser__refresh_dimensions(browser); hist_browser__refresh_dimensions(browser);
hists__browser_title(browser->hists, title, sizeof(title), ev_name); hists__browser_title(browser->hists, title, sizeof(title), ev_name);
...@@ -330,9 +335,18 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, ...@@ -330,9 +335,18 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
key = ui_browser__run(&browser->b, delay_secs); key = ui_browser__run(&browser->b, delay_secs);
switch (key) { switch (key) {
case K_TIMER: case K_TIMER: {
u64 nr_entries;
hbt->timer(hbt->arg); hbt->timer(hbt->arg);
ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
if (browser->min_pcnt) {
hist_browser__update_pcnt_entries(browser);
nr_entries = browser->nr_pcnt_entries;
} else {
nr_entries = browser->hists->nr_entries;
}
ui_browser__update_nr_entries(&browser->b, nr_entries);
if (browser->hists->stats.nr_lost_warned != if (browser->hists->stats.nr_lost_warned !=
browser->hists->stats.nr_events[PERF_RECORD_LOST]) { browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
...@@ -344,6 +358,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name, ...@@ -344,6 +358,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
hists__browser_title(browser->hists, title, sizeof(title), ev_name); hists__browser_title(browser->hists, title, sizeof(title), ev_name);
ui_browser__show_title(&browser->b, title); ui_browser__show_title(&browser->b, title);
continue; continue;
}
case 'D': { /* Debug */ case 'D': { /* Debug */
static int seq; static int seq;
struct hist_entry *h = rb_entry(browser->b.top, struct hist_entry *h = rb_entry(browser->b.top,
...@@ -796,10 +811,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) ...@@ -796,10 +811,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
for (nd = browser->top; nd; nd = rb_next(nd)) { for (nd = browser->top; nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
float percent = h->stat.period * 100.0 /
hb->hists->stats.total_period;
if (h->filtered) if (h->filtered)
continue; continue;
if (percent < hb->min_pcnt)
continue;
row += hist_browser__show_entry(hb, h, row); row += hist_browser__show_entry(hb, h, row);
if (row == browser->height) if (row == browser->height)
break; break;
...@@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser) ...@@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
return row; return row;
} }
static struct rb_node *hists__filter_entries(struct rb_node *nd) static struct rb_node *hists__filter_entries(struct rb_node *nd,
struct hists *hists,
float min_pcnt)
{ {
while (nd != NULL) { while (nd != NULL) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
float percent = h->stat.period * 100.0 /
hists->stats.total_period;
if (percent < min_pcnt)
return NULL;
if (!h->filtered) if (!h->filtered)
return nd; return nd;
...@@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd) ...@@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd)
return NULL; return NULL;
} }
static struct rb_node *hists__filter_prev_entries(struct rb_node *nd) static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
struct hists *hists,
float min_pcnt)
{ {
while (nd != NULL) { while (nd != NULL) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
if (!h->filtered) float percent = h->stat.period * 100.0 /
hists->stats.total_period;
if (!h->filtered && percent >= min_pcnt)
return nd; return nd;
nd = rb_prev(nd); nd = rb_prev(nd);
...@@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser, ...@@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
struct hist_entry *h; struct hist_entry *h;
struct rb_node *nd; struct rb_node *nd;
bool first = true; bool first = true;
struct hist_browser *hb;
hb = container_of(browser, struct hist_browser, b);
if (browser->nr_entries == 0) if (browser->nr_entries == 0)
return; return;
...@@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser, ...@@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
switch (whence) { switch (whence) {
case SEEK_SET: case SEEK_SET:
nd = hists__filter_entries(rb_first(browser->entries)); nd = hists__filter_entries(rb_first(browser->entries),
hb->hists, hb->min_pcnt);
break; break;
case SEEK_CUR: case SEEK_CUR:
nd = browser->top; nd = browser->top;
goto do_offset; goto do_offset;
case SEEK_END: case SEEK_END:
nd = hists__filter_prev_entries(rb_last(browser->entries)); nd = hists__filter_prev_entries(rb_last(browser->entries),
hb->hists, hb->min_pcnt);
first = false; first = false;
break; break;
default: default:
...@@ -897,7 +935,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser, ...@@ -897,7 +935,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
break; break;
} }
} }
nd = hists__filter_entries(rb_next(nd)); nd = hists__filter_entries(rb_next(nd), hb->hists,
hb->min_pcnt);
if (nd == NULL) if (nd == NULL)
break; break;
--offset; --offset;
...@@ -930,7 +969,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser, ...@@ -930,7 +969,8 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
} }
} }
nd = hists__filter_prev_entries(rb_prev(nd)); nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
hb->min_pcnt);
if (nd == NULL) if (nd == NULL)
break; break;
++offset; ++offset;
...@@ -1099,14 +1139,17 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser, ...@@ -1099,14 +1139,17 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
{ {
struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries)); struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
browser->hists,
browser->min_pcnt);
int printed = 0; int printed = 0;
while (nd) { while (nd) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
printed += hist_browser__fprintf_entry(browser, h, fp); printed += hist_browser__fprintf_entry(browser, h, fp);
nd = hists__filter_entries(rb_next(nd)); nd = hists__filter_entries(rb_next(nd), browser->hists,
browser->min_pcnt);
} }
return printed; return printed;
...@@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists) ...@@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
browser->b.refresh = hist_browser__refresh; browser->b.refresh = hist_browser__refresh;
browser->b.seek = ui_browser__hists_seek; browser->b.seek = ui_browser__hists_seek;
browser->b.use_navkeypressed = true; browser->b.use_navkeypressed = true;
if (sort__branch_mode == 1)
browser->has_symbols = sort_sym_from.list.next != NULL;
else
browser->has_symbols = sort_sym.list.next != NULL;
} }
return browser; return browser;
...@@ -1329,11 +1368,25 @@ static int switch_data_file(void) ...@@ -1329,11 +1368,25 @@ static int switch_data_file(void)
return ret; return ret;
} }
static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
{
u64 nr_entries = 0;
struct rb_node *nd = rb_first(&hb->hists->entries);
while (nd) {
nr_entries++;
nd = hists__filter_entries(rb_next(nd), hb->hists,
hb->min_pcnt);
}
hb->nr_pcnt_entries = nr_entries;
}
static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
const char *helpline, const char *ev_name, const char *helpline, const char *ev_name,
bool left_exits, bool left_exits,
struct hist_browser_timer *hbt, struct hist_browser_timer *hbt,
float min_pcnt,
struct perf_session_env *env) struct perf_session_env *env)
{ {
struct hists *hists = &evsel->hists; struct hists *hists = &evsel->hists;
...@@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
if (browser == NULL) if (browser == NULL)
return -1; return -1;
if (min_pcnt) {
browser->min_pcnt = min_pcnt;
hist_browser__update_pcnt_entries(browser);
}
fstack = pstack__new(2); fstack = pstack__new(2);
if (fstack == NULL) if (fstack == NULL)
goto out; goto out;
...@@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
*/ */
goto out_free_stack; goto out_free_stack;
case 'a': case 'a':
if (!browser->has_symbols) { if (!sort__has_sym) {
ui_browser__warning(&browser->b, delay_secs * 2, ui_browser__warning(&browser->b, delay_secs * 2,
"Annotation is only available for symbolic views, " "Annotation is only available for symbolic views, "
"include \"sym*\" in --sort to use it."); "include \"sym*\" in --sort to use it.");
...@@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, ...@@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
continue; continue;
} }
if (!browser->has_symbols) if (!sort__has_sym)
goto add_exit_option; goto add_exit_option;
if (sort__branch_mode == 1) { if (sort__mode == SORT_MODE__BRANCH) {
bi = browser->he_selection->branch_info; bi = browser->he_selection->branch_info;
if (browser->selection != NULL && if (browser->selection != NULL &&
bi && bi &&
...@@ -1689,6 +1747,7 @@ struct perf_evsel_menu { ...@@ -1689,6 +1747,7 @@ struct perf_evsel_menu {
struct ui_browser b; struct ui_browser b;
struct perf_evsel *selection; struct perf_evsel *selection;
bool lost_events, lost_events_warned; bool lost_events, lost_events_warned;
float min_pcnt;
struct perf_session_env *env; struct perf_session_env *env;
}; };
...@@ -1782,6 +1841,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu, ...@@ -1782,6 +1841,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
ev_name = perf_evsel__name(pos); ev_name = perf_evsel__name(pos);
key = perf_evsel__hists_browse(pos, nr_events, help, key = perf_evsel__hists_browse(pos, nr_events, help,
ev_name, true, hbt, ev_name, true, hbt,
menu->min_pcnt,
menu->env); menu->env);
ui_browser__show_title(&menu->b, title); ui_browser__show_title(&menu->b, title);
switch (key) { switch (key) {
...@@ -1843,6 +1903,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused, ...@@ -1843,6 +1903,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused,
static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
int nr_entries, const char *help, int nr_entries, const char *help,
struct hist_browser_timer *hbt, struct hist_browser_timer *hbt,
float min_pcnt,
struct perf_session_env *env) struct perf_session_env *env)
{ {
struct perf_evsel *pos; struct perf_evsel *pos;
...@@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, ...@@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
.nr_entries = nr_entries, .nr_entries = nr_entries,
.priv = evlist, .priv = evlist,
}, },
.min_pcnt = min_pcnt,
.env = env, .env = env,
}; };
...@@ -1874,6 +1936,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, ...@@ -1874,6 +1936,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
struct hist_browser_timer *hbt, struct hist_browser_timer *hbt,
float min_pcnt,
struct perf_session_env *env) struct perf_session_env *env)
{ {
int nr_entries = evlist->nr_entries; int nr_entries = evlist->nr_entries;
...@@ -1885,7 +1948,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, ...@@ -1885,7 +1948,8 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
const char *ev_name = perf_evsel__name(first); const char *ev_name = perf_evsel__name(first);
return perf_evsel__hists_browse(first, nr_entries, help, return perf_evsel__hists_browse(first, nr_entries, help,
ev_name, false, hbt, env); ev_name, false, hbt, min_pcnt,
env);
} }
if (symbol_conf.event_group) { if (symbol_conf.event_group) {
...@@ -1901,5 +1965,5 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, ...@@ -1901,5 +1965,5 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
} }
return __perf_evlist__tui_browse_hists(evlist, nr_entries, help, return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
hbt, env); hbt, min_pcnt, env);
} }
...@@ -124,7 +124,8 @@ void perf_gtk__init_hpp(void) ...@@ -124,7 +124,8 @@ void perf_gtk__init_hpp(void)
perf_gtk__hpp_color_overhead_guest_us; perf_gtk__hpp_color_overhead_guest_us;
} }
static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
float min_pcnt)
{ {
struct perf_hpp_fmt *fmt; struct perf_hpp_fmt *fmt;
GType col_types[MAX_COLUMNS]; GType col_types[MAX_COLUMNS];
...@@ -189,10 +190,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) ...@@ -189,10 +190,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
GtkTreeIter iter; GtkTreeIter iter;
float percent = h->stat.period * 100.0 /
hists->stats.total_period;
if (h->filtered) if (h->filtered)
continue; continue;
if (percent < min_pcnt)
continue;
gtk_list_store_append(store, &iter); gtk_list_store_append(store, &iter);
col_idx = 0; col_idx = 0;
...@@ -222,7 +228,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) ...@@ -222,7 +228,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
const char *help, const char *help,
struct hist_browser_timer *hbt __maybe_unused) struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt)
{ {
struct perf_evsel *pos; struct perf_evsel *pos;
GtkWidget *vbox; GtkWidget *vbox;
...@@ -286,7 +293,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, ...@@ -286,7 +293,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC); GTK_POLICY_AUTOMATIC);
perf_gtk__show_hists(scrolled_window, hists); perf_gtk__show_hists(scrolled_window, hists, min_pcnt);
tab_label = gtk_label_new(evname); tab_label = gtk_label_new(evname);
......
...@@ -334,7 +334,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size, ...@@ -334,7 +334,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
} }
size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
int max_cols, FILE *fp) int max_cols, float min_pcnt, FILE *fp)
{ {
struct perf_hpp_fmt *fmt; struct perf_hpp_fmt *fmt;
struct sort_entry *se; struct sort_entry *se;
...@@ -440,10 +440,15 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, ...@@ -440,10 +440,15 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
print_entries: print_entries:
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
float percent = h->stat.period * 100.0 /
hists->stats.total_period;
if (h->filtered) if (h->filtered)
continue; continue;
if (percent < min_pcnt)
continue;
ret += hist_entry__fprintf(h, max_cols, hists, fp); ret += hist_entry__fprintf(h, max_cols, hists, fp);
if (max_rows && ++nr_rows >= max_rows) if (max_rows && ++nr_rows >= max_rows)
......
...@@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, ...@@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
if (pipe_output) if (pipe_output)
dup2(2, 1); dup2(2, 1);
signal(SIGTERM, SIG_DFL);
close(child_ready_pipe[0]); close(child_ready_pipe[0]);
close(go_pipe[1]); close(go_pipe[1]);
fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
......
...@@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, ...@@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel,
switch (err) { switch (err) {
case EPERM: case EPERM:
case EACCES: case EACCES:
return scnprintf(msg, size, "%s", return scnprintf(msg, size,
"You may not have permission to collect %sstats.\n" "You may not have permission to collect %sstats.\n"
"Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
" -1 - Not paranoid at all\n" " -1 - Not paranoid at all\n"
......
...@@ -2391,7 +2391,6 @@ int perf_session__write_header(struct perf_session *session, ...@@ -2391,7 +2391,6 @@ int perf_session__write_header(struct perf_session *session,
} }
lseek(fd, header->data_offset + header->data_size, SEEK_SET); lseek(fd, header->data_offset + header->data_size, SEEK_SET);
header->frozen = 1;
return 0; return 0;
} }
...@@ -2871,7 +2870,6 @@ int perf_session__read_header(struct perf_session *session, int fd) ...@@ -2871,7 +2870,6 @@ int perf_session__read_header(struct perf_session *session, int fd)
session->pevent)) session->pevent))
goto out_delete_evlist; goto out_delete_evlist;
header->frozen = 1;
return 0; return 0;
out_errno: out_errno:
return -errno; return -errno;
......
...@@ -84,7 +84,6 @@ struct perf_session_env { ...@@ -84,7 +84,6 @@ struct perf_session_env {
}; };
struct perf_header { struct perf_header {
int frozen;
bool needs_swap; bool needs_swap;
s64 attr_offset; s64 attr_offset;
u64 data_offset; u64 data_offset;
......
...@@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) ...@@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
int symlen; int symlen;
u16 len; u16 len;
if (h->ms.sym) /*
hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4); * +4 accounts for '[x] ' priv level info
else { * +2 accounts for 0x prefix on raw addresses
* +3 accounts for ' y ' symtab origin info
*/
if (h->ms.sym) {
symlen = h->ms.sym->namelen + 4;
if (verbose)
symlen += BITS_PER_LONG / 4 + 2 + 3;
hists__new_col_len(hists, HISTC_SYMBOL, symlen);
} else {
symlen = unresolved_col_width + 4 + 2; symlen = unresolved_col_width + 4 + 2;
hists__new_col_len(hists, HISTC_SYMBOL, symlen); hists__new_col_len(hists, HISTC_SYMBOL, symlen);
hists__set_unres_dso_col_len(hists, HISTC_DSO); hists__set_unres_dso_col_len(hists, HISTC_DSO);
...@@ -91,12 +99,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) ...@@ -91,12 +99,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen); hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
if (h->branch_info) { if (h->branch_info) {
/*
* +4 accounts for '[x] ' priv level info
* +2 account of 0x prefix on raw addresses
*/
if (h->branch_info->from.sym) { if (h->branch_info->from.sym) {
symlen = (int)h->branch_info->from.sym->namelen + 4; symlen = (int)h->branch_info->from.sym->namelen + 4;
if (verbose)
symlen += BITS_PER_LONG / 4 + 2 + 3;
hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
symlen = dso__name_len(h->branch_info->from.map->dso); symlen = dso__name_len(h->branch_info->from.map->dso);
...@@ -109,6 +115,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) ...@@ -109,6 +115,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
if (h->branch_info->to.sym) { if (h->branch_info->to.sym) {
symlen = (int)h->branch_info->to.sym->namelen + 4; symlen = (int)h->branch_info->to.sym->namelen + 4;
if (verbose)
symlen += BITS_PER_LONG / 4 + 2 + 3;
hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
symlen = dso__name_len(h->branch_info->to.map->dso); symlen = dso__name_len(h->branch_info->to.map->dso);
...@@ -121,10 +129,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) ...@@ -121,10 +129,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
} }
if (h->mem_info) { if (h->mem_info) {
/*
* +4 accounts for '[x] ' priv level info
* +2 account of 0x prefix on raw addresses
*/
if (h->mem_info->daddr.sym) { if (h->mem_info->daddr.sym) {
symlen = (int)h->mem_info->daddr.sym->namelen + 4 symlen = (int)h->mem_info->daddr.sym->namelen + 4
+ unresolved_col_width + 2; + unresolved_col_width + 2;
...@@ -236,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) ...@@ -236,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
return he->stat.period == 0; return he->stat.period == 0;
} }
static void __hists__decay_entries(struct hists *hists, bool zap_user, void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
bool zap_kernel, bool threaded)
{ {
struct rb_node *next = rb_first(&hists->entries); struct rb_node *next = rb_first(&hists->entries);
struct hist_entry *n; struct hist_entry *n;
...@@ -256,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user, ...@@ -256,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
!n->used) { !n->used) {
rb_erase(&n->rb_node, &hists->entries); rb_erase(&n->rb_node, &hists->entries);
if (sort__need_collapse || threaded) if (sort__need_collapse)
rb_erase(&n->rb_node_in, &hists->entries_collapsed); rb_erase(&n->rb_node_in, &hists->entries_collapsed);
hist_entry__free(n); hist_entry__free(n);
...@@ -265,17 +268,6 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user, ...@@ -265,17 +268,6 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
} }
} }
void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
{
return __hists__decay_entries(hists, zap_user, zap_kernel, false);
}
void hists__decay_entries_threaded(struct hists *hists,
bool zap_user, bool zap_kernel)
{
return __hists__decay_entries(hists, zap_user, zap_kernel, true);
}
/* /*
* histogram, sorted on item, collects periods * histogram, sorted on item, collects periods
*/ */
...@@ -292,6 +284,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) ...@@ -292,6 +284,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
he->ms.map->referenced = true; he->ms.map->referenced = true;
if (he->branch_info) { if (he->branch_info) {
/*
* This branch info is (a part of) allocated from
* machine__resolve_bstack() and will be freed after
* adding new entries. So we need to save a copy.
*/
he->branch_info = malloc(sizeof(*he->branch_info));
if (he->branch_info == NULL) {
free(he);
return NULL;
}
memcpy(he->branch_info, template->branch_info,
sizeof(*he->branch_info));
if (he->branch_info->from.map) if (he->branch_info->from.map)
he->branch_info->from.map->referenced = true; he->branch_info->from.map->referenced = true;
if (he->branch_info->to.map) if (he->branch_info->to.map)
...@@ -341,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists, ...@@ -341,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
struct hist_entry *he; struct hist_entry *he;
int cmp; int cmp;
pthread_mutex_lock(&hists->lock);
p = &hists->entries_in->rb_node; p = &hists->entries_in->rb_node;
while (*p != NULL) { while (*p != NULL) {
...@@ -360,6 +364,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists, ...@@ -360,6 +364,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
if (!cmp) { if (!cmp) {
he_stat__add_period(&he->stat, period, weight); he_stat__add_period(&he->stat, period, weight);
/*
* This mem info was allocated from machine__resolve_mem
* and will not be used anymore.
*/
free(entry->mem_info);
/* If the map of an existing hist_entry has /* If the map of an existing hist_entry has
* become out-of-date due to an exec() or * become out-of-date due to an exec() or
* similar, update it. Otherwise we will * similar, update it. Otherwise we will
...@@ -382,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists, ...@@ -382,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
he = hist_entry__new(entry); he = hist_entry__new(entry);
if (!he) if (!he)
goto out_unlock; return NULL;
rb_link_node(&he->rb_node_in, parent, p); rb_link_node(&he->rb_node_in, parent, p);
rb_insert_color(&he->rb_node_in, hists->entries_in); rb_insert_color(&he->rb_node_in, hists->entries_in);
out: out:
hist_entry__add_cpumode_period(he, al->cpumode, period); hist_entry__add_cpumode_period(he, al->cpumode, period);
out_unlock:
pthread_mutex_unlock(&hists->lock);
return he; return he;
} }
...@@ -589,13 +597,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he) ...@@ -589,13 +597,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
hists__filter_entry_by_symbol(hists, he); hists__filter_entry_by_symbol(hists, he);
} }
static void __hists__collapse_resort(struct hists *hists, bool threaded) void hists__collapse_resort(struct hists *hists)
{ {
struct rb_root *root; struct rb_root *root;
struct rb_node *next; struct rb_node *next;
struct hist_entry *n; struct hist_entry *n;
if (!sort__need_collapse && !threaded) if (!sort__need_collapse)
return; return;
root = hists__get_rotate_entries_in(hists); root = hists__get_rotate_entries_in(hists);
...@@ -617,16 +625,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded) ...@@ -617,16 +625,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded)
} }
} }
void hists__collapse_resort(struct hists *hists)
{
return __hists__collapse_resort(hists, false);
}
void hists__collapse_resort_threaded(struct hists *hists)
{
return __hists__collapse_resort(hists, true);
}
/* /*
* reverse the map, sort on period. * reverse the map, sort on period.
*/ */
...@@ -713,7 +711,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, ...@@ -713,7 +711,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
rb_insert_color(&he->rb_node, entries); rb_insert_color(&he->rb_node, entries);
} }
static void __hists__output_resort(struct hists *hists, bool threaded) void hists__output_resort(struct hists *hists)
{ {
struct rb_root *root; struct rb_root *root;
struct rb_node *next; struct rb_node *next;
...@@ -722,7 +720,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded) ...@@ -722,7 +720,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
if (sort__need_collapse || threaded) if (sort__need_collapse)
root = &hists->entries_collapsed; root = &hists->entries_collapsed;
else else
root = hists->entries_in; root = hists->entries_in;
...@@ -743,16 +741,6 @@ static void __hists__output_resort(struct hists *hists, bool threaded) ...@@ -743,16 +741,6 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
} }
} }
void hists__output_resort(struct hists *hists)
{
return __hists__output_resort(hists, false);
}
void hists__output_resort_threaded(struct hists *hists)
{
return __hists__output_resort(hists, true);
}
static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h, static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
enum hist_filter filter) enum hist_filter filter)
{ {
......
...@@ -43,12 +43,12 @@ enum hist_column { ...@@ -43,12 +43,12 @@ enum hist_column {
HISTC_COMM, HISTC_COMM,
HISTC_PARENT, HISTC_PARENT,
HISTC_CPU, HISTC_CPU,
HISTC_SRCLINE,
HISTC_MISPREDICT, HISTC_MISPREDICT,
HISTC_SYMBOL_FROM, HISTC_SYMBOL_FROM,
HISTC_SYMBOL_TO, HISTC_SYMBOL_TO,
HISTC_DSO_FROM, HISTC_DSO_FROM,
HISTC_DSO_TO, HISTC_DSO_TO,
HISTC_SRCLINE,
HISTC_LOCAL_WEIGHT, HISTC_LOCAL_WEIGHT,
HISTC_GLOBAL_WEIGHT, HISTC_GLOBAL_WEIGHT,
HISTC_MEM_DADDR_SYMBOL, HISTC_MEM_DADDR_SYMBOL,
...@@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self, ...@@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
u64 weight); u64 weight);
void hists__output_resort(struct hists *self); void hists__output_resort(struct hists *self);
void hists__output_resort_threaded(struct hists *hists);
void hists__collapse_resort(struct hists *self); void hists__collapse_resort(struct hists *self);
void hists__collapse_resort_threaded(struct hists *hists);
void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
void hists__decay_entries_threaded(struct hists *hists, bool zap_user,
bool zap_kernel);
void hists__output_recalc_col_len(struct hists *hists, int max_rows); void hists__output_recalc_col_len(struct hists *hists, int max_rows);
void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h); void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h);
...@@ -119,7 +115,7 @@ void events_stats__inc(struct events_stats *stats, u32 type); ...@@ -119,7 +115,7 @@ void events_stats__inc(struct events_stats *stats, u32 type);
size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
size_t hists__fprintf(struct hists *self, bool show_header, int max_rows, size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
int max_cols, FILE *fp); int max_cols, float min_pcnt, FILE *fp);
int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr); int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
int hist_entry__annotate(struct hist_entry *self, size_t privsize); int hist_entry__annotate(struct hist_entry *self, size_t privsize);
...@@ -199,6 +195,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel, ...@@ -199,6 +195,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
struct hist_browser_timer *hbt, struct hist_browser_timer *hbt,
float min_pcnt,
struct perf_session_env *env); struct perf_session_env *env);
int script_browse(const char *script_opt); int script_browse(const char *script_opt);
#else #else
...@@ -206,6 +203,7 @@ static inline ...@@ -206,6 +203,7 @@ static inline
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused, const char *help __maybe_unused,
struct hist_browser_timer *hbt __maybe_unused, struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt __maybe_unused,
struct perf_session_env *env __maybe_unused) struct perf_session_env *env __maybe_unused)
{ {
return 0; return 0;
...@@ -233,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused) ...@@ -233,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused)
#ifdef GTK2_SUPPORT #ifdef GTK2_SUPPORT
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
struct hist_browser_timer *hbt __maybe_unused); struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt);
#else #else
static inline static inline
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
const char *help __maybe_unused, const char *help __maybe_unused,
struct hist_browser_timer *hbt __maybe_unused) struct hist_browser_timer *hbt __maybe_unused,
float min_pcnt __maybe_unused)
{ {
return 0; return 0;
} }
......
...@@ -21,6 +21,7 @@ const char *map_type__name[MAP__NR_TYPES] = { ...@@ -21,6 +21,7 @@ const char *map_type__name[MAP__NR_TYPES] = {
static inline int is_anon_memory(const char *filename) static inline int is_anon_memory(const char *filename)
{ {
return !strcmp(filename, "//anon") || return !strcmp(filename, "//anon") ||
!strcmp(filename, "/dev/zero (deleted)") ||
!strcmp(filename, "/anon_hugepage (deleted)"); !strcmp(filename, "/anon_hugepage (deleted)");
} }
......
...@@ -37,7 +37,6 @@ struct perf_session { ...@@ -37,7 +37,6 @@ struct perf_session {
int fd; int fd;
bool fd_pipe; bool fd_pipe;
bool repipe; bool repipe;
int cwdlen;
char *cwd; char *cwd;
struct ordered_samples ordered_samples; struct ordered_samples ordered_samples;
char filename[1]; char filename[1];
......
...@@ -18,8 +18,9 @@ class install_lib(_install_lib): ...@@ -18,8 +18,9 @@ class install_lib(_install_lib):
self.build_dir = build_lib self.build_dir = build_lib
cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] cflags = getenv('CFLAGS', '').split()
cflags += getenv('CFLAGS', '').split() # switch off several checks (need to be at the end of cflags list)
cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ]
build_lib = getenv('PYTHON_EXTBUILD_LIB') build_lib = getenv('PYTHON_EXTBUILD_LIB')
build_tmp = getenv('PYTHON_EXTBUILD_TMP') build_tmp = getenv('PYTHON_EXTBUILD_TMP')
......
#include "sort.h" #include "sort.h"
#include "hist.h" #include "hist.h"
#include "symbol.h"
regex_t parent_regex; regex_t parent_regex;
const char default_parent_pattern[] = "^sys_|^do_page_fault"; const char default_parent_pattern[] = "^sys_|^do_page_fault";
...@@ -9,7 +10,7 @@ const char *sort_order = default_sort_order; ...@@ -9,7 +10,7 @@ const char *sort_order = default_sort_order;
int sort__need_collapse = 0; int sort__need_collapse = 0;
int sort__has_parent = 0; int sort__has_parent = 0;
int sort__has_sym = 0; int sort__has_sym = 0;
int sort__branch_mode = -1; /* -1 = means not set */ enum sort_mode sort__mode = SORT_MODE__NORMAL;
enum sort_type sort__first_dimension; enum sort_type sort__first_dimension;
...@@ -194,7 +195,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, ...@@ -194,7 +195,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
if (verbose) { if (verbose) {
char o = map ? dso__symtab_origin(map->dso) : '!'; char o = map ? dso__symtab_origin(map->dso) : '!';
ret += repsep_snprintf(bf, size, "%-#*llx %c ", ret += repsep_snprintf(bf, size, "%-#*llx %c ",
BITS_PER_LONG / 4, ip, o); BITS_PER_LONG / 4 + 2, ip, o);
} }
ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
...@@ -871,14 +872,6 @@ static struct sort_dimension common_sort_dimensions[] = { ...@@ -871,14 +872,6 @@ static struct sort_dimension common_sort_dimensions[] = {
DIM(SORT_PARENT, "parent", sort_parent), DIM(SORT_PARENT, "parent", sort_parent),
DIM(SORT_CPU, "cpu", sort_cpu), DIM(SORT_CPU, "cpu", sort_cpu),
DIM(SORT_SRCLINE, "srcline", sort_srcline), DIM(SORT_SRCLINE, "srcline", sort_srcline),
DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
}; };
#undef DIM #undef DIM
...@@ -895,6 +888,36 @@ static struct sort_dimension bstack_sort_dimensions[] = { ...@@ -895,6 +888,36 @@ static struct sort_dimension bstack_sort_dimensions[] = {
#undef DIM #undef DIM
#define DIM(d, n, func) [d - __SORT_MEMORY_MODE] = { .name = n, .entry = &(func) }
static struct sort_dimension memory_sort_dimensions[] = {
DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
};
#undef DIM
static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
{
if (sd->taken)
return;
if (sd->entry->se_collapse)
sort__need_collapse = 1;
if (list_empty(&hist_entry__sort_list))
sort__first_dimension = idx;
list_add_tail(&sd->entry->list, &hist_entry__sort_list);
sd->taken = 1;
}
int sort_dimension__add(const char *tok) int sort_dimension__add(const char *tok)
{ {
unsigned int i; unsigned int i;
...@@ -915,25 +938,11 @@ int sort_dimension__add(const char *tok) ...@@ -915,25 +938,11 @@ int sort_dimension__add(const char *tok)
return -EINVAL; return -EINVAL;
} }
sort__has_parent = 1; sort__has_parent = 1;
} else if (sd->entry == &sort_sym || } else if (sd->entry == &sort_sym) {
sd->entry == &sort_sym_from ||
sd->entry == &sort_sym_to ||
sd->entry == &sort_mem_daddr_sym) {
sort__has_sym = 1; sort__has_sym = 1;
} }
if (sd->taken) __sort_dimension__add(sd, i);
return 0;
if (sd->entry->se_collapse)
sort__need_collapse = 1;
if (list_empty(&hist_entry__sort_list))
sort__first_dimension = i;
list_add_tail(&sd->entry->list, &hist_entry__sort_list);
sd->taken = 1;
return 0; return 0;
} }
...@@ -943,24 +952,29 @@ int sort_dimension__add(const char *tok) ...@@ -943,24 +952,29 @@ int sort_dimension__add(const char *tok)
if (strncasecmp(tok, sd->name, strlen(tok))) if (strncasecmp(tok, sd->name, strlen(tok)))
continue; continue;
if (sort__branch_mode != 1) if (sort__mode != SORT_MODE__BRANCH)
return -EINVAL; return -EINVAL;
if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
sort__has_sym = 1; sort__has_sym = 1;
if (sd->taken) __sort_dimension__add(sd, i + __SORT_BRANCH_STACK);
return 0; return 0;
}
if (sd->entry->se_collapse) for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
sort__need_collapse = 1; struct sort_dimension *sd = &memory_sort_dimensions[i];
if (list_empty(&hist_entry__sort_list)) if (strncasecmp(tok, sd->name, strlen(tok)))
sort__first_dimension = i + __SORT_BRANCH_STACK; continue;
list_add_tail(&sd->entry->list, &hist_entry__sort_list); if (sort__mode != SORT_MODE__MEMORY)
sd->taken = 1; return -EINVAL;
if (sd->entry == &sort_mem_daddr_sym)
sort__has_sym = 1;
__sort_dimension__add(sd, i + __SORT_MEMORY_MODE);
return 0; return 0;
} }
...@@ -993,8 +1007,9 @@ int setup_sorting(void) ...@@ -993,8 +1007,9 @@ int setup_sorting(void)
return ret; return ret;
} }
void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, static void sort_entry__setup_elide(struct sort_entry *self,
const char *list_name, FILE *fp) struct strlist *list,
const char *list_name, FILE *fp)
{ {
if (list && strlist__nr_entries(list) == 1) { if (list && strlist__nr_entries(list) == 1) {
if (fp != NULL) if (fp != NULL)
...@@ -1003,3 +1018,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, ...@@ -1003,3 +1018,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
self->elide = true; self->elide = true;
} }
} }
void sort__setup_elide(FILE *output)
{
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"dso", output);
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list,
"comm", output);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list,
"symbol", output);
if (sort__mode == SORT_MODE__BRANCH) {
sort_entry__setup_elide(&sort_dso_from,
symbol_conf.dso_from_list,
"dso_from", output);
sort_entry__setup_elide(&sort_dso_to,
symbol_conf.dso_to_list,
"dso_to", output);
sort_entry__setup_elide(&sort_sym_from,
symbol_conf.sym_from_list,
"sym_from", output);
sort_entry__setup_elide(&sort_sym_to,
symbol_conf.sym_to_list,
"sym_to", output);
} else if (sort__mode == SORT_MODE__MEMORY) {
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"symbol_daddr", output);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"dso_daddr", output);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"mem", output);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"local_weight", output);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"tlb", output);
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
"snoop", output);
}
}
...@@ -32,7 +32,7 @@ extern const char default_sort_order[]; ...@@ -32,7 +32,7 @@ extern const char default_sort_order[];
extern int sort__need_collapse; extern int sort__need_collapse;
extern int sort__has_parent; extern int sort__has_parent;
extern int sort__has_sym; extern int sort__has_sym;
extern int sort__branch_mode; extern enum sort_mode sort__mode;
extern struct sort_entry sort_comm; extern struct sort_entry sort_comm;
extern struct sort_entry sort_dso; extern struct sort_entry sort_dso;
extern struct sort_entry sort_sym; extern struct sort_entry sort_sym;
...@@ -117,12 +117,18 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he) ...@@ -117,12 +117,18 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he)
return NULL; return NULL;
} }
static inline void hist_entry__add_pair(struct hist_entry *he, static inline void hist_entry__add_pair(struct hist_entry *pair,
struct hist_entry *pair) struct hist_entry *he)
{ {
list_add_tail(&he->pairs.head, &pair->pairs.node); list_add_tail(&pair->pairs.node, &he->pairs.head);
} }
enum sort_mode {
SORT_MODE__NORMAL,
SORT_MODE__BRANCH,
SORT_MODE__MEMORY,
};
enum sort_type { enum sort_type {
/* common sort keys */ /* common sort keys */
SORT_PID, SORT_PID,
...@@ -132,14 +138,6 @@ enum sort_type { ...@@ -132,14 +138,6 @@ enum sort_type {
SORT_PARENT, SORT_PARENT,
SORT_CPU, SORT_CPU,
SORT_SRCLINE, SORT_SRCLINE,
SORT_LOCAL_WEIGHT,
SORT_GLOBAL_WEIGHT,
SORT_MEM_DADDR_SYMBOL,
SORT_MEM_DADDR_DSO,
SORT_MEM_LOCKED,
SORT_MEM_TLB,
SORT_MEM_LVL,
SORT_MEM_SNOOP,
/* branch stack specific sort keys */ /* branch stack specific sort keys */
__SORT_BRANCH_STACK, __SORT_BRANCH_STACK,
...@@ -148,6 +146,17 @@ enum sort_type { ...@@ -148,6 +146,17 @@ enum sort_type {
SORT_SYM_FROM, SORT_SYM_FROM,
SORT_SYM_TO, SORT_SYM_TO,
SORT_MISPREDICT, SORT_MISPREDICT,
/* memory mode specific sort keys */
__SORT_MEMORY_MODE,
SORT_LOCAL_WEIGHT = __SORT_MEMORY_MODE,
SORT_GLOBAL_WEIGHT,
SORT_MEM_DADDR_SYMBOL,
SORT_MEM_DADDR_DSO,
SORT_MEM_LOCKED,
SORT_MEM_TLB,
SORT_MEM_LVL,
SORT_MEM_SNOOP,
}; };
/* /*
...@@ -172,7 +181,6 @@ extern struct list_head hist_entry__sort_list; ...@@ -172,7 +181,6 @@ extern struct list_head hist_entry__sort_list;
int setup_sorting(void); int setup_sorting(void);
extern int sort_dimension__add(const char *); extern int sort_dimension__add(const char *);
void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, void sort__setup_elide(FILE *fp);
const char *list_name, FILE *fp);
#endif /* __PERF_SORT_H */ #endif /* __PERF_SORT_H */
...@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats) ...@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats)
{ {
double variance, variance_mean; double variance, variance_mean;
if (!stats->n) if (stats->n < 2)
return 0.0; return 0.0;
variance = stats->M2 / (stats->n - 1); variance = stats->M2 / (stats->n - 1);
......
...@@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid) ...@@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid)
if (self != NULL) { if (self != NULL) {
map_groups__init(&self->mg); map_groups__init(&self->mg);
self->pid = pid; self->pid = pid;
self->ppid = -1;
self->comm = malloc(32); self->comm = malloc(32);
if (self->comm) if (self->comm)
snprintf(self->comm, 32, ":%d", self->pid); snprintf(self->comm, 32, ":%d", self->pid);
...@@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent) ...@@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent)
for (i = 0; i < MAP__NR_TYPES; ++i) for (i = 0; i < MAP__NR_TYPES; ++i)
if (map_groups__clone(&self->mg, &parent->mg, i) < 0) if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
return -ENOMEM; return -ENOMEM;
self->ppid = parent->pid;
return 0; return 0;
} }
...@@ -13,6 +13,7 @@ struct thread { ...@@ -13,6 +13,7 @@ struct thread {
}; };
struct map_groups mg; struct map_groups mg;
pid_t pid; pid_t pid;
pid_t ppid;
char shortname[3]; char shortname[3];
bool comm_set; bool comm_set;
char *comm; char *comm;
......
...@@ -23,20 +23,31 @@ ...@@ -23,20 +23,31 @@
size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
{ {
float samples_per_sec = top->samples / top->delay_secs; float samples_per_sec;
float ksamples_per_sec = top->kernel_samples / top->delay_secs; float ksamples_per_sec;
float esamples_percent = (100.0 * top->exact_samples) / top->samples; float esamples_percent;
struct perf_record_opts *opts = &top->record_opts; struct perf_record_opts *opts = &top->record_opts;
struct perf_target *target = &opts->target; struct perf_target *target = &opts->target;
size_t ret = 0; size_t ret = 0;
if (top->samples) {
samples_per_sec = top->samples / top->delay_secs;
ksamples_per_sec = top->kernel_samples / top->delay_secs;
esamples_percent = (100.0 * top->exact_samples) / top->samples;
} else {
samples_per_sec = ksamples_per_sec = esamples_percent = 0.0;
}
if (!perf_guest) { if (!perf_guest) {
float ksamples_percent = 0.0;
if (samples_per_sec)
ksamples_percent = (100.0 * ksamples_per_sec) /
samples_per_sec;
ret = SNPRINTF(bf, size, ret = SNPRINTF(bf, size,
" PerfTop:%8.0f irqs/sec kernel:%4.1f%%" " PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
" exact: %4.1f%% [", samples_per_sec, " exact: %4.1f%% [", samples_per_sec,
100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) / ksamples_percent, esamples_percent);
samples_per_sec)),
esamples_percent);
} else { } else {
float us_samples_per_sec = top->us_samples / top->delay_secs; float us_samples_per_sec = top->us_samples / top->delay_secs;
float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs; float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
......
...@@ -26,7 +26,6 @@ struct perf_top { ...@@ -26,7 +26,6 @@ struct perf_top {
int print_entries, count_filter, delay_secs; int print_entries, count_filter, delay_secs;
bool hide_kernel_symbols, hide_user_symbols, zero; bool hide_kernel_symbols, hide_user_symbols, zero;
bool use_tui, use_stdio; bool use_tui, use_stdio;
bool sort_has_symbols;
bool kptr_restrict_warned; bool kptr_restrict_warned;
bool vmlinux_warned; bool vmlinux_warned;
bool dump_symtab; bool dump_symtab;
...@@ -37,6 +36,7 @@ struct perf_top { ...@@ -37,6 +36,7 @@ struct perf_top {
int realtime_prio; int realtime_prio;
int sym_pcnt_filter; int sym_pcnt_filter;
const char *sym_filter; const char *sym_filter;
float min_percent;
}; };
size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
......
...@@ -221,8 +221,8 @@ extern unsigned char sane_ctype[256]; ...@@ -221,8 +221,8 @@ extern unsigned char sane_ctype[256];
#define isalpha(x) sane_istest(x,GIT_ALPHA) #define isalpha(x) sane_istest(x,GIT_ALPHA)
#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
#define isprint(x) sane_istest(x,GIT_PRINT) #define isprint(x) sane_istest(x,GIT_PRINT)
#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20)) #define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20))
#define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20)) #define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20))
#define tolower(x) sane_case((unsigned char)(x), 0x20) #define tolower(x) sane_case((unsigned char)(x), 0x20)
#define toupper(x) sane_case((unsigned char)(x), 0) #define toupper(x) sane_case((unsigned char)(x), 0)
......
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