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: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) iQIcBAABAgAGBQJRp3FFAAoJENZQFvNTUqpAjD0QAKOBjf/6XxZOOj4KJmv9oafa f4tNGtAVJMTtsQpGF/yWhaezJaUCkkY0SaRECNibh0DXv29zDrVZNqClonxhgIIf Ruu4zH6T5GudwXy56Bp2Jdt4S9g++u1QZueoq8Q3TfYNUf1iinxBwkvl/hQGfnAB ob2w7TPkd6weL/+28Thj+pT5GoPbJTyAGK6VN4Vs7sZjD0NN+8UlwQY2LUQCX8Qj qMa8IVwvVGrEGVAeOPvws5z7oFPrcuHZ/mtyxnGzn01AoZun1BQ+WDZNly8714sz b22h1BudEXW/+aMNmvM1lpaJDWVK0AC27rcdqDTCeHu4bVwM2Aof01MVgNW59tkn nUanAlQ7a9FRvnKyexNVje5FLasEOikBj7Oxl2rud/IDMmUTl/Yio/1rqhLcls17 A1JjwyNKdKNykZeVJZcvSLCcyBTCR2awMbe1cTN5+RWQG5TWX6aLLsR8KRxT2zI0 kDnb9EIXUg5KBryuYcEhr8XzViUZlC0rSs9oDPY+raH+Ch9tnNonmMtBvGQWCJnR WSEF0XXj9n/C/9nXbbuYCBPYgrosraJlRaHz08aY1EL9rAehkDCJMpPVhXhojKX2 wJ2uNhCVp9A3DGViBZKk+lt/2JzOmXBMwobhQNzLSECd+0s5wIbd78larh0EiWQp QsrWtnxB+eIh7P5BrsJY =hnhv -----END PGP SIGNATURE----- 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: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
commit
afb71193a4
@ -27,14 +27,36 @@ Description: Generic performance monitoring events
|
||||
"basename".
|
||||
|
||||
|
||||
What: /sys/devices/cpu/events/PM_LD_MISS_L1
|
||||
/sys/devices/cpu/events/PM_LD_REF_L1
|
||||
/sys/devices/cpu/events/PM_CYC
|
||||
What: /sys/devices/cpu/events/PM_1PLUS_PPC_CMPL
|
||||
/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_INST_CMPL
|
||||
/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
|
||||
|
||||
|
@ -9,6 +9,12 @@ Description:
|
||||
we want to export, so that userspace can deal with sane
|
||||
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'
|
||||
Defines contents of attribute that occupies bits 1,6-10,44 of
|
||||
perf_event_attr::config1.
|
||||
|
@ -62,6 +62,29 @@
|
||||
#define PME_PM_BRU_FIN 0x10068
|
||||
#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:
|
||||
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||
@ -393,6 +416,31 @@ POWER_EVENT_ATTR(LD_MISS_L1, LD_MISS_L1);
|
||||
POWER_EVENT_ATTR(BRU_FIN, BRU_FIN)
|
||||
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[] = {
|
||||
GENERIC_EVENT_PTR(CYC),
|
||||
GENERIC_EVENT_PTR(GCT_NOSLOT_CYC),
|
||||
@ -411,6 +459,31 @@ static struct attribute *power7_events_attr[] = {
|
||||
POWER_EVENT_PTR(LD_MISS_L1),
|
||||
POWER_EVENT_PTR(BRU_FIN),
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
include ../../scripts/Makefile.include
|
||||
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
|
||||
# guard against environment variables
|
||||
LIB_H=
|
||||
LIB_OBJS=
|
||||
|
@ -13,7 +13,7 @@ SYNOPSIS
|
||||
DESCRIPTION
|
||||
-----------
|
||||
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.
|
||||
|
||||
|
||||
|
@ -210,6 +210,10 @@ OPTIONS
|
||||
Demangle symbol names to human readable form. It's enabled by default,
|
||||
disable with --no-demangle.
|
||||
|
||||
--percent-limit::
|
||||
Do not show entries which have an overhead under that percent.
|
||||
(Default: 0).
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-stat[1], linkperf:perf-annotate[1]
|
||||
|
@ -155,6 +155,10 @@ Default is to monitor all CPUS.
|
||||
|
||||
Default: fractal,0.5,callee.
|
||||
|
||||
--percent-limit::
|
||||
Do not show entries which have an overhead under that percent.
|
||||
(Default: 0).
|
||||
|
||||
INTERACTIVE PROMPTING KEYS
|
||||
--------------------------
|
||||
|
||||
|
@ -51,148 +51,10 @@ include config/utilities.mak
|
||||
# Define NO_BACKTRACE if you do not want stack backtrace debug feature
|
||||
#
|
||||
# Define NO_LIBNUMA if you do not want numa perf benchmark
|
||||
|
||||
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
|
||||
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
ifdef PARSER_DEBUG
|
||||
PARSER_DEBUG_BISON := -t
|
||||
PARSER_DEBUG_FLEX := -d
|
||||
PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
|
||||
endif
|
||||
|
||||
ifdef NO_NEWT
|
||||
NO_SLANG=1
|
||||
endif
|
||||
|
||||
CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
|
||||
EXTLIBS = -lpthread -lrt -lelf -lm
|
||||
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
|
||||
|
||||
RM = rm -f
|
||||
MKDIR = mkdir
|
||||
FIND = find
|
||||
INSTALL = install
|
||||
FLEX = flex
|
||||
BISON= bison
|
||||
|
||||
# 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)
|
||||
CFLAGS := $(CFLAGS) -fstack-protector-all
|
||||
endif
|
||||
|
||||
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
|
||||
CFLAGS := $(CFLAGS) -Wstack-protector
|
||||
endif
|
||||
|
||||
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
|
||||
CFLAGS := $(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 := $(CFLAGS) -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
endif
|
||||
|
||||
### --- END CONFIGURATION SECTION ---
|
||||
#
|
||||
# Define NO_LIBAUDIT if you do not want libaudit support
|
||||
#
|
||||
# Define NO_LIBBIONIC if you do not want bionic support
|
||||
|
||||
ifeq ($(srctree),)
|
||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||
@ -208,32 +70,44 @@ ifneq ($(OUTPUT),)
|
||||
#$(info Determined 'OUTPUT' to be $(OUTPUT))
|
||||
endif
|
||||
|
||||
BASIC_CFLAGS = \
|
||||
-Iutil/include \
|
||||
-Iarch/$(ARCH)/include \
|
||||
$(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
|
||||
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
|
||||
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
|
||||
|
||||
BASIC_LDFLAGS =
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
|
||||
ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
|
||||
BIONIC := 1
|
||||
EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
|
||||
EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
|
||||
BASIC_CFLAGS += -I.
|
||||
RM = rm -f
|
||||
MKDIR = mkdir
|
||||
FIND = find
|
||||
INSTALL = install
|
||||
FLEX = flex
|
||||
BISON = bison
|
||||
STRIP = strip
|
||||
|
||||
LK_DIR = $(srctree)/tools/lib/lk/
|
||||
TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
|
||||
|
||||
# include config/Makefile by default and rule out
|
||||
# non-config cases
|
||||
config := 1
|
||||
|
||||
NON_CONFIG_TARGETS := clean TAGS tags cscope help
|
||||
|
||||
ifdef MAKECMDGOALS
|
||||
ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
|
||||
config := 0
|
||||
endif
|
||||
endif # MAKECMDGOALS != tags
|
||||
endif # MAKECMDGOALS != clean
|
||||
endif
|
||||
|
||||
ifeq ($(config),1)
|
||||
include config/Makefile
|
||||
endif
|
||||
|
||||
export prefix bindir sharedir sysconfdir
|
||||
|
||||
# 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__
|
||||
|
||||
# Guard against environment variables
|
||||
BUILTIN_OBJS =
|
||||
@ -247,20 +121,17 @@ SCRIPT_SH += perf-archive.sh
|
||||
grep-libs = $(filter -l%,$(1))
|
||||
strip-libs = $(filter-out -l%,$(1))
|
||||
|
||||
LK_DIR = ../lib/lk/
|
||||
TRACE_EVENT_DIR = ../lib/traceevent/
|
||||
|
||||
LK_PATH=$(LK_DIR)
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
TE_PATH=$(OUTPUT)
|
||||
TE_PATH=$(OUTPUT)
|
||||
ifneq ($(subdir),)
|
||||
LK_PATH=$(OUTPUT)$(LK_DIR)
|
||||
LK_PATH=$(OUTPUT)$(LK_DIR)
|
||||
else
|
||||
LK_PATH=$(OUTPUT)
|
||||
LK_PATH=$(OUTPUT)
|
||||
endif
|
||||
else
|
||||
TE_PATH=$(TRACE_EVENT_DIR)
|
||||
TE_PATH=$(TRACE_EVENT_DIR)
|
||||
endif
|
||||
|
||||
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
||||
@ -278,10 +149,10 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
|
||||
python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
|
||||
|
||||
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)
|
||||
$(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
|
||||
$(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
|
||||
--quiet build_ext; \
|
||||
mkdir -p $(OUTPUT)python && \
|
||||
cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
|
||||
@ -296,8 +167,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
|
||||
#
|
||||
PROGRAMS += $(OUTPUT)perf
|
||||
|
||||
LANG_BINDINGS =
|
||||
|
||||
# what 'all' will build and 'install' will install, in perfexecdir
|
||||
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
|
||||
|
||||
@ -306,10 +175,10 @@ OTHER_PROGRAMS = $(OUTPUT)perf
|
||||
|
||||
# Set paths to tools early so that they can be used for version tests.
|
||||
ifndef SHELL_PATH
|
||||
SHELL_PATH = /bin/sh
|
||||
SHELL_PATH = /bin/sh
|
||||
endif
|
||||
ifndef PERL_PATH
|
||||
PERL_PATH = /usr/bin/perl
|
||||
PERL_PATH = /usr/bin/perl
|
||||
endif
|
||||
|
||||
export PERL_PATH
|
||||
@ -557,79 +426,14 @@ BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
|
||||
|
||||
PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
|
||||
|
||||
#
|
||||
# Platform specific tweaks
|
||||
#
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),tags)
|
||||
|
||||
# We choose to avoid "if .. else if .. else .. endif endif"
|
||||
# because maintaining the nesting to match is a pain. If
|
||||
# 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
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
BASIC_CFLAGS += -I$(OUTPUT)
|
||||
CFLAGS += -I$(OUTPUT)
|
||||
endif
|
||||
|
||||
ifdef NO_LIBELF
|
||||
@ -647,281 +451,74 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
|
||||
LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
|
||||
|
||||
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
|
||||
ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
|
||||
msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
|
||||
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
|
||||
LIB_OBJS += $(OUTPUT)util/probe-finder.o
|
||||
LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
|
||||
endif # NO_DWARF
|
||||
endif # NO_LIBELF
|
||||
|
||||
ifndef NO_LIBUNWIND
|
||||
BASIC_CFLAGS += -DLIBUNWIND_SUPPORT
|
||||
EXTLIBS += $(LIBUNWIND_LIBS)
|
||||
BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
|
||||
BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
|
||||
LIB_OBJS += $(OUTPUT)util/unwind.o
|
||||
LIB_OBJS += $(OUTPUT)util/unwind.o
|
||||
endif
|
||||
|
||||
ifndef NO_LIBAUDIT
|
||||
FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_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);
|
||||
else
|
||||
BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
|
||||
EXTLIBS += -laudit
|
||||
endif
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
|
||||
endif
|
||||
|
||||
ifndef NO_SLANG
|
||||
FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_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);
|
||||
else
|
||||
# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
|
||||
BASIC_CFLAGS += -I/usr/include/slang
|
||||
BASIC_CFLAGS += -DSLANG_SUPPORT
|
||||
EXTLIBS += -lslang
|
||||
LIB_OBJS += $(OUTPUT)ui/browser.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/map.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
|
||||
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
|
||||
LIB_OBJS += $(OUTPUT)ui/browser.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/map.o
|
||||
LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
|
||||
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
|
||||
|
||||
ifndef NO_GTK2
|
||||
FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_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);
|
||||
else
|
||||
ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
|
||||
BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR
|
||||
endif
|
||||
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
|
||||
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
|
||||
|
||||
ifdef NO_LIBPERL
|
||||
BASIC_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)
|
||||
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
|
||||
ifndef NO_LIBPERL
|
||||
LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
|
||||
LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
|
||||
endif
|
||||
|
||||
disable-python = $(eval $(disable-python_code))
|
||||
define disable-python_code
|
||||
BASIC_CFLAGS += -DNO_LIBPYTHON
|
||||
$(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
|
||||
ifndef NO_LIBPYTHON
|
||||
LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
|
||||
LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
|
||||
endif
|
||||
|
||||
ifeq ($(NO_PERF_REGS),0)
|
||||
ifeq ($(ARCH),x86)
|
||||
LIB_H += arch/x86/include/perf_regs.h
|
||||
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
|
||||
ifeq ($(ARCH),x86)
|
||||
LIB_H += arch/x86/include/perf_regs.h
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_LIBNUMA
|
||||
FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_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);
|
||||
else
|
||||
BASIC_CFLAGS += -DLIBNUMA_SUPPORT
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/numa.o
|
||||
EXTLIBS += -lnuma
|
||||
endif
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/numa.o
|
||||
endif
|
||||
|
||||
ifdef ASCIIDOC8
|
||||
export ASCIIDOC8
|
||||
export ASCIIDOC8
|
||||
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
|
||||
|
||||
ALL_CFLAGS += $(BASIC_CFLAGS)
|
||||
ALL_CFLAGS += $(ARCH_CFLAGS)
|
||||
ALL_LDFLAGS += $(BASIC_LDFLAGS)
|
||||
|
||||
export INSTALL SHELL_PATH
|
||||
|
||||
|
||||
### Build rules
|
||||
|
||||
SHELL = $(SHELL_PATH)
|
||||
@ -939,20 +536,20 @@ strip: $(PROGRAMS) $(OUTPUT)perf
|
||||
$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
|
||||
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
|
||||
$(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
|
||||
$(CFLAGS) -c $(filter %.c,$^) -o $@
|
||||
|
||||
$(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 $@
|
||||
|
||||
$(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_MAN_PATH="$(mandir_SQ)"' \
|
||||
'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
|
||||
|
||||
$(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_MAN_PATH="$(mandir_SQ)"' \
|
||||
'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
|
||||
@ -977,77 +574,77 @@ $(OUTPUT)perf.o perf.spec \
|
||||
# over the general rule for .o
|
||||
|
||||
$(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
|
||||
$(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
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(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
|
||||
$(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $<
|
||||
$(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
|
||||
$(OUTPUT)%.o: %.S
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
|
||||
$(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
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
|
||||
'-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
|
||||
'-DPREFIX="$(prefix_SQ)"' \
|
||||
$<
|
||||
|
||||
$(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)"' \
|
||||
$<
|
||||
|
||||
$(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"' \
|
||||
-DPYTHON='"$(PYTHON_WORD)"' \
|
||||
$<
|
||||
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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
|
||||
$(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)
|
||||
$(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)
|
||||
$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
|
||||
@ -1134,7 +731,7 @@ cscope:
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs cscope -b
|
||||
|
||||
### Detect prefix changes
|
||||
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
|
||||
TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
|
||||
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
|
||||
|
||||
$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
|
||||
@ -1155,7 +752,7 @@ check: $(OUTPUT)common-cmds.h
|
||||
then \
|
||||
for i in *.c */*.c; \
|
||||
do \
|
||||
sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
|
||||
sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
|
||||
done; \
|
||||
else \
|
||||
exit 1; \
|
||||
@ -1163,13 +760,6 @@ check: $(OUTPUT)common-cmds.h
|
||||
|
||||
### 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) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
|
@ -323,13 +323,20 @@ static void hists__baseline_only(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) {
|
||||
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);
|
||||
|
||||
next = rb_next(&he->rb_node);
|
||||
next = rb_next(&he->rb_node_in);
|
||||
if (!pair)
|
||||
continue;
|
||||
|
||||
@ -457,7 +464,7 @@ static void hists__process(struct hists *old, struct hists *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)
|
||||
@ -611,9 +618,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
|
||||
setup_pager();
|
||||
|
||||
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", 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);
|
||||
sort__setup_elide(NULL);
|
||||
|
||||
return __cmd_diff();
|
||||
}
|
||||
|
@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key)
|
||||
static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
|
||||
{
|
||||
int old_max_vcpu = event->max_vcpu;
|
||||
void *prev;
|
||||
|
||||
if (vcpu_id < event->max_vcpu)
|
||||
return true;
|
||||
@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
|
||||
while (event->max_vcpu <= vcpu_id)
|
||||
event->max_vcpu += DEFAULT_VCPU_NUM;
|
||||
|
||||
prev = event->vcpu;
|
||||
event->vcpu = realloc(event->vcpu,
|
||||
event->max_vcpu * sizeof(*event->vcpu));
|
||||
if (!event->vcpu) {
|
||||
free(prev);
|
||||
pr_err("Not enough memory\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -198,7 +198,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
|
||||
return;
|
||||
|
||||
signal(signr, SIG_DFL);
|
||||
kill(getpid(), signr);
|
||||
}
|
||||
|
||||
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)
|
||||
signal(SIGCHLD, sig_handler);
|
||||
signal(SIGINT, sig_handler);
|
||||
signal(SIGUSR1, sig_handler);
|
||||
signal(SIGTERM, sig_handler);
|
||||
|
||||
if (!output_name) {
|
||||
if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
|
||||
|
@ -52,6 +52,7 @@ struct perf_report {
|
||||
symbol_filter_t annotate_init;
|
||||
const char *cpu_list;
|
||||
const char *symbol_filter_str;
|
||||
float min_percent;
|
||||
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
|
||||
};
|
||||
|
||||
@ -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);
|
||||
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);
|
||||
}
|
||||
@ -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++) {
|
||||
if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
|
||||
continue;
|
||||
|
||||
err = -ENOMEM;
|
||||
|
||||
/*
|
||||
* The report shows the percentage of total branches captured
|
||||
* 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,
|
||||
&bi[i], 1, 1);
|
||||
if (he) {
|
||||
struct annotation *notes;
|
||||
err = -ENOMEM;
|
||||
bx = he->branch_info;
|
||||
if (bx->from.sym && use_browser == 1 && sort__has_sym) {
|
||||
notes = symbol__annotation(bx->from.sym);
|
||||
@ -226,11 +234,12 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
|
||||
}
|
||||
evsel->hists.stats.total_period += 1;
|
||||
hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
|
||||
err = 0;
|
||||
} else
|
||||
return -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
err = 0;
|
||||
out:
|
||||
free(bi);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -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 addr_location al;
|
||||
int ret;
|
||||
|
||||
if (perf_event__preprocess_sample(event, machine, &al, sample,
|
||||
rep->annotate_init) < 0) {
|
||||
@ -308,28 +318,25 @@ static int process_sample_event(struct perf_tool *tool,
|
||||
if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
|
||||
return 0;
|
||||
|
||||
if (sort__branch_mode == 1) {
|
||||
if (perf_report__add_branch_hist_entry(tool, &al, sample,
|
||||
evsel, machine)) {
|
||||
if (sort__mode == SORT_MODE__BRANCH) {
|
||||
ret = perf_report__add_branch_hist_entry(tool, &al, sample,
|
||||
evsel, machine);
|
||||
if (ret < 0)
|
||||
pr_debug("problem adding lbr entry, skipping event\n");
|
||||
return -1;
|
||||
}
|
||||
} else if (rep->mem_mode == 1) {
|
||||
if (perf_report__add_mem_hist_entry(tool, &al, sample,
|
||||
evsel, machine, event)) {
|
||||
ret = perf_report__add_mem_hist_entry(tool, &al, sample,
|
||||
evsel, machine, event);
|
||||
if (ret < 0)
|
||||
pr_debug("problem adding mem entry, skipping event\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (al.map != NULL)
|
||||
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");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int process_read_event(struct perf_tool *tool,
|
||||
@ -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 &&
|
||||
!(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
|
||||
ui__error("Selected -b but no branch data. "
|
||||
@ -455,7 +462,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
|
||||
continue;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
@ -574,8 +581,8 @@ static int __cmd_report(struct perf_report *rep)
|
||||
if (use_browser > 0) {
|
||||
if (use_browser == 1) {
|
||||
ret = perf_evlist__tui_browse_hists(session->evlist,
|
||||
help,
|
||||
NULL,
|
||||
help, NULL,
|
||||
rep->min_percent,
|
||||
&session->header.env);
|
||||
/*
|
||||
* Usually "ret" is the last pressed key, and we only
|
||||
@ -586,7 +593,7 @@ static int __cmd_report(struct perf_report *rep)
|
||||
|
||||
} else if (use_browser == 2) {
|
||||
perf_evlist__gtk_browse_hists(session->evlist, help,
|
||||
NULL);
|
||||
NULL, rep->min_percent);
|
||||
}
|
||||
} else
|
||||
perf_evlist__tty_browse_hists(session->evlist, rep, help);
|
||||
@ -691,7 +698,19 @@ static int
|
||||
parse_branch_mode(const struct option *opt __maybe_unused,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -700,6 +719,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
struct perf_session *session;
|
||||
struct stat st;
|
||||
bool has_br_stack = false;
|
||||
int branch_mode = -1;
|
||||
int ret = -1;
|
||||
char callchain_default_opt[] = "fractal,0.5,callee";
|
||||
const char * const report_usage[] = {
|
||||
@ -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"),
|
||||
OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
|
||||
"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),
|
||||
OPT_STRING(0, "objdump", &objdump_path, "path",
|
||||
"objdump binary to use for disassembly and annotations"),
|
||||
OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
|
||||
"Disable symbol demangling"),
|
||||
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()
|
||||
};
|
||||
|
||||
perf_config(perf_report_config, NULL);
|
||||
perf_config(perf_report_config, &report);
|
||||
|
||||
argc = parse_options(argc, argv, options, report_usage, 0);
|
||||
|
||||
@ -846,11 +868,11 @@ repeat:
|
||||
has_br_stack = perf_header__has_feat(&session->header,
|
||||
HEADER_BRANCH_STACK);
|
||||
|
||||
if (sort__branch_mode == -1 && has_br_stack)
|
||||
sort__branch_mode = 1;
|
||||
if (branch_mode == -1 && has_br_stack)
|
||||
sort__mode = SORT_MODE__BRANCH;
|
||||
|
||||
/* sort__branch_mode could be 0 if --no-branch-stack */
|
||||
if (sort__branch_mode == 1) {
|
||||
/* sort__mode could be NORMAL if --no-branch-stack */
|
||||
if (sort__mode == SORT_MODE__BRANCH) {
|
||||
/*
|
||||
* if no sort_order is provided, then specify
|
||||
* branch-mode specific order
|
||||
@ -861,10 +883,12 @@ repeat:
|
||||
|
||||
}
|
||||
if (report.mem_mode) {
|
||||
if (sort__branch_mode == 1) {
|
||||
if (sort__mode == SORT_MODE__BRANCH) {
|
||||
fprintf(stderr, "branch and mem mode incompatible\n");
|
||||
goto error;
|
||||
}
|
||||
sort__mode = SORT_MODE__MEMORY;
|
||||
|
||||
/*
|
||||
* if no sort_order is provided, then specify
|
||||
* branch-mode specific order
|
||||
@ -929,25 +953,7 @@ repeat:
|
||||
report.symbol_filter_str = argv[0];
|
||||
}
|
||||
|
||||
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", 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);
|
||||
}
|
||||
sort__setup_elide(stdout);
|
||||
|
||||
ret = __cmd_report(&report);
|
||||
if (ret == K_SWITCH_INPUT_DATA) {
|
||||
|
@ -70,10 +70,11 @@
|
||||
|
||||
static volatile int done;
|
||||
|
||||
#define HEADER_LINE_NR 5
|
||||
|
||||
static void perf_top__update_print_entries(struct perf_top *top)
|
||||
{
|
||||
if (top->print_entries > 9)
|
||||
top->print_entries -= 9;
|
||||
top->print_entries = top->winsize.ws_row - HEADER_LINE_NR;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -251,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
|
||||
{
|
||||
struct hist_entry *he;
|
||||
|
||||
pthread_mutex_lock(&evsel->hists.lock);
|
||||
he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
|
||||
sample->weight);
|
||||
pthread_mutex_unlock(&evsel->hists.lock);
|
||||
|
||||
if (he == NULL)
|
||||
return NULL;
|
||||
|
||||
@ -290,16 +287,17 @@ static void perf_top__print_sym_table(struct perf_top *top)
|
||||
return;
|
||||
}
|
||||
|
||||
hists__collapse_resort_threaded(&top->sym_evsel->hists);
|
||||
hists__output_resort_threaded(&top->sym_evsel->hists);
|
||||
hists__decay_entries_threaded(&top->sym_evsel->hists,
|
||||
top->hide_user_symbols,
|
||||
top->hide_kernel_symbols);
|
||||
hists__collapse_resort(&top->sym_evsel->hists);
|
||||
hists__output_resort(&top->sym_evsel->hists);
|
||||
hists__decay_entries(&top->sym_evsel->hists,
|
||||
top->hide_user_symbols,
|
||||
top->hide_kernel_symbols);
|
||||
hists__output_recalc_col_len(&top->sym_evsel->hists,
|
||||
top->winsize.ws_row - 3);
|
||||
top->print_entries - printed);
|
||||
putchar('\n');
|
||||
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)
|
||||
@ -477,7 +475,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
|
||||
perf_top__sig_winch(SIGWINCH, NULL, top);
|
||||
sigaction(SIGWINCH, &act, NULL);
|
||||
} else {
|
||||
perf_top__sig_winch(SIGWINCH, NULL, top);
|
||||
signal(SIGWINCH, SIG_DFL);
|
||||
}
|
||||
break;
|
||||
@ -556,11 +553,11 @@ static void perf_top__sort_new_samples(void *arg)
|
||||
if (t->evlist->selected != NULL)
|
||||
t->sym_evsel = t->evlist->selected;
|
||||
|
||||
hists__collapse_resort_threaded(&t->sym_evsel->hists);
|
||||
hists__output_resort_threaded(&t->sym_evsel->hists);
|
||||
hists__decay_entries_threaded(&t->sym_evsel->hists,
|
||||
t->hide_user_symbols,
|
||||
t->hide_kernel_symbols);
|
||||
hists__collapse_resort(&t->sym_evsel->hists);
|
||||
hists__output_resort(&t->sym_evsel->hists);
|
||||
hists__decay_entries(&t->sym_evsel->hists,
|
||||
t->hide_user_symbols,
|
||||
t->hide_kernel_symbols);
|
||||
}
|
||||
|
||||
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)
|
||||
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);
|
||||
|
||||
done = 1;
|
||||
@ -794,7 +791,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
|
||||
return;
|
||||
}
|
||||
|
||||
if (top->sort_has_symbols)
|
||||
if (sort__has_sym)
|
||||
perf_top__record_precise_ip(top, he, evsel->idx, ip);
|
||||
}
|
||||
|
||||
@ -912,9 +909,9 @@ out_err:
|
||||
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) {
|
||||
ui__error("Selected -g but \"sym\" not present in --sort/-s.");
|
||||
return -EINVAL;
|
||||
@ -1025,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int 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 status;
|
||||
@ -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",
|
||||
"Specify disassembler style (e.g. -M intel for intel syntax)"),
|
||||
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()
|
||||
};
|
||||
const char * const top_usage[] = {
|
||||
@ -1133,6 +1142,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (setup_sorting() < 0)
|
||||
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)
|
||||
use_browser = 0;
|
||||
else if (top.use_tui)
|
||||
@ -1200,15 +1212,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (symbol__init() < 0)
|
||||
return -1;
|
||||
|
||||
sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", 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;
|
||||
sort__setup_elide(stdout);
|
||||
|
||||
get_term_dimensions(&top.winsize);
|
||||
if (top.print_entries == 0) {
|
||||
|
477
tools/perf/config/Makefile
Normal file
477
tools/perf/config/Makefile
Normal file
@ -0,0 +1,477 @@
|
||||
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
|
||||
precise_ip=0
|
||||
mmap_data=0
|
||||
sample_id_all=1
|
||||
exclude_host=0
|
||||
exclude_guest=1
|
||||
exclude_host=0|1
|
||||
exclude_guest=0|1
|
||||
exclude_callchain_kernel=0
|
||||
exclude_callchain_user=0
|
||||
wakeup_events=0
|
||||
|
@ -27,8 +27,8 @@ watermark=0
|
||||
precise_ip=0
|
||||
mmap_data=0
|
||||
sample_id_all=0
|
||||
exclude_host=0
|
||||
exclude_guest=1
|
||||
exclude_host=0|1
|
||||
exclude_guest=0|1
|
||||
exclude_callchain_kernel=0
|
||||
exclude_callchain_user=0
|
||||
wakeup_events=0
|
||||
|
@ -4,5 +4,8 @@ args = -d kill >/dev/null 2>&1
|
||||
|
||||
[event:base-record]
|
||||
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
|
||||
|
@ -4,6 +4,12 @@
|
||||
* (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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -3,6 +3,12 @@
|
||||
* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
@ -70,7 +70,7 @@ static struct test {
|
||||
.func = test__attr,
|
||||
},
|
||||
{
|
||||
.desc = "Test matching and linking mutliple hists",
|
||||
.desc = "Test matching and linking multiple hists",
|
||||
.func = test__hists_link,
|
||||
},
|
||||
{
|
||||
|
138
tools/perf/tests/make
Normal file
138
tools/perf/tests/make
Normal file
@ -0,0 +1,138 @@
|
||||
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 {
|
||||
struct map_symbol *selection;
|
||||
int print_seq;
|
||||
bool show_dso;
|
||||
bool has_symbols;
|
||||
float min_pcnt;
|
||||
u64 nr_pcnt_entries;
|
||||
};
|
||||
|
||||
extern void hist_browser__init_hpp(void);
|
||||
@ -309,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
|
||||
"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,
|
||||
struct hist_browser_timer *hbt)
|
||||
{
|
||||
@ -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.nr_entries = browser->hists->nr_entries;
|
||||
if (browser->min_pcnt)
|
||||
browser->b.nr_entries = browser->nr_pcnt_entries;
|
||||
|
||||
hist_browser__refresh_dimensions(browser);
|
||||
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,
|
||||
key = ui_browser__run(&browser->b, delay_secs);
|
||||
|
||||
switch (key) {
|
||||
case K_TIMER:
|
||||
case K_TIMER: {
|
||||
u64 nr_entries;
|
||||
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 !=
|
||||
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,
|
||||
hists__browser_title(browser->hists, title, sizeof(title), ev_name);
|
||||
ui_browser__show_title(&browser->b, title);
|
||||
continue;
|
||||
}
|
||||
case 'D': { /* Debug */
|
||||
static int seq;
|
||||
struct hist_entry *h = rb_entry(browser->b.top,
|
||||
@ -796,10 +811,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
|
||||
|
||||
for (nd = browser->top; nd; nd = rb_next(nd)) {
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (percent < hb->min_pcnt)
|
||||
continue;
|
||||
|
||||
row += hist_browser__show_entry(hb, h, row);
|
||||
if (row == browser->height)
|
||||
break;
|
||||
@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
|
||||
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) {
|
||||
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)
|
||||
return nd;
|
||||
|
||||
@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd)
|
||||
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) {
|
||||
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;
|
||||
|
||||
nd = rb_prev(nd);
|
||||
@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
|
||||
struct hist_entry *h;
|
||||
struct rb_node *nd;
|
||||
bool first = true;
|
||||
struct hist_browser *hb;
|
||||
|
||||
hb = container_of(browser, struct hist_browser, b);
|
||||
|
||||
if (browser->nr_entries == 0)
|
||||
return;
|
||||
@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
|
||||
|
||||
switch (whence) {
|
||||
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;
|
||||
case SEEK_CUR:
|
||||
nd = browser->top;
|
||||
goto do_offset;
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
@ -897,7 +935,8 @@ do_offset:
|
||||
break;
|
||||
}
|
||||
}
|
||||
nd = hists__filter_entries(rb_next(nd));
|
||||
nd = hists__filter_entries(rb_next(nd), hb->hists,
|
||||
hb->min_pcnt);
|
||||
if (nd == NULL)
|
||||
break;
|
||||
--offset;
|
||||
@ -930,7 +969,8 @@ do_offset:
|
||||
}
|
||||
}
|
||||
|
||||
nd = hists__filter_prev_entries(rb_prev(nd));
|
||||
nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
|
||||
hb->min_pcnt);
|
||||
if (nd == NULL)
|
||||
break;
|
||||
++offset;
|
||||
@ -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)
|
||||
{
|
||||
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;
|
||||
|
||||
while (nd) {
|
||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||
|
||||
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;
|
||||
@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
|
||||
browser->b.refresh = hist_browser__refresh;
|
||||
browser->b.seek = ui_browser__hists_seek;
|
||||
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;
|
||||
@ -1329,11 +1368,25 @@ close_file_and_continue:
|
||||
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,
|
||||
const char *helpline, const char *ev_name,
|
||||
bool left_exits,
|
||||
struct hist_browser_timer *hbt,
|
||||
float min_pcnt,
|
||||
struct perf_session_env *env)
|
||||
{
|
||||
struct hists *hists = &evsel->hists;
|
||||
@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
if (browser == NULL)
|
||||
return -1;
|
||||
|
||||
if (min_pcnt) {
|
||||
browser->min_pcnt = min_pcnt;
|
||||
hist_browser__update_pcnt_entries(browser);
|
||||
}
|
||||
|
||||
fstack = pstack__new(2);
|
||||
if (fstack == NULL)
|
||||
goto out;
|
||||
@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
*/
|
||||
goto out_free_stack;
|
||||
case 'a':
|
||||
if (!browser->has_symbols) {
|
||||
if (!sort__has_sym) {
|
||||
ui_browser__warning(&browser->b, delay_secs * 2,
|
||||
"Annotation is only available for symbolic views, "
|
||||
"include \"sym*\" in --sort to use it.");
|
||||
@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!browser->has_symbols)
|
||||
if (!sort__has_sym)
|
||||
goto add_exit_option;
|
||||
|
||||
if (sort__branch_mode == 1) {
|
||||
if (sort__mode == SORT_MODE__BRANCH) {
|
||||
bi = browser->he_selection->branch_info;
|
||||
if (browser->selection != NULL &&
|
||||
bi &&
|
||||
@ -1689,6 +1747,7 @@ struct perf_evsel_menu {
|
||||
struct ui_browser b;
|
||||
struct perf_evsel *selection;
|
||||
bool lost_events, lost_events_warned;
|
||||
float min_pcnt;
|
||||
struct perf_session_env *env;
|
||||
};
|
||||
|
||||
@ -1782,6 +1841,7 @@ browse_hists:
|
||||
ev_name = perf_evsel__name(pos);
|
||||
key = perf_evsel__hists_browse(pos, nr_events, help,
|
||||
ev_name, true, hbt,
|
||||
menu->min_pcnt,
|
||||
menu->env);
|
||||
ui_browser__show_title(&menu->b, title);
|
||||
switch (key) {
|
||||
@ -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,
|
||||
int nr_entries, const char *help,
|
||||
struct hist_browser_timer *hbt,
|
||||
float min_pcnt,
|
||||
struct perf_session_env *env)
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
|
||||
.nr_entries = nr_entries,
|
||||
.priv = evlist,
|
||||
},
|
||||
.min_pcnt = min_pcnt,
|
||||
.env = env,
|
||||
};
|
||||
|
||||
@ -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,
|
||||
struct hist_browser_timer *hbt,
|
||||
float min_pcnt,
|
||||
struct perf_session_env *env)
|
||||
{
|
||||
int nr_entries = evlist->nr_entries;
|
||||
@ -1885,7 +1948,8 @@ single_entry:
|
||||
const char *ev_name = perf_evsel__name(first);
|
||||
|
||||
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) {
|
||||
@ -1901,5 +1965,5 @@ single_entry:
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
GType col_types[MAX_COLUMNS];
|
||||
@ -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)) {
|
||||
struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
|
||||
GtkTreeIter iter;
|
||||
float percent = h->stat.period * 100.0 /
|
||||
hists->stats.total_period;
|
||||
|
||||
if (h->filtered)
|
||||
continue;
|
||||
|
||||
if (percent < min_pcnt)
|
||||
continue;
|
||||
|
||||
gtk_list_store_append(store, &iter);
|
||||
|
||||
col_idx = 0;
|
||||
@ -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,
|
||||
const char *help,
|
||||
struct hist_browser_timer *hbt __maybe_unused)
|
||||
struct hist_browser_timer *hbt __maybe_unused,
|
||||
float min_pcnt)
|
||||
{
|
||||
struct perf_evsel *pos;
|
||||
GtkWidget *vbox;
|
||||
@ -286,7 +293,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
|
||||
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);
|
||||
|
||||
|
@ -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,
|
||||
int max_cols, FILE *fp)
|
||||
int max_cols, float min_pcnt, FILE *fp)
|
||||
{
|
||||
struct perf_hpp_fmt *fmt;
|
||||
struct sort_entry *se;
|
||||
@ -440,10 +440,15 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
|
||||
print_entries:
|
||||
for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (percent < min_pcnt)
|
||||
continue;
|
||||
|
||||
ret += hist_entry__fprintf(h, max_cols, hists, fp);
|
||||
|
||||
if (max_rows && ++nr_rows >= max_rows)
|
||||
|
@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
|
||||
if (pipe_output)
|
||||
dup2(2, 1);
|
||||
|
||||
signal(SIGTERM, SIG_DFL);
|
||||
|
||||
close(child_ready_pipe[0]);
|
||||
close(go_pipe[1]);
|
||||
fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
|
||||
|
@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel,
|
||||
switch (err) {
|
||||
case EPERM:
|
||||
case EACCES:
|
||||
return scnprintf(msg, size, "%s",
|
||||
return scnprintf(msg, size,
|
||||
"You may not have permission to collect %sstats.\n"
|
||||
"Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
|
||||
" -1 - Not paranoid at all\n"
|
||||
|
@ -2391,7 +2391,6 @@ out_err_write:
|
||||
}
|
||||
lseek(fd, header->data_offset + header->data_size, SEEK_SET);
|
||||
|
||||
header->frozen = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2871,7 +2870,6 @@ int perf_session__read_header(struct perf_session *session, int fd)
|
||||
session->pevent))
|
||||
goto out_delete_evlist;
|
||||
|
||||
header->frozen = 1;
|
||||
return 0;
|
||||
out_errno:
|
||||
return -errno;
|
||||
|
@ -84,7 +84,6 @@ struct perf_session_env {
|
||||
};
|
||||
|
||||
struct perf_header {
|
||||
int frozen;
|
||||
bool needs_swap;
|
||||
s64 attr_offset;
|
||||
u64 data_offset;
|
||||
|
@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
|
||||
int symlen;
|
||||
u16 len;
|
||||
|
||||
if (h->ms.sym)
|
||||
hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4);
|
||||
else {
|
||||
/*
|
||||
* +4 accounts for '[x] ' priv level info
|
||||
* +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;
|
||||
hists__new_col_len(hists, HISTC_SYMBOL, symlen);
|
||||
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)
|
||||
hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
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)
|
||||
|
||||
if (h->branch_info->to.sym) {
|
||||
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);
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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) {
|
||||
symlen = (int)h->mem_info->daddr.sym->namelen + 4
|
||||
+ unresolved_col_width + 2;
|
||||
@ -236,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
|
||||
return he->stat.period == 0;
|
||||
}
|
||||
|
||||
static void __hists__decay_entries(struct hists *hists, bool zap_user,
|
||||
bool zap_kernel, bool threaded)
|
||||
void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
|
||||
{
|
||||
struct rb_node *next = rb_first(&hists->entries);
|
||||
struct hist_entry *n;
|
||||
@ -256,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
|
||||
!n->used) {
|
||||
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);
|
||||
|
||||
hist_entry__free(n);
|
||||
@ -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
|
||||
*/
|
||||
@ -292,6 +284,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
|
||||
he->ms.map->referenced = true;
|
||||
|
||||
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)
|
||||
he->branch_info->from.map->referenced = true;
|
||||
if (he->branch_info->to.map)
|
||||
@ -341,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
|
||||
struct hist_entry *he;
|
||||
int cmp;
|
||||
|
||||
pthread_mutex_lock(&hists->lock);
|
||||
|
||||
p = &hists->entries_in->rb_node;
|
||||
|
||||
while (*p != NULL) {
|
||||
@ -360,6 +364,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
|
||||
if (!cmp) {
|
||||
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
|
||||
* become out-of-date due to an exec() or
|
||||
* similar, update it. Otherwise we will
|
||||
@ -382,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
|
||||
|
||||
he = hist_entry__new(entry);
|
||||
if (!he)
|
||||
goto out_unlock;
|
||||
return NULL;
|
||||
|
||||
rb_link_node(&he->rb_node_in, parent, p);
|
||||
rb_insert_color(&he->rb_node_in, hists->entries_in);
|
||||
out:
|
||||
hist_entry__add_cpumode_period(he, al->cpumode, period);
|
||||
out_unlock:
|
||||
pthread_mutex_unlock(&hists->lock);
|
||||
return he;
|
||||
}
|
||||
|
||||
@ -589,13 +597,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *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_node *next;
|
||||
struct hist_entry *n;
|
||||
|
||||
if (!sort__need_collapse && !threaded)
|
||||
if (!sort__need_collapse)
|
||||
return;
|
||||
|
||||
root = hists__get_rotate_entries_in(hists);
|
||||
@ -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.
|
||||
*/
|
||||
@ -713,7 +711,7 @@ static void __hists__insert_output_entry(struct rb_root *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_node *next;
|
||||
@ -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);
|
||||
|
||||
if (sort__need_collapse || threaded)
|
||||
if (sort__need_collapse)
|
||||
root = &hists->entries_collapsed;
|
||||
else
|
||||
root = hists->entries_in;
|
||||
@ -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,
|
||||
enum hist_filter filter)
|
||||
{
|
||||
|
@ -43,12 +43,12 @@ enum hist_column {
|
||||
HISTC_COMM,
|
||||
HISTC_PARENT,
|
||||
HISTC_CPU,
|
||||
HISTC_SRCLINE,
|
||||
HISTC_MISPREDICT,
|
||||
HISTC_SYMBOL_FROM,
|
||||
HISTC_SYMBOL_TO,
|
||||
HISTC_DSO_FROM,
|
||||
HISTC_DSO_TO,
|
||||
HISTC_SRCLINE,
|
||||
HISTC_LOCAL_WEIGHT,
|
||||
HISTC_GLOBAL_WEIGHT,
|
||||
HISTC_MEM_DADDR_SYMBOL,
|
||||
@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
|
||||
u64 weight);
|
||||
|
||||
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_threaded(struct hists *hists);
|
||||
|
||||
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__inc_nr_entries(struct hists *hists, struct hist_entry *h);
|
||||
@ -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 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__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,
|
||||
|
||||
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
|
||||
struct hist_browser_timer *hbt,
|
||||
float min_pcnt,
|
||||
struct perf_session_env *env);
|
||||
int script_browse(const char *script_opt);
|
||||
#else
|
||||
@ -206,6 +203,7 @@ static inline
|
||||
int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
|
||||
const char *help __maybe_unused,
|
||||
struct hist_browser_timer *hbt __maybe_unused,
|
||||
float min_pcnt __maybe_unused,
|
||||
struct perf_session_env *env __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
@ -233,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused)
|
||||
|
||||
#ifdef GTK2_SUPPORT
|
||||
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
|
||||
static inline
|
||||
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __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;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ const char *map_type__name[MAP__NR_TYPES] = {
|
||||
static inline int is_anon_memory(const char *filename)
|
||||
{
|
||||
return !strcmp(filename, "//anon") ||
|
||||
!strcmp(filename, "/dev/zero (deleted)") ||
|
||||
!strcmp(filename, "/anon_hugepage (deleted)");
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,6 @@ struct perf_session {
|
||||
int fd;
|
||||
bool fd_pipe;
|
||||
bool repipe;
|
||||
int cwdlen;
|
||||
char *cwd;
|
||||
struct ordered_samples ordered_samples;
|
||||
char filename[1];
|
||||
|
@ -18,8 +18,9 @@ class install_lib(_install_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_tmp = getenv('PYTHON_EXTBUILD_TMP')
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "sort.h"
|
||||
#include "hist.h"
|
||||
#include "symbol.h"
|
||||
|
||||
regex_t parent_regex;
|
||||
const char default_parent_pattern[] = "^sys_|^do_page_fault";
|
||||
@ -9,7 +10,7 @@ const char *sort_order = default_sort_order;
|
||||
int sort__need_collapse = 0;
|
||||
int sort__has_parent = 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;
|
||||
|
||||
@ -194,7 +195,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
|
||||
if (verbose) {
|
||||
char o = map ? dso__symtab_origin(map->dso) : '!';
|
||||
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);
|
||||
@ -871,14 +872,6 @@ static struct sort_dimension common_sort_dimensions[] = {
|
||||
DIM(SORT_PARENT, "parent", sort_parent),
|
||||
DIM(SORT_CPU, "cpu", sort_cpu),
|
||||
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
|
||||
@ -895,6 +888,36 @@ static struct sort_dimension bstack_sort_dimensions[] = {
|
||||
|
||||
#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)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -915,25 +938,11 @@ int sort_dimension__add(const char *tok)
|
||||
return -EINVAL;
|
||||
}
|
||||
sort__has_parent = 1;
|
||||
} else if (sd->entry == &sort_sym ||
|
||||
sd->entry == &sort_sym_from ||
|
||||
sd->entry == &sort_sym_to ||
|
||||
sd->entry == &sort_mem_daddr_sym) {
|
||||
} else if (sd->entry == &sort_sym) {
|
||||
sort__has_sym = 1;
|
||||
}
|
||||
|
||||
if (sd->taken)
|
||||
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;
|
||||
|
||||
__sort_dimension__add(sd, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -943,24 +952,29 @@ int sort_dimension__add(const char *tok)
|
||||
if (strncasecmp(tok, sd->name, strlen(tok)))
|
||||
continue;
|
||||
|
||||
if (sort__branch_mode != 1)
|
||||
if (sort__mode != SORT_MODE__BRANCH)
|
||||
return -EINVAL;
|
||||
|
||||
if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
|
||||
sort__has_sym = 1;
|
||||
|
||||
if (sd->taken)
|
||||
return 0;
|
||||
__sort_dimension__add(sd, i + __SORT_BRANCH_STACK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sd->entry->se_collapse)
|
||||
sort__need_collapse = 1;
|
||||
for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
|
||||
struct sort_dimension *sd = &memory_sort_dimensions[i];
|
||||
|
||||
if (list_empty(&hist_entry__sort_list))
|
||||
sort__first_dimension = i + __SORT_BRANCH_STACK;
|
||||
if (strncasecmp(tok, sd->name, strlen(tok)))
|
||||
continue;
|
||||
|
||||
list_add_tail(&sd->entry->list, &hist_entry__sort_list);
|
||||
sd->taken = 1;
|
||||
if (sort__mode != SORT_MODE__MEMORY)
|
||||
return -EINVAL;
|
||||
|
||||
if (sd->entry == &sort_mem_daddr_sym)
|
||||
sort__has_sym = 1;
|
||||
|
||||
__sort_dimension__add(sd, i + __SORT_MEMORY_MODE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -993,8 +1007,9 @@ int setup_sorting(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
|
||||
const char *list_name, FILE *fp)
|
||||
static void sort_entry__setup_elide(struct sort_entry *self,
|
||||
struct strlist *list,
|
||||
const char *list_name, FILE *fp)
|
||||
{
|
||||
if (list && strlist__nr_entries(list) == 1) {
|
||||
if (fp != NULL)
|
||||
@ -1003,3 +1018,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
|
||||
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[];
|
||||
extern int sort__need_collapse;
|
||||
extern int sort__has_parent;
|
||||
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_dso;
|
||||
extern struct sort_entry sort_sym;
|
||||
@ -117,12 +117,18 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void hist_entry__add_pair(struct hist_entry *he,
|
||||
struct hist_entry *pair)
|
||||
static inline void hist_entry__add_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 {
|
||||
/* common sort keys */
|
||||
SORT_PID,
|
||||
@ -132,14 +138,6 @@ enum sort_type {
|
||||
SORT_PARENT,
|
||||
SORT_CPU,
|
||||
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 */
|
||||
__SORT_BRANCH_STACK,
|
||||
@ -148,6 +146,17 @@ enum sort_type {
|
||||
SORT_SYM_FROM,
|
||||
SORT_SYM_TO,
|
||||
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;
|
||||
|
||||
int setup_sorting(void);
|
||||
extern int sort_dimension__add(const char *);
|
||||
void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
|
||||
const char *list_name, FILE *fp);
|
||||
void sort__setup_elide(FILE *fp);
|
||||
|
||||
#endif /* __PERF_SORT_H */
|
||||
|
@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats)
|
||||
{
|
||||
double variance, variance_mean;
|
||||
|
||||
if (!stats->n)
|
||||
if (stats->n < 2)
|
||||
return 0.0;
|
||||
|
||||
variance = stats->M2 / (stats->n - 1);
|
||||
|
@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid)
|
||||
if (self != NULL) {
|
||||
map_groups__init(&self->mg);
|
||||
self->pid = pid;
|
||||
self->ppid = -1;
|
||||
self->comm = malloc(32);
|
||||
if (self->comm)
|
||||
snprintf(self->comm, 32, ":%d", self->pid);
|
||||
@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent)
|
||||
for (i = 0; i < MAP__NR_TYPES; ++i)
|
||||
if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
self->ppid = parent->pid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ struct thread {
|
||||
};
|
||||
struct map_groups mg;
|
||||
pid_t pid;
|
||||
pid_t ppid;
|
||||
char shortname[3];
|
||||
bool comm_set;
|
||||
char *comm;
|
||||
|
@ -23,20 +23,31 @@
|
||||
|
||||
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 ksamples_per_sec = top->kernel_samples / top->delay_secs;
|
||||
float esamples_percent = (100.0 * top->exact_samples) / top->samples;
|
||||
float samples_per_sec;
|
||||
float ksamples_per_sec;
|
||||
float esamples_percent;
|
||||
struct perf_record_opts *opts = &top->record_opts;
|
||||
struct perf_target *target = &opts->target;
|
||||
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) {
|
||||
float ksamples_percent = 0.0;
|
||||
|
||||
if (samples_per_sec)
|
||||
ksamples_percent = (100.0 * ksamples_per_sec) /
|
||||
samples_per_sec;
|
||||
ret = SNPRINTF(bf, size,
|
||||
" PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
|
||||
" exact: %4.1f%% [", samples_per_sec,
|
||||
100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) /
|
||||
samples_per_sec)),
|
||||
esamples_percent);
|
||||
ksamples_percent, esamples_percent);
|
||||
} else {
|
||||
float us_samples_per_sec = top->us_samples / top->delay_secs;
|
||||
float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
|
||||
|
@ -26,7 +26,6 @@ struct perf_top {
|
||||
int print_entries, count_filter, delay_secs;
|
||||
bool hide_kernel_symbols, hide_user_symbols, zero;
|
||||
bool use_tui, use_stdio;
|
||||
bool sort_has_symbols;
|
||||
bool kptr_restrict_warned;
|
||||
bool vmlinux_warned;
|
||||
bool dump_symtab;
|
||||
@ -37,6 +36,7 @@ struct perf_top {
|
||||
int realtime_prio;
|
||||
int sym_pcnt_filter;
|
||||
const char *sym_filter;
|
||||
float min_percent;
|
||||
};
|
||||
|
||||
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];
|
||||
#define isalpha(x) sane_istest(x,GIT_ALPHA)
|
||||
#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
|
||||
#define isprint(x) sane_istest(x,GIT_PRINT)
|
||||
#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20))
|
||||
#define isupper(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) && !(x & 0x20))
|
||||
#define tolower(x) sane_case((unsigned char)(x), 0x20)
|
||||
#define toupper(x) sane_case((unsigned char)(x), 0)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user