Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6fcdb1ed authored by Ingo Molnar's avatar Ingo Molnar
Browse files

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

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

 into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

 * Handle PERF_RECORD_EXIT events in sched and annotate.

 * struct machine refactorings to help in top and trace.

 * Add on_exit implementation for systems without one, e.g. Android, from
   Bernhard Rosenkraenzer.

 * Only process events for vcpus of interest, helps handling large number
   of events, from David Ahern.

 * Cross compilation fixes for Android, from Irina Tirdea.

 * Add documentation on compiling for Android, from Irina Tirdea.

 * perf diff improvements from Jiri Olsa.

 * Target (task/user/cpu/syswide) handling improvements, from Namhyung Kim.

 * Add support in 'trace' for tracing workload given by command line, from
   Namhyung Kim.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 1d787d37 7747e2f4
Loading
Loading
Loading
Loading
+75 −0
Original line number Diff line number Diff line
How to compile perf for Android
=========================================

I. Set the Android NDK environment
------------------------------------------------

(a). Use the Android NDK
------------------------------------------------
1. You need to download and install the Android Native Development Kit (NDK).
Set the NDK variable to point to the path where you installed the NDK:
  export NDK=/path/to/android-ndk

2. Set cross-compiling environment variables for NDK toolchain and sysroot.
For arm:
  export NDK_TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
  export NDK_SYSROOT=${NDK}/platforms/android-9/arch-arm
For x86:
  export NDK_TOOLCHAIN=${NDK}/toolchains/x86-4.6/prebuilt/linux-x86/bin/i686-linux-android-
  export NDK_SYSROOT=${NDK}/platforms/android-9/arch-x86

This method is not working for Android NDK versions up to Revision 8b.
perf uses some bionic enhancements that are not included in these NDK versions.
You can use method (b) described below instead.

(b). Use the Android source tree
-----------------------------------------------
1. Download the master branch of the Android source tree.
Set the environment for the target you want using:
  source build/envsetup.sh
  lunch

2. Build your own NDK sysroot to contain latest bionic changes and set the
NDK sysroot environment variable.
  cd ${ANDROID_BUILD_TOP}/ndk
For arm:
  ./build/tools/build-ndk-sysroot.sh --abi=arm
  export NDK_SYSROOT=${ANDROID_BUILD_TOP}/ndk/build/platforms/android-3/arch-arm
For x86:
  ./build/tools/build-ndk-sysroot.sh --abi=x86
  export NDK_SYSROOT=${ANDROID_BUILD_TOP}/ndk/build/platforms/android-3/arch-x86

3. Set the NDK toolchain environment variable.
For arm:
  export NDK_TOOLCHAIN=${ANDROID_TOOLCHAIN}/arm-linux-androideabi-
For x86:
  export NDK_TOOLCHAIN=${ANDROID_TOOLCHAIN}/i686-linux-android-

II. Compile perf for Android
------------------------------------------------
You need to run make with the NDK toolchain and sysroot defined above:
  make CROSS_COMPILE=${NDK_TOOLCHAIN} CFLAGS="--sysroot=${NDK_SYSROOT}"

III. Install perf
-----------------------------------------------
You need to connect to your Android device/emulator using adb.
Install perf using:
  adb push perf /data/perf

If you also want to use perf-archive you need busybox tools for Android.
For installing perf-archive, you first need to replace #!/bin/bash with #!/system/bin/sh:
  sed 's/#!\/bin\/bash/#!\/system\/bin\/sh/g' perf-archive >> /tmp/perf-archive
  chmod +x /tmp/perf-archive
  adb push /tmp/perf-archive /data/perf-archive

IV. Environment settings for running perf
------------------------------------------------
Some perf features need environment variables to run properly.
You need to set these before running perf on the target:
  adb shell
  # PERF_PAGER=cat

IV. Run perf
------------------------------------------------
Run perf on your device/emulator to which you previously connected using adb:
  # ./data/perf
+60 −0
Original line number Diff line number Diff line
@@ -72,6 +72,66 @@ OPTIONS
--symfs=<directory>::
        Look for files with symbols relative to this directory.

-b::
--baseline-only::
        Show only items with match in baseline.

-c::
--compute::
        Differential computation selection - delta,ratio,wdiff (default is delta).
        If '+' is specified as a first character, the output is sorted based
        on the computation results.
        See COMPARISON METHODS section for more info.

-p::
--period::
        Show period values for both compared hist entries.

-F::
--formula::
        Show formula for given computation.

COMPARISON METHODS
------------------
delta
~~~~~
If specified the 'Delta' column is displayed with value 'd' computed as:

  d = A->period_percent - B->period_percent

with:
  - A/B being matching hist entry from first/second file specified
    (or perf.data/perf.data.old) respectively.

  - period_percent being the % of the hist entry period value within
    single data file

ratio
~~~~~
If specified the 'Ratio' column is displayed with value 'r' computed as:

  r = A->period / B->period

with:
  - A/B being matching hist entry from first/second file specified
    (or perf.data/perf.data.old) respectively.

  - period being the hist entry period value

wdiff
~~~~~
If specified the 'Weighted diff' column is displayed with value 'd' computed as:

   d = B->period * WEIGHT-A - A->period * WEIGHT-B

  - A/B being matching hist entry from first/second file specified
    (or perf.data/perf.data.old) respectively.

  - period being the hist entry period value

  - WEIGHT-A/WEIGHT-B being user suplied weights in the the '-c' option
    behind ':' separator like '-c wdiff:1,2'.

SEE ALSO
--------
linkperf:perf-record[1]
+56 −60
Original line number Diff line number Diff line
@@ -45,6 +45,8 @@ include config/utilities.mak
#
# Define NO_LIBUNWIND if you do not want libunwind dependency for dwarf
# backtrace post unwind.
#
# Define NO_BACKTRACE if you do not want stack backtrace debug feature

$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
	@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
@@ -153,15 +155,15 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__

-include config/feature-tests.mak

ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y)
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all),y)
	CFLAGS := $(CFLAGS) -fstack-protector-all
endif

ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wstack-protector),y)
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector),y)
       CFLAGS := $(CFLAGS) -Wstack-protector
endif

ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wvolatile-register-var),y)
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var),y)
       CFLAGS := $(CFLAGS) -Wvolatile-register-var
endif

@@ -170,6 +172,13 @@ endif
BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)util -I$(TRACE_EVENT_DIR) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
BASIC_LDFLAGS =

ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS)),y)
	BIONIC := 1
	EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
	EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
	BASIC_CFLAGS += -I.
endif

# Guard against environment variables
BUILTIN_OBJS =
LIB_H =
@@ -185,7 +194,7 @@ strip-libs = $(filter-out -l%,$(1))
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py

$(OUTPUT)python/perf.so: $(PYRF_OBJS) $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
	$(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
	  --quiet build_ext; \
	mkdir -p $(OUTPUT)python && \
@@ -298,6 +307,7 @@ LIB_H += util/evlist.h
LIB_H += util/exec_cmd.h
LIB_H += util/types.h
LIB_H += util/levenshtein.h
LIB_H += util/machine.h
LIB_H += util/map.h
LIB_H += util/parse-options.h
LIB_H += util/parse-events.h
@@ -381,6 +391,7 @@ LIB_OBJS += $(OUTPUT)util/header.o
LIB_OBJS += $(OUTPUT)util/callchain.o
LIB_OBJS += $(OUTPUT)util/values.o
LIB_OBJS += $(OUTPUT)util/debug.o
LIB_OBJS += $(OUTPUT)util/machine.o
LIB_OBJS += $(OUTPUT)util/map.o
LIB_OBJS += $(OUTPUT)util/pstack.o
LIB_OBJS += $(OUTPUT)util/session.o
@@ -446,20 +457,6 @@ BUILTIN_OBJS += $(OUTPUT)builtin-inject.o

PERFLIBS = $(LIB_FILE) $(LIBTRACEEVENT)

# Files needed for the python binding, perf.so
# pyrf is just an internal name needed for all those wrappers.
# This has to be in sync with what is in the 'sources' variable in
# tools/perf/util/setup.py

PYRF_OBJS += $(OUTPUT)util/cpumap.o
PYRF_OBJS += $(OUTPUT)util/ctype.o
PYRF_OBJS += $(OUTPUT)util/evlist.o
PYRF_OBJS += $(OUTPUT)util/evsel.o
PYRF_OBJS += $(OUTPUT)util/python.o
PYRF_OBJS += $(OUTPUT)util/thread_map.o
PYRF_OBJS += $(OUTPUT)util/util.o
PYRF_OBJS += $(OUTPUT)util/xyarray.o

#
# Platform specific tweaks
#
@@ -479,14 +476,26 @@ else
FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
	FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
	ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y)
		msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
	else
	ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y)
		LIBC_SUPPORT := 1
	endif
	ifeq ($(BIONIC),1)
		LIBC_SUPPORT := 1
	endif
	ifeq ($(LIBC_SUPPORT),1)
		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
endif
else
	FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
	ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),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_LIBUNWIND
@@ -511,8 +520,6 @@ ifneq ($(OUTPUT),)
endif

ifdef NO_LIBELF
BASIC_CFLAGS += -DNO_LIBELF_SUPPORT

EXTLIBS := $(filter-out -lelf,$(EXTLIBS))

# Remove ELF/DWARF dependent codes
@@ -527,17 +534,12 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
LIB_OBJS += $(OUTPUT)util/symbol-minimal.o

else # NO_LIBELF
BASIC_CFLAGS += -DLIBELF_SUPPORT

ifneq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
	BASIC_CFLAGS += -DLIBELF_NO_MMAP
ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
	BASIC_CFLAGS += -DLIBELF_MMAP
endif

FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),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

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);
@@ -550,38 +552,33 @@ endif # PERF_HAVE_DWARF_REGS
endif # NO_DWARF
endif # NO_LIBELF

ifdef NO_LIBUNWIND
	BASIC_CFLAGS += -DNO_LIBUNWIND_SUPPORT
else
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
endif

ifdef NO_LIBAUDIT
	BASIC_CFLAGS += -DNO_LIBAUDIT_SUPPORT
else
ifndef NO_LIBAUDIT
	FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit
	ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT)),y)
		msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
		BASIC_CFLAGS += -DNO_LIBAUDIT_SUPPORT
	else
		BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
		BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
		EXTLIBS += -laudit
	endif
endif

ifdef NO_NEWT
	BASIC_CFLAGS += -DNO_NEWT_SUPPORT
else
ifndef NO_NEWT
	FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
	ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y)
		msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
		BASIC_CFLAGS += -DNO_NEWT_SUPPORT
	else
		# Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
		BASIC_CFLAGS += -I/usr/include/slang
		BASIC_CFLAGS += -DNEWT_SUPPORT
		EXTLIBS += -lnewt -lslang
		LIB_OBJS += $(OUTPUT)ui/setup.o
		LIB_OBJS += $(OUTPUT)ui/browser.o
@@ -603,17 +600,15 @@ else
	endif
endif

ifdef NO_GTK2
	BASIC_CFLAGS += -DNO_GTK2_SUPPORT
else
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)),y)
		msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
		BASIC_CFLAGS += -DNO_GTK2_SUPPORT
	else
		ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2)),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
@@ -621,7 +616,7 @@ else
		LIB_OBJS += $(OUTPUT)ui/gtk/util.o
		LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
		# Make sure that it'd be included only once.
		ifneq ($(findstring -DNO_NEWT_SUPPORT,$(BASIC_CFLAGS)),)
		ifeq ($(findstring -DNEWT_SUPPORT,$(BASIC_CFLAGS)),)
			LIB_OBJS += $(OUTPUT)ui/setup.o
			LIB_OBJS += $(OUTPUT)ui/util.o
		endif
@@ -762,23 +757,24 @@ ifeq ($(NO_PERF_REGS),0)
	ifeq ($(ARCH),x86)
		LIB_H += arch/x86/include/perf_regs.h
	endif
else
	BASIC_CFLAGS += -DNO_PERF_REGS
	BASIC_CFLAGS += -DHAVE_PERF_REGS
endif

ifdef NO_STRLCPY
	BASIC_CFLAGS += -DNO_STRLCPY
else
	ifneq ($(call try-cc,$(SOURCE_STRLCPY),),y)
		BASIC_CFLAGS += -DNO_STRLCPY
ifndef NO_STRLCPY
	ifeq ($(call try-cc,$(SOURCE_STRLCPY),),y)
		BASIC_CFLAGS += -DHAVE_STRLCPY
	endif
endif

ifdef NO_BACKTRACE
       BASIC_CFLAGS += -DNO_BACKTRACE
else
       ifneq ($(call try-cc,$(SOURCE_BACKTRACE),),y)
               BASIC_CFLAGS += -DNO_BACKTRACE
ifndef NO_ON_EXIT
	ifeq ($(call try-cc,$(SOURCE_ON_EXIT),),y)
		BASIC_CFLAGS += -DHAVE_ON_EXIT
	endif
endif

ifndef NO_BACKTRACE
       ifeq ($(call try-cc,$(SOURCE_BACKTRACE),),y)
               BASIC_CFLAGS += -DBACKTRACE_SUPPORT
       endif
endif

+43 −7
Original line number Diff line number Diff line
# perf completion

function_exists()
{
	declare -F $1 > /dev/null
	return $?
}

function_exists __ltrim_colon_completions ||
__ltrim_colon_completions()
{
	if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
		# Remove colon-word prefix from COMPREPLY items
		local colon_word=${1%${1##*:}}
		local i=${#COMPREPLY[*]}
		while [[ $((--i)) -ge 0 ]]; do
			COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
		done
	fi
}

have perf &&
_perf()
{
	local cur cmd
	local cur prev cmd

	COMPREPLY=()
	_get_comp_words_by_ref cur prev
	if function_exists _get_comp_words_by_ref; then
		_get_comp_words_by_ref -n : cur prev
	else
		cur=$(_get_cword :)
		prev=${COMP_WORDS[COMP_CWORD-1]}
	fi

	cmd=${COMP_WORDS[0]}

	# List perf subcommands
	# List perf subcommands or long options
	if [ $COMP_CWORD -eq 1 ]; then
		if [[ $cur == --* ]]; then
			COMPREPLY=( $( compgen -W '--help --version \
			--exec-path --html-path --paginate --no-pager \
			--perf-dir --work-tree --debugfs-dir' -- "$cur" ) )
		else
			cmds=$($cmd --list-cmds)
			COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
		fi
	# List possible events for -e option
	elif [[ $prev == "-e" && "${COMP_WORDS[1]}" == @(record|stat|top) ]]; then
		cmds=$($cmd list --raw-dump)
		COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
		evts=$($cmd list --raw-dump)
		COMPREPLY=( $( compgen -W '$evts' -- "$cur" ) )
		__ltrim_colon_completions $cur
	# List long option names
	elif [[ $cur == --* ]];  then
		subcmd=${COMP_WORDS[1]}
		opts=$($cmd $subcmd --list-opts)
		COMPREPLY=( $( compgen -W '$opts' -- "$cur" ) )
	# Fall down to list regular files
	else
		_filedir
+2 −1
Original line number Diff line number Diff line
@@ -246,7 +246,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
			.sample	= process_sample_event,
			.mmap	= perf_event__process_mmap,
			.comm	= perf_event__process_comm,
			.fork	= perf_event__process_task,
			.exit	= perf_event__process_exit,
			.fork	= perf_event__process_fork,
			.ordered_samples = true,
			.ordering_requires_timestamps = true,
		},
Loading