mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 14:36:46 +07:00
perf/core improvements and fixes
. kcore annotation improvements, including build-id cache support, multi map 'call' instruction navigation fixes, kcore address validation, objdump workarounds. From Adrian Hunter. . 'trace' beautifiers for lots of syscall arguments. . More compact 'trace' output by suppressing zeroed args. . Show thread COMM by default in 'trace'. . Show path associated with fd in live sessions, using a 'vfs_getname' 'perf probe' created dynamic tracepoint or by looking at /proc/pid/fd. . Memory and mmap leak fixes from Chenggang Qin. . Add option to show full timestamp in 'trace', from David Ahern. . Add 'record' command in 'trace', to record raw_syscalls:*, from David Ahern. . Add summary option to dump syscall statistics in 'trace', from David Ahern. . Fix comm resolution in 'trace' when reading events from file, from David Ahern. . Improved messages when doing profiling in all or a subset of CPUs using a workload as the session delimitator, as in: 'perf stat --cpu 0,2 sleep 10s' . Add units to nanosec-based counters in 'perf stat', from David Ahern. . Assorted build fixes for from David Ahern and Jiri Olsa. . 'perf lock' fixes and cleanups, from Davidlohr Bueso. . Memory leak fixes in 'perf test', from Felipe Pena. . Build system super speedups, from Ingo Molnar. . Fix mmap_read event overflow, from Jiri Olsa. . Code cleanups from Jiri Olsa. . Allow specifying B/K/M/G unit to the --mmap-pages arguments, from Jiri Olsa. . Separate the GTK support in a separate libperf-gtk.so DSO, that is only loaded when --gtk is specified, from Namhyung Kim. . Fixes for some memory leaks, from Namhyumg Kim. . Fix srcline sort key behavior, from Namhyung Kim. . Fix failing assertions in numa bench, from Petr Holasek. . perf bash completion fixes and improvements from Ramkumar Ramachandra. . Improve error messages in 'trace', providing hints about system configuration steps needed for using it, from Ramkumar Ramachandra. . Remove bogus info when using 'perf stat' -e cycles/instructions, from Ramkumar Ramachandra . . Support for Openembedded/Yocto -dbg packages, from Ricardo Ribalda Delgado. . Implement addr2line directly using libbfd, from Roberto Vitillo. . Add new option --ignore-vmlinux for perf top, from Willy Tarreau. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSXEszAAoJENZQFvNTUqpAYIEP+wV2G7attDjTKlew5U1FYepp pdrc+y0mJN/MZSYSYnanQ73m2R3d+S1GZV08l05isxSoEC75FHvb5uBaOEKDTyzv uJNubUAnclPGz3qzu0CtU1hrpudRYe8Pc3O/CoHC5Li47ozOkXcZ8U0z6UpGfKrt Xiy3gTWJgiYw1nq2M7V/0juYhci7uncFfiFUIKeubcG+AQF7+kbsYKMfNaWbCbAM PZ9iYMXBwXsChIJWA3+erUjq8CFjiXX0/n9wM/bzs8lFGiVLWbB3NaFHujgQ1d3P FkDKflR5GE95gwQDKQiuJ0VttTJMncTl/SJXCSvmmnOK6mbqC9jSw5m8xfwV2Lko XO/M9wBpgfascpcFkxKK66WnDH+fBPY0R1Il3mVgG1oTnQSSIRpS0hWi6hZXAQwK vXJskIDGvk2gS0kCMO7tixzF9XQ2duL8b4aTaN5P24zjLpv72+Hjn/Wg1ZChhVet VnLZbtUpVRQw7epMeOCUVdGo8IpfIOs1kXp8MRFj72kgyRQF4dBEnKJmykizeH5f UxC0KCy9UV90QkPeedJiboeKxtKgVNXifE8KEbu464htk9aL0EZZ+EeZX4dE0JRz 4WTqnht+/6HvWRheh8BJ8WV13nYIbpb1lU0JcAkhw2QI894vizU+gQ/eEGDZv4k/ AQZzkXQ+yDmB8mKnpJd6 =n+4C -----END PGP SIGNATURE----- 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: * kcore annotation improvements, including build-id cache support, multi map 'call' instruction navigation fixes, kcore address validation, objdump workarounds. From Adrian Hunter. * 'trace' beautifiers for lots of syscall arguments, from Arnaldo Carvalho de Melo. * More compact 'trace' output by suppressing zeroed args, from Arnaldo Carvalho de Melo. * Show thread COMM by default in 'trace', from Arnaldo Carvalho de Melo. * Show path associated with fd in live sessions, using a 'vfs_getname' 'perf probe' created dynamic tracepoint or by looking at /proc/pid/fd, from Arnaldo Carvalho de Melo. * Memory and mmap leak fixes from Chenggang Qin. * Add option to show full timestamp in 'trace', from David Ahern. * Add 'record' command in 'trace', to record raw_syscalls:*, from David Ahern. * Add summary option to dump syscall statistics in 'trace', from David Ahern. * Fix comm resolution in 'trace' when reading events from file, from David Ahern. * Improved messages when doing profiling in all or a subset of CPUs using a workload as the session delimitator, as in: 'perf stat --cpu 0,2 sleep 10s' from Arnaldo Carvalho de Melo. * Add units to nanosec-based counters in 'perf stat', from David Ahern. * Assorted build fixes for from David Ahern and Jiri Olsa. * 'perf lock' fixes and cleanups, from Davidlohr Bueso. * Memory leak fixes in 'perf test', from Felipe Pena. * Build system super speedups, from Ingo Molnar. * Fix mmap_read event overflow, from Jiri Olsa. * Code cleanups from Jiri Olsa. * Allow specifying B/K/M/G unit to the --mmap-pages arguments, from Jiri Olsa. * Separate the GTK support in a separate libperf-gtk.so DSO, that is only loaded when --gtk is specified, from Namhyung Kim. * Fixes for some memory leaks, from Namhyumg Kim. * Fix srcline sort key behavior, from Namhyung Kim. * Fix failing assertions in numa bench, from Petr Holasek. * perf bash completion fixes and improvements from Ramkumar Ramachandra. * Improve error messages in 'trace', providing hints about system configuration steps needed for using it, from Ramkumar Ramachandra. * Remove bogus info when using 'perf stat' -e cycles/instructions, from Ramkumar Ramachandra. * Support for Openembedded/Yocto -dbg packages, from Ricardo Ribalda Delgado. * Implement addr2line directly using libbfd, from Roberto Vitillo. * Add new option --ignore-vmlinux for perf top, from Willy Tarreau. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
1ff9ecf797
@ -134,14 +134,14 @@ ifeq ($(VERBOSE),1)
|
||||
print_install =
|
||||
else
|
||||
Q = @
|
||||
print_compile = echo ' CC '$(OBJ);
|
||||
print_app_build = echo ' BUILD '$(OBJ);
|
||||
print_fpic_compile = echo ' CC FPIC '$(OBJ);
|
||||
print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ);
|
||||
print_plugin_obj_compile = echo ' CC PLUGIN OBJ '$(OBJ);
|
||||
print_plugin_build = echo ' CC PLUGI '$(OBJ);
|
||||
print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ);
|
||||
print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2';
|
||||
print_compile = echo ' CC '$(OBJ);
|
||||
print_app_build = echo ' BUILD '$(OBJ);
|
||||
print_fpic_compile = echo ' CC FPIC '$(OBJ);
|
||||
print_shared_lib_compile = echo ' BUILD SHARED LIB '$(OBJ);
|
||||
print_plugin_obj_compile = echo ' BUILD PLUGIN OBJ '$(OBJ);
|
||||
print_plugin_build = echo ' BUILD PLUGIN '$(OBJ);
|
||||
print_static_lib_build = echo ' BUILD STATIC LIB '$(OBJ);
|
||||
print_install = echo ' INSTALL '$1' to $(DESTDIR_SQ)$2';
|
||||
endif
|
||||
|
||||
do_fpic_compile = \
|
||||
@ -268,7 +268,7 @@ TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
|
||||
TRACEEVENT-CFLAGS: force
|
||||
@FLAGS='$(TRACK_CFLAGS)'; \
|
||||
if test x"$$FLAGS" != x"`cat TRACEEVENT-CFLAGS 2>/dev/null`" ; then \
|
||||
echo 1>&2 " * new build flags or cross compiler"; \
|
||||
echo 1>&2 " FLAGS: * new build flags or cross compiler"; \
|
||||
echo "$$FLAGS" >TRACEEVENT-CFLAGS; \
|
||||
fi
|
||||
|
||||
|
1
tools/perf/.gitignore
vendored
1
tools/perf/.gitignore
vendored
@ -13,6 +13,7 @@ perf*.html
|
||||
common-cmds.h
|
||||
perf.data
|
||||
perf.data.old
|
||||
output.svg
|
||||
perf-archive
|
||||
tags
|
||||
TAGS
|
||||
|
@ -145,16 +145,17 @@ endif
|
||||
|
||||
ifneq ($(findstring $(MAKEFLAGS),s),s)
|
||||
ifneq ($(V),1)
|
||||
QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@;
|
||||
QUIET_XMLTO = @echo ' ' XMLTO $@;
|
||||
QUIET_DB2TEXI = @echo ' ' DB2TEXI $@;
|
||||
QUIET_MAKEINFO = @echo ' ' MAKEINFO $@;
|
||||
QUIET_DBLATEX = @echo ' ' DBLATEX $@;
|
||||
QUIET_XSLTPROC = @echo ' ' XSLTPROC $@;
|
||||
QUIET_GEN = @echo ' ' GEN $@;
|
||||
QUIET_ASCIIDOC = @echo ' ASCIIDOC '$@;
|
||||
QUIET_XMLTO = @echo ' XMLTO '$@;
|
||||
QUIET_DB2TEXI = @echo ' DB2TEXI '$@;
|
||||
QUIET_MAKEINFO = @echo ' MAKEINFO '$@;
|
||||
QUIET_DBLATEX = @echo ' DBLATEX '$@;
|
||||
QUIET_XSLTPROC = @echo ' XSLTPROC '$@;
|
||||
QUIET_GEN = @echo ' GEN '$@;
|
||||
QUIET_STDERR = 2> /dev/null
|
||||
QUIET_SUBDIR0 = +@subdir=
|
||||
QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
|
||||
QUIET_SUBDIR1 = ;$(NO_SUBDIR) \
|
||||
echo ' SUBDIR ' $$subdir; \
|
||||
$(MAKE) $(PRINT_DIR) -C $$subdir
|
||||
export V
|
||||
endif
|
||||
@ -183,47 +184,43 @@ ifdef missing_tools
|
||||
endif
|
||||
|
||||
do-install-man: man
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
|
||||
# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir)
|
||||
# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir)
|
||||
$(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir)
|
||||
# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir)
|
||||
# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
|
||||
$(call QUIET_INSTALL, Documentation-man) \
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(man1dir); \
|
||||
# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir); \
|
||||
# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir); \
|
||||
$(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir); \
|
||||
# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir); \
|
||||
# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
|
||||
|
||||
install-man: check-man-tools man
|
||||
|
||||
try-install-man:
|
||||
ifdef missing_tools
|
||||
$(warning Please install $(missing_tools) to have the man pages installed)
|
||||
DO_INSTALL_MAN = $(warning Please install $(missing_tools) to have the man pages installed)
|
||||
else
|
||||
$(MAKE) do-install-man
|
||||
DO_INSTALL_MAN = do-install-man
|
||||
endif
|
||||
|
||||
try-install-man: $(DO_INSTALL_MAN)
|
||||
|
||||
install-info: info
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir)
|
||||
$(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir)
|
||||
$(call QUIET_INSTALL, Documentation-info) \
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(infodir); \
|
||||
$(INSTALL) -m 644 $(OUTPUT)perf.info $(OUTPUT)perfman.info $(DESTDIR)$(infodir); \
|
||||
if test -r $(DESTDIR)$(infodir)/dir; then \
|
||||
$(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perf.info ;\
|
||||
$(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perfman.info ;\
|
||||
$(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perf.info ;\
|
||||
$(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) perfman.info ;\
|
||||
else \
|
||||
echo "No directory found in $(DESTDIR)$(infodir)" >&2 ; \
|
||||
fi
|
||||
|
||||
install-pdf: pdf
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir)
|
||||
$(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir)
|
||||
$(call QUIET_INSTALL, Documentation-pdf) \
|
||||
$(INSTALL) -d -m 755 $(DESTDIR)$(pdfdir); \
|
||||
$(INSTALL) -m 644 $(OUTPUT)user-manual.pdf $(DESTDIR)$(pdfdir)
|
||||
|
||||
#install-html: html
|
||||
# '$(SHELL_PATH_SQ)' ./install-webdoc.sh $(DESTDIR)$(htmldir)
|
||||
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(MAKECMDGOALS),tags)
|
||||
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
|
||||
$(QUIET_SUBDIR0)../ $(QUIET_SUBDIR1) $(OUTPUT)PERF-VERSION-FILE
|
||||
|
||||
-include $(OUTPUT)PERF-VERSION-FILE
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# Determine "include::" file references in asciidoc files.
|
||||
@ -253,15 +250,17 @@ $(OUTPUT)cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
|
||||
$(PERL_PATH) ./cmd-list.perl ../command-list.txt $(QUIET_STDERR) && \
|
||||
date >$@
|
||||
|
||||
CLEAN_FILES = \
|
||||
$(MAN_XML) $(addsuffix +,$(MAN_XML)) \
|
||||
$(MAN_HTML) $(addsuffix +,$(MAN_HTML)) \
|
||||
$(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7) \
|
||||
$(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++ \
|
||||
$(OUTPUT)perf.info $(OUTPUT)perfman.info \
|
||||
$(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep \
|
||||
$(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt \
|
||||
$(cmds_txt) $(OUTPUT)*.made
|
||||
clean:
|
||||
$(RM) $(MAN_XML) $(addsuffix +,$(MAN_XML))
|
||||
$(RM) $(MAN_HTML) $(addsuffix +,$(MAN_HTML))
|
||||
$(RM) $(DOC_HTML) $(DOC_MAN1) $(DOC_MAN5) $(DOC_MAN7)
|
||||
$(RM) $(OUTPUT)*.texi $(OUTPUT)*.texi+ $(OUTPUT)*.texi++
|
||||
$(RM) $(OUTPUT)perf.info $(OUTPUT)perfman.info
|
||||
$(RM) $(OUTPUT)howto-index.txt $(OUTPUT)howto/*.html $(OUTPUT)doc.dep
|
||||
$(RM) $(OUTPUT)technical/api-*.html $(OUTPUT)technical/api-index.txt
|
||||
$(RM) $(cmds_txt) $(OUTPUT)*.made
|
||||
$(call QUIET_CLEAN, Documentation) $(RM) $(CLEAN_FILES)
|
||||
|
||||
$(MAN_HTML): $(OUTPUT)%.html : %.txt
|
||||
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
|
||||
@ -342,5 +341,3 @@ $(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt
|
||||
|
||||
#quick-install-html:
|
||||
# '$(SHELL_PATH_SQ)' ./install-doc-quick.sh $(HTML_REF) $(DESTDIR)$(htmldir)
|
||||
|
||||
.PHONY: .FORCE-PERF-VERSION-FILE
|
||||
|
@ -21,6 +21,19 @@ OPTIONS
|
||||
-a::
|
||||
--add=::
|
||||
Add specified file to the cache.
|
||||
-k::
|
||||
--kcore::
|
||||
Add specified kcore file to the cache. For the current host that is
|
||||
/proc/kcore which requires root permissions to read. Be aware that
|
||||
running 'perf buildid-cache' as root may update root's build-id cache
|
||||
not the user's. Use the -v option to see where the file is created.
|
||||
Note that the copied file contains only code sections not the whole core
|
||||
image. Note also that files "kallsyms" and "modules" must also be in the
|
||||
same directory and are also copied. All 3 files are created with read
|
||||
permissions for root only. kcore will not be added if there is already a
|
||||
kcore in the cache (with the same build-id) that has the same modules at
|
||||
the same addresses. Use the -v option to see if a copy of kcore is
|
||||
actually made.
|
||||
-r::
|
||||
--remove=::
|
||||
Remove specified file from the cache.
|
||||
|
@ -109,7 +109,9 @@ STAT LIVE OPTIONS
|
||||
|
||||
-m::
|
||||
--mmap-pages=::
|
||||
Number of mmap data pages. Must be a power of two.
|
||||
Number of mmap data pages (must be a power of two) or size
|
||||
specification with appended unit character - B/K/M/G. The
|
||||
size is rounded up to have nearest pages power of two value.
|
||||
|
||||
-a::
|
||||
--all-cpus::
|
||||
|
@ -48,7 +48,7 @@ REPORT OPTIONS
|
||||
-k::
|
||||
--key=<value>::
|
||||
Sorting key. Possible values: acquired (default), contended,
|
||||
wait_total, wait_max, wait_min.
|
||||
avg_wait, wait_total, wait_max, wait_min.
|
||||
|
||||
INFO OPTIONS
|
||||
------------
|
||||
|
@ -87,7 +87,9 @@ OPTIONS
|
||||
|
||||
-m::
|
||||
--mmap-pages=::
|
||||
Number of mmap data pages. Must be a power of two.
|
||||
Number of mmap data pages (must be a power of two) or size
|
||||
specification with appended unit character - B/K/M/G. The
|
||||
size is rounded up to have nearest pages power of two value.
|
||||
|
||||
-g::
|
||||
--call-graph::
|
||||
|
@ -8,7 +8,8 @@ perf-timechart - Tool to visualize total system behavior during a workload
|
||||
SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'perf timechart' {record}
|
||||
'perf timechart' record <command>
|
||||
'perf timechart' [<options>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -41,6 +42,18 @@ OPTIONS
|
||||
--symfs=<directory>::
|
||||
Look for files with symbols relative to this directory.
|
||||
|
||||
EXAMPLES
|
||||
--------
|
||||
|
||||
$ perf timechart record git pull
|
||||
|
||||
[ perf record: Woken up 13 times to write data ]
|
||||
[ perf record: Captured and wrote 4.253 MB perf.data (~185801 samples) ]
|
||||
|
||||
$ perf timechart
|
||||
|
||||
Written 10.2 seconds of trace to output.svg.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-record[1]
|
||||
|
@ -68,7 +68,9 @@ Default is to monitor all CPUS.
|
||||
|
||||
-m <pages>::
|
||||
--mmap-pages=<pages>::
|
||||
Number of mmapped data pages.
|
||||
Number of mmap data pages (must be a power of two) or size
|
||||
specification with appended unit character - B/K/M/G. The
|
||||
size is rounded up to have nearest pages power of two value.
|
||||
|
||||
-p <pid>::
|
||||
--pid=<pid>::
|
||||
|
@ -9,6 +9,7 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'perf trace'
|
||||
'perf trace record'
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -16,9 +17,14 @@ This command will show the events associated with the target, initially
|
||||
syscalls, but other system events like pagefaults, task lifetime events,
|
||||
scheduling events, etc.
|
||||
|
||||
Initially this is a live mode only tool, but eventually will work with
|
||||
perf.data files like the other tools, allowing a detached 'record' from
|
||||
analysis phases.
|
||||
This is a live mode tool in addition to working with perf.data files like
|
||||
the other perf tools. Files can be generated using the 'perf record' command
|
||||
but the session needs to include the raw_syscalls events (-e 'raw_syscalls:*').
|
||||
Alernatively, the 'perf trace record' can be used as a shortcut to
|
||||
automatically include the raw_syscalls events when writing events to a file.
|
||||
|
||||
The following options apply to perf trace; options to perf trace record are
|
||||
found in the perf record man page.
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
@ -59,7 +65,9 @@ OPTIONS
|
||||
|
||||
-m::
|
||||
--mmap-pages=::
|
||||
Number of mmap data pages. Must be a power of two.
|
||||
Number of mmap data pages (must be a power of two) or size
|
||||
specification with appended unit character - B/K/M/G. The
|
||||
size is rounded up to have nearest pages power of two value.
|
||||
|
||||
-C::
|
||||
--cpu::
|
||||
@ -78,6 +86,17 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
|
||||
--input
|
||||
Process events from a given perf data file.
|
||||
|
||||
-T
|
||||
--time
|
||||
Print full timestamp rather time relative to first sample.
|
||||
|
||||
--comm::
|
||||
Show process COMM right beside its ID, on by default, disable with --no-comm.
|
||||
|
||||
--summary::
|
||||
Show a summary of syscalls by thread with min, max, and average times (in
|
||||
msec) and relative stddev.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-record[1], linkperf:perf-script[1]
|
||||
|
@ -1,819 +1,79 @@
|
||||
include ../scripts/Makefile.include
|
||||
|
||||
# The default target of this Makefile is...
|
||||
all:
|
||||
|
||||
include config/utilities.mak
|
||||
|
||||
# Define V to have a more verbose compile.
|
||||
#
|
||||
# Define O to save output files in a separate directory.
|
||||
# This is a simple wrapper Makefile that calls the main Makefile.perf
|
||||
# with a -j option to do parallel builds
|
||||
#
|
||||
# Define ARCH as name of target architecture if you want cross-builds.
|
||||
#
|
||||
# Define CROSS_COMPILE as prefix name of compiler if you want cross-builds.
|
||||
#
|
||||
# Define NO_LIBPERL to disable perl script extension.
|
||||
#
|
||||
# Define NO_LIBPYTHON to disable python script extension.
|
||||
#
|
||||
# Define PYTHON to point to the python binary if the default
|
||||
# `python' is not correct; for example: PYTHON=python2
|
||||
#
|
||||
# Define PYTHON_CONFIG to point to the python-config binary if
|
||||
# the default `$(PYTHON)-config' is not correct.
|
||||
#
|
||||
# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
|
||||
#
|
||||
# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
|
||||
#
|
||||
# Define LDFLAGS=-static to build a static binary.
|
||||
#
|
||||
# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
|
||||
#
|
||||
# Define NO_DWARF if you do not want debug-info analysis feature at all.
|
||||
#
|
||||
# Define WERROR=0 to disable treating any warnings as errors.
|
||||
#
|
||||
# Define NO_NEWT if you do not want TUI support. (deprecated)
|
||||
#
|
||||
# Define NO_SLANG if you do not want TUI support.
|
||||
#
|
||||
# Define NO_GTK2 if you do not want GTK+ GUI support.
|
||||
#
|
||||
# Define NO_DEMANGLE if you do not want C++ symbol demangling.
|
||||
#
|
||||
# Define NO_LIBELF if you do not want libelf dependency (e.g. cross-builds)
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Define NO_LIBNUMA if you do not want numa perf benchmark
|
||||
#
|
||||
# Define NO_LIBAUDIT if you do not want libaudit support
|
||||
#
|
||||
# Define NO_LIBBIONIC if you do not want bionic support
|
||||
|
||||
ifeq ($(srctree),)
|
||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||
#$(info Determined 'srctree' to be $(srctree))
|
||||
endif
|
||||
|
||||
ifneq ($(objtree),)
|
||||
#$(info Determined 'objtree' to be $(objtree))
|
||||
endif
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
#$(info Determined 'OUTPUT' to be $(OUTPUT))
|
||||
endif
|
||||
|
||||
$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
|
||||
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
|
||||
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
|
||||
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
|
||||
|
||||
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 =
|
||||
LIB_H =
|
||||
LIB_OBJS =
|
||||
PYRF_OBJS =
|
||||
SCRIPT_SH =
|
||||
|
||||
SCRIPT_SH += perf-archive.sh
|
||||
|
||||
grep-libs = $(filter -l%,$(1))
|
||||
strip-libs = $(filter-out -l%,$(1))
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
TE_PATH=$(OUTPUT)
|
||||
ifneq ($(subdir),)
|
||||
LK_PATH=$(OUTPUT)/../lib/lk/
|
||||
else
|
||||
LK_PATH=$(OUTPUT)
|
||||
endif
|
||||
else
|
||||
TE_PATH=$(TRACE_EVENT_DIR)
|
||||
LK_PATH=$(LK_DIR)
|
||||
endif
|
||||
|
||||
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
||||
export LIBTRACEEVENT
|
||||
|
||||
LIBLK = $(LK_PATH)liblk.a
|
||||
export LIBLK
|
||||
|
||||
# python extension build directories
|
||||
PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/
|
||||
PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
|
||||
PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/
|
||||
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) $(LIBLK)
|
||||
|
||||
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
|
||||
$(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
|
||||
--quiet build_ext; \
|
||||
mkdir -p $(OUTPUT)python && \
|
||||
cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
|
||||
#
|
||||
# No Perl scripts right now:
|
||||
# If you want to invoke the perf build in some non-standard way then
|
||||
# you can use the 'make -f Makefile.perf' method to invoke it.
|
||||
#
|
||||
|
||||
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
|
||||
#
|
||||
# Clear out the built-in rules GNU make defines by default (such as .o targets),
|
||||
# so that we pass through all targets to Makefile.perf:
|
||||
#
|
||||
.SUFFIXES:
|
||||
|
||||
#
|
||||
# Single 'perf' binary right now:
|
||||
# We don't want to pass along options like -j:
|
||||
#
|
||||
PROGRAMS += $(OUTPUT)perf
|
||||
unexport MAKEFLAGS
|
||||
|
||||
# what 'all' will build and 'install' will install, in perfexecdir
|
||||
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
|
||||
|
||||
# what 'all' will build but not install in perfexecdir
|
||||
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
|
||||
endif
|
||||
ifndef PERL_PATH
|
||||
PERL_PATH = /usr/bin/perl
|
||||
endif
|
||||
|
||||
export PERL_PATH
|
||||
|
||||
$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
|
||||
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
|
||||
|
||||
$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
|
||||
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
|
||||
|
||||
$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
|
||||
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
|
||||
|
||||
$(OUTPUT)util/pmu-bison.c: util/pmu.y
|
||||
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
|
||||
|
||||
$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
|
||||
$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
|
||||
|
||||
LIB_FILE=$(OUTPUT)libperf.a
|
||||
|
||||
LIB_H += ../../include/uapi/linux/perf_event.h
|
||||
LIB_H += ../../include/linux/rbtree.h
|
||||
LIB_H += ../../include/linux/list.h
|
||||
LIB_H += ../../include/uapi/linux/const.h
|
||||
LIB_H += ../../include/linux/hash.h
|
||||
LIB_H += ../../include/linux/stringify.h
|
||||
LIB_H += util/include/linux/bitmap.h
|
||||
LIB_H += util/include/linux/bitops.h
|
||||
LIB_H += util/include/linux/compiler.h
|
||||
LIB_H += util/include/linux/const.h
|
||||
LIB_H += util/include/linux/ctype.h
|
||||
LIB_H += util/include/linux/kernel.h
|
||||
LIB_H += util/include/linux/list.h
|
||||
LIB_H += util/include/linux/export.h
|
||||
LIB_H += util/include/linux/magic.h
|
||||
LIB_H += util/include/linux/poison.h
|
||||
LIB_H += util/include/linux/prefetch.h
|
||||
LIB_H += util/include/linux/rbtree.h
|
||||
LIB_H += util/include/linux/rbtree_augmented.h
|
||||
LIB_H += util/include/linux/string.h
|
||||
LIB_H += util/include/linux/types.h
|
||||
LIB_H += util/include/linux/linkage.h
|
||||
LIB_H += util/include/asm/asm-offsets.h
|
||||
LIB_H += util/include/asm/bug.h
|
||||
LIB_H += util/include/asm/byteorder.h
|
||||
LIB_H += util/include/asm/hweight.h
|
||||
LIB_H += util/include/asm/swab.h
|
||||
LIB_H += util/include/asm/system.h
|
||||
LIB_H += util/include/asm/uaccess.h
|
||||
LIB_H += util/include/dwarf-regs.h
|
||||
LIB_H += util/include/asm/dwarf2.h
|
||||
LIB_H += util/include/asm/cpufeature.h
|
||||
LIB_H += util/include/asm/unistd_32.h
|
||||
LIB_H += util/include/asm/unistd_64.h
|
||||
LIB_H += perf.h
|
||||
LIB_H += util/annotate.h
|
||||
LIB_H += util/cache.h
|
||||
LIB_H += util/callchain.h
|
||||
LIB_H += util/build-id.h
|
||||
LIB_H += util/debug.h
|
||||
LIB_H += util/sysfs.h
|
||||
LIB_H += util/pmu.h
|
||||
LIB_H += util/event.h
|
||||
LIB_H += util/evsel.h
|
||||
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
|
||||
LIB_H += util/quote.h
|
||||
LIB_H += util/util.h
|
||||
LIB_H += util/xyarray.h
|
||||
LIB_H += util/header.h
|
||||
LIB_H += util/help.h
|
||||
LIB_H += util/session.h
|
||||
LIB_H += util/strbuf.h
|
||||
LIB_H += util/strlist.h
|
||||
LIB_H += util/strfilter.h
|
||||
LIB_H += util/svghelper.h
|
||||
LIB_H += util/tool.h
|
||||
LIB_H += util/run-command.h
|
||||
LIB_H += util/sigchain.h
|
||||
LIB_H += util/dso.h
|
||||
LIB_H += util/symbol.h
|
||||
LIB_H += util/color.h
|
||||
LIB_H += util/values.h
|
||||
LIB_H += util/sort.h
|
||||
LIB_H += util/hist.h
|
||||
LIB_H += util/thread.h
|
||||
LIB_H += util/thread_map.h
|
||||
LIB_H += util/trace-event.h
|
||||
LIB_H += util/probe-finder.h
|
||||
LIB_H += util/dwarf-aux.h
|
||||
LIB_H += util/probe-event.h
|
||||
LIB_H += util/pstack.h
|
||||
LIB_H += util/cpumap.h
|
||||
LIB_H += util/top.h
|
||||
LIB_H += $(ARCH_INCLUDE)
|
||||
LIB_H += util/cgroup.h
|
||||
LIB_H += $(LIB_INCLUDE)traceevent/event-parse.h
|
||||
LIB_H += util/target.h
|
||||
LIB_H += util/rblist.h
|
||||
LIB_H += util/intlist.h
|
||||
LIB_H += util/perf_regs.h
|
||||
LIB_H += util/unwind.h
|
||||
LIB_H += util/vdso.h
|
||||
LIB_H += ui/helpline.h
|
||||
LIB_H += ui/progress.h
|
||||
LIB_H += ui/util.h
|
||||
LIB_H += ui/ui.h
|
||||
|
||||
LIB_OBJS += $(OUTPUT)util/abspath.o
|
||||
LIB_OBJS += $(OUTPUT)util/alias.o
|
||||
LIB_OBJS += $(OUTPUT)util/annotate.o
|
||||
LIB_OBJS += $(OUTPUT)util/build-id.o
|
||||
LIB_OBJS += $(OUTPUT)util/config.o
|
||||
LIB_OBJS += $(OUTPUT)util/ctype.o
|
||||
LIB_OBJS += $(OUTPUT)util/sysfs.o
|
||||
LIB_OBJS += $(OUTPUT)util/pmu.o
|
||||
LIB_OBJS += $(OUTPUT)util/environment.o
|
||||
LIB_OBJS += $(OUTPUT)util/event.o
|
||||
LIB_OBJS += $(OUTPUT)util/evlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/evsel.o
|
||||
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
|
||||
LIB_OBJS += $(OUTPUT)util/help.o
|
||||
LIB_OBJS += $(OUTPUT)util/levenshtein.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-options.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events.o
|
||||
LIB_OBJS += $(OUTPUT)util/path.o
|
||||
LIB_OBJS += $(OUTPUT)util/rbtree.o
|
||||
LIB_OBJS += $(OUTPUT)util/bitmap.o
|
||||
LIB_OBJS += $(OUTPUT)util/hweight.o
|
||||
LIB_OBJS += $(OUTPUT)util/run-command.o
|
||||
LIB_OBJS += $(OUTPUT)util/quote.o
|
||||
LIB_OBJS += $(OUTPUT)util/strbuf.o
|
||||
LIB_OBJS += $(OUTPUT)util/string.o
|
||||
LIB_OBJS += $(OUTPUT)util/strlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/strfilter.o
|
||||
LIB_OBJS += $(OUTPUT)util/top.o
|
||||
LIB_OBJS += $(OUTPUT)util/usage.o
|
||||
LIB_OBJS += $(OUTPUT)util/wrapper.o
|
||||
LIB_OBJS += $(OUTPUT)util/sigchain.o
|
||||
LIB_OBJS += $(OUTPUT)util/dso.o
|
||||
LIB_OBJS += $(OUTPUT)util/symbol.o
|
||||
LIB_OBJS += $(OUTPUT)util/symbol-elf.o
|
||||
LIB_OBJS += $(OUTPUT)util/color.o
|
||||
LIB_OBJS += $(OUTPUT)util/pager.o
|
||||
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
|
||||
LIB_OBJS += $(OUTPUT)util/thread.o
|
||||
LIB_OBJS += $(OUTPUT)util/thread_map.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events-flex.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events-bison.o
|
||||
LIB_OBJS += $(OUTPUT)util/pmu-flex.o
|
||||
LIB_OBJS += $(OUTPUT)util/pmu-bison.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-read.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-info.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
|
||||
LIB_OBJS += $(OUTPUT)util/svghelper.o
|
||||
LIB_OBJS += $(OUTPUT)util/sort.o
|
||||
LIB_OBJS += $(OUTPUT)util/hist.o
|
||||
LIB_OBJS += $(OUTPUT)util/probe-event.o
|
||||
LIB_OBJS += $(OUTPUT)util/util.o
|
||||
LIB_OBJS += $(OUTPUT)util/xyarray.o
|
||||
LIB_OBJS += $(OUTPUT)util/cpumap.o
|
||||
LIB_OBJS += $(OUTPUT)util/cgroup.o
|
||||
LIB_OBJS += $(OUTPUT)util/target.o
|
||||
LIB_OBJS += $(OUTPUT)util/rblist.o
|
||||
LIB_OBJS += $(OUTPUT)util/intlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/vdso.o
|
||||
LIB_OBJS += $(OUTPUT)util/stat.o
|
||||
LIB_OBJS += $(OUTPUT)util/record.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)ui/setup.o
|
||||
LIB_OBJS += $(OUTPUT)ui/helpline.o
|
||||
LIB_OBJS += $(OUTPUT)ui/progress.o
|
||||
LIB_OBJS += $(OUTPUT)ui/util.o
|
||||
LIB_OBJS += $(OUTPUT)ui/hist.o
|
||||
LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)arch/common.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)tests/parse-events.o
|
||||
LIB_OBJS += $(OUTPUT)tests/dso-data.o
|
||||
LIB_OBJS += $(OUTPUT)tests/attr.o
|
||||
LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o
|
||||
LIB_OBJS += $(OUTPUT)tests/open-syscall.o
|
||||
LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
|
||||
LIB_OBJS += $(OUTPUT)tests/open-syscall-tp-fields.o
|
||||
LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
|
||||
LIB_OBJS += $(OUTPUT)tests/perf-record.o
|
||||
LIB_OBJS += $(OUTPUT)tests/rdpmc.o
|
||||
LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o
|
||||
LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o
|
||||
LIB_OBJS += $(OUTPUT)tests/pmu.o
|
||||
LIB_OBJS += $(OUTPUT)tests/hists_link.o
|
||||
LIB_OBJS += $(OUTPUT)tests/python-use.o
|
||||
LIB_OBJS += $(OUTPUT)tests/bp_signal.o
|
||||
LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
|
||||
LIB_OBJS += $(OUTPUT)tests/task-exit.o
|
||||
LIB_OBJS += $(OUTPUT)tests/sw-clock.o
|
||||
ifeq ($(ARCH),x86)
|
||||
LIB_OBJS += $(OUTPUT)tests/perf-time-to-tsc.o
|
||||
endif
|
||||
LIB_OBJS += $(OUTPUT)tests/code-reading.o
|
||||
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
|
||||
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
|
||||
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
|
||||
# Benchmark modules
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
|
||||
ifeq ($(RAW_ARCH),x86_64)
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o
|
||||
endif
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o
|
||||
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-help.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-list.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-record.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-report.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-top.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-script.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
|
||||
BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
|
||||
|
||||
PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
|
||||
|
||||
# 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...
|
||||
|
||||
-include arch/$(ARCH)/Makefile
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
CFLAGS += -I$(OUTPUT)
|
||||
endif
|
||||
|
||||
ifdef NO_LIBELF
|
||||
EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
|
||||
|
||||
# Remove ELF/DWARF dependent codes
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS))
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/probe-event.o,$(LIB_OBJS))
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/probe-finder.o,$(LIB_OBJS))
|
||||
|
||||
BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
|
||||
|
||||
# Use minimal symbol handling
|
||||
LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
|
||||
|
||||
else # NO_LIBELF
|
||||
ifndef NO_DWARF
|
||||
LIB_OBJS += $(OUTPUT)util/probe-finder.o
|
||||
LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
|
||||
endif # NO_DWARF
|
||||
endif # NO_LIBELF
|
||||
|
||||
ifndef NO_LIBUNWIND
|
||||
LIB_OBJS += $(OUTPUT)util/unwind.o
|
||||
endif
|
||||
LIB_OBJS += $(OUTPUT)tests/keep-tracking.o
|
||||
|
||||
ifndef NO_LIBAUDIT
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
|
||||
endif
|
||||
|
||||
ifndef NO_SLANG
|
||||
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
|
||||
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
|
||||
|
||||
ifndef NO_LIBPERL
|
||||
LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
|
||||
LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
|
||||
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
|
||||
#
|
||||
# Do a parallel build with multiple jobs, based on the number of CPUs online
|
||||
# in this system: 'make -j8' on a 8-CPU system, etc.
|
||||
#
|
||||
# (To override it, run 'make JOBS=1' and similar.)
|
||||
#
|
||||
ifeq ($(JOBS),)
|
||||
JOBS := $(shell grep -c ^processor /proc/cpuinfo 2>/dev/null)
|
||||
ifeq ($(JOBS),)
|
||||
JOBS := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_LIBNUMA
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/numa.o
|
||||
#
|
||||
# Only pass canonical directory names as the output directory:
|
||||
#
|
||||
ifneq ($(O),)
|
||||
FULL_O := $(shell readlink -f $(O) || echo $(O))
|
||||
endif
|
||||
|
||||
ifdef ASCIIDOC8
|
||||
export ASCIIDOC8
|
||||
#
|
||||
# Only accept the 'DEBUG' variable from the command line:
|
||||
#
|
||||
ifeq ("$(origin DEBUG)", "command line")
|
||||
ifeq ($(DEBUG),)
|
||||
override DEBUG = 0
|
||||
else
|
||||
SET_DEBUG = "DEBUG=$(DEBUG)"
|
||||
endif
|
||||
else
|
||||
override DEBUG = 0
|
||||
endif
|
||||
|
||||
LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
|
||||
define print_msg
|
||||
@printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n'
|
||||
endef
|
||||
|
||||
export INSTALL SHELL_PATH
|
||||
define make
|
||||
@$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $(SET_DEBUG) $@
|
||||
endef
|
||||
|
||||
### Build rules
|
||||
#
|
||||
# Needed if no target specified:
|
||||
#
|
||||
all:
|
||||
$(print_msg)
|
||||
$(make)
|
||||
|
||||
SHELL = $(SHELL_PATH)
|
||||
#
|
||||
# The clean target is not really parallel, don't print the jobs info:
|
||||
#
|
||||
clean:
|
||||
$(make)
|
||||
|
||||
all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
|
||||
|
||||
please_set_SHELL_PATH_to_a_more_modern_shell:
|
||||
@$$(:)
|
||||
|
||||
shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
|
||||
strip: $(PROGRAMS) $(OUTPUT)perf
|
||||
$(STRIP) $(STRIP_OPTS) $(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)"' \
|
||||
$(CFLAGS) -c $(filter %.c,$^) -o $@
|
||||
|
||||
$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
|
||||
$(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 $(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 $(CFLAGS) \
|
||||
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
|
||||
'-DPERF_MAN_PATH="$(mandir_SQ)"' \
|
||||
'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
|
||||
|
||||
$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
|
||||
|
||||
$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
|
||||
$(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
|
||||
|
||||
$(SCRIPTS) : % : %.sh
|
||||
$(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
|
||||
|
||||
# These can record PERF_VERSION
|
||||
$(OUTPUT)perf.o perf.spec \
|
||||
$(SCRIPTS) \
|
||||
: $(OUTPUT)PERF-VERSION-FILE
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .o .c .S .s
|
||||
|
||||
# These two need to be here so that when O= is not used they take precedence
|
||||
# over the general rule for .o
|
||||
|
||||
$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
|
||||
|
||||
$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
|
||||
$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
|
||||
$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
|
||||
$(OUTPUT)%.o: %.S
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
|
||||
$(OUTPUT)%.s: %.S
|
||||
$(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
|
||||
|
||||
$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-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 $(CFLAGS) \
|
||||
'-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
|
||||
$<
|
||||
|
||||
$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-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 $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
||||
|
||||
$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(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 $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $<
|
||||
|
||||
$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default $<
|
||||
|
||||
$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
|
||||
|
||||
$(OUTPUT)perf-%: %.o $(PERFLIBS)
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
|
||||
|
||||
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
|
||||
$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
|
||||
|
||||
# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
|
||||
# we depend the various files onto their directories.
|
||||
DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
|
||||
$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
|
||||
# In the second step, we make a rule to actually create these directories
|
||||
$(sort $(dir $(DIRECTORY_DEPS))):
|
||||
$(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
|
||||
|
||||
$(LIB_FILE): $(LIB_OBJS)
|
||||
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
|
||||
|
||||
# libtraceevent.a
|
||||
$(LIBTRACEEVENT):
|
||||
$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a
|
||||
|
||||
$(LIBTRACEEVENT)-clean:
|
||||
$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
|
||||
|
||||
# if subdir is set, we've been called from above so target has been built
|
||||
# already
|
||||
$(LIBLK):
|
||||
ifeq ($(subdir),)
|
||||
$(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a
|
||||
endif
|
||||
|
||||
$(LIBLK)-clean:
|
||||
ifeq ($(subdir),)
|
||||
$(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean
|
||||
endif
|
||||
|
||||
help:
|
||||
@echo 'Perf make targets:'
|
||||
@echo ' doc - make *all* documentation (see below)'
|
||||
@echo ' man - make manpage documentation (access with man <foo>)'
|
||||
@echo ' html - make html documentation'
|
||||
@echo ' info - make GNU info documentation (access with info <foo>)'
|
||||
@echo ' pdf - make pdf documentation'
|
||||
@echo ' TAGS - use etags to make tag information for source browsing'
|
||||
@echo ' tags - use ctags to make tag information for source browsing'
|
||||
@echo ' cscope - use cscope to make interactive browsing database'
|
||||
@echo ''
|
||||
@echo 'Perf install targets:'
|
||||
@echo ' NOTE: documentation build requires asciidoc, xmlto packages to be installed'
|
||||
@echo ' HINT: use "make prefix=<path> <install target>" to install to a particular'
|
||||
@echo ' path like make prefix=/usr/local install install-doc'
|
||||
@echo ' install - install compiled binaries'
|
||||
@echo ' install-doc - install *all* documentation'
|
||||
@echo ' install-man - install manpage documentation'
|
||||
@echo ' install-html - install html documentation'
|
||||
@echo ' install-info - install GNU info documentation'
|
||||
@echo ' install-pdf - install pdf documentation'
|
||||
@echo ''
|
||||
@echo ' quick-install-doc - alias for quick-install-man'
|
||||
@echo ' quick-install-man - install the documentation quickly'
|
||||
@echo ' quick-install-html - install the html documentation quickly'
|
||||
@echo ''
|
||||
@echo 'Perf maintainer targets:'
|
||||
@echo ' clean - clean all binary objects and build output'
|
||||
|
||||
|
||||
DOC_TARGETS := doc man html info pdf
|
||||
|
||||
INSTALL_DOC_TARGETS := $(patsubst %,install-%,$(DOC_TARGETS)) try-install-man
|
||||
INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
|
||||
|
||||
# 'make doc' should call 'make -C Documentation all'
|
||||
$(DOC_TARGETS):
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
|
||||
|
||||
TAGS:
|
||||
$(RM) TAGS
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs etags -a
|
||||
|
||||
tags:
|
||||
$(RM) tags
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs ctags -a
|
||||
|
||||
cscope:
|
||||
$(RM) cscope*
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs cscope -b
|
||||
|
||||
### Detect prefix changes
|
||||
TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
|
||||
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
|
||||
|
||||
$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
|
||||
@FLAGS='$(TRACK_CFLAGS)'; \
|
||||
if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
|
||||
echo 1>&2 " * new build flags or prefix"; \
|
||||
echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
|
||||
fi
|
||||
|
||||
### Testing rules
|
||||
|
||||
# GNU make supports exporting all variables by "export" without parameters.
|
||||
# However, the environment gets quite big, and some programs have problems
|
||||
# with that.
|
||||
|
||||
check: $(OUTPUT)common-cmds.h
|
||||
if sparse; \
|
||||
then \
|
||||
for i in *.c */*.c; \
|
||||
do \
|
||||
sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
|
||||
done; \
|
||||
else \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
### Installation rules
|
||||
|
||||
install-bin: all
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
||||
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
||||
ifndef NO_LIBPERL
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
|
||||
$(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
|
||||
$(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
|
||||
$(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
|
||||
endif
|
||||
ifndef NO_LIBPYTHON
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
|
||||
$(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
|
||||
$(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'
|
||||
$(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
|
||||
endif
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'
|
||||
$(INSTALL) bash_completion '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'
|
||||
$(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
|
||||
$(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
|
||||
|
||||
install: install-bin try-install-man
|
||||
|
||||
install-python_ext:
|
||||
$(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
|
||||
|
||||
# 'make install-doc' should call 'make -C Documentation install'
|
||||
$(INSTALL_DOC_TARGETS):
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=)
|
||||
|
||||
### Cleaning rules
|
||||
|
||||
clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean
|
||||
$(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
|
||||
$(RM) $(ALL_PROGRAMS) perf
|
||||
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
|
||||
$(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
|
||||
$(RM) $(OUTPUT)util/*-bison*
|
||||
$(RM) $(OUTPUT)util/*-flex*
|
||||
$(python-clean)
|
||||
|
||||
.PHONY: all install clean strip $(LIBTRACEEVENT) $(LIBLK)
|
||||
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
.PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
|
||||
#
|
||||
# All other targets get passed through:
|
||||
#
|
||||
%:
|
||||
$(print_msg)
|
||||
$(make)
|
||||
|
887
tools/perf/Makefile.perf
Normal file
887
tools/perf/Makefile.perf
Normal file
@ -0,0 +1,887 @@
|
||||
include ../scripts/Makefile.include
|
||||
|
||||
# The default target of this Makefile is...
|
||||
all:
|
||||
|
||||
include config/utilities.mak
|
||||
|
||||
# Define V to have a more verbose compile.
|
||||
#
|
||||
# Define O to save output files in a separate directory.
|
||||
#
|
||||
# Define ARCH as name of target architecture if you want cross-builds.
|
||||
#
|
||||
# Define CROSS_COMPILE as prefix name of compiler if you want cross-builds.
|
||||
#
|
||||
# Define NO_LIBPERL to disable perl script extension.
|
||||
#
|
||||
# Define NO_LIBPYTHON to disable python script extension.
|
||||
#
|
||||
# Define PYTHON to point to the python binary if the default
|
||||
# `python' is not correct; for example: PYTHON=python2
|
||||
#
|
||||
# Define PYTHON_CONFIG to point to the python-config binary if
|
||||
# the default `$(PYTHON)-config' is not correct.
|
||||
#
|
||||
# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
|
||||
#
|
||||
# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
|
||||
#
|
||||
# Define LDFLAGS=-static to build a static binary.
|
||||
#
|
||||
# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
|
||||
#
|
||||
# Define NO_DWARF if you do not want debug-info analysis feature at all.
|
||||
#
|
||||
# Define WERROR=0 to disable treating any warnings as errors.
|
||||
#
|
||||
# Define NO_NEWT if you do not want TUI support. (deprecated)
|
||||
#
|
||||
# Define NO_SLANG if you do not want TUI support.
|
||||
#
|
||||
# Define NO_GTK2 if you do not want GTK+ GUI support.
|
||||
#
|
||||
# Define NO_DEMANGLE if you do not want C++ symbol demangling.
|
||||
#
|
||||
# Define NO_LIBELF if you do not want libelf dependency (e.g. cross-builds)
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Define NO_LIBNUMA if you do not want numa perf benchmark
|
||||
#
|
||||
# Define NO_LIBAUDIT if you do not want libaudit support
|
||||
#
|
||||
# Define NO_LIBBIONIC if you do not want bionic support
|
||||
|
||||
ifeq ($(srctree),)
|
||||
srctree := $(patsubst %/,%,$(dir $(shell pwd)))
|
||||
srctree := $(patsubst %/,%,$(dir $(srctree)))
|
||||
#$(info Determined 'srctree' to be $(srctree))
|
||||
endif
|
||||
|
||||
ifneq ($(objtree),)
|
||||
#$(info Determined 'objtree' to be $(objtree))
|
||||
endif
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
#$(info Determined 'OUTPUT' to be $(OUTPUT))
|
||||
endif
|
||||
|
||||
$(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD
|
||||
@$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
|
||||
@touch $(OUTPUT)PERF-VERSION-FILE
|
||||
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
AR = $(CROSS_COMPILE)ar
|
||||
|
||||
RM = rm -f
|
||||
LN = ln -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
|
||||
|
||||
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 =
|
||||
LIB_H =
|
||||
LIB_OBJS =
|
||||
GTK_OBJS =
|
||||
PYRF_OBJS =
|
||||
SCRIPT_SH =
|
||||
|
||||
SCRIPT_SH += perf-archive.sh
|
||||
|
||||
grep-libs = $(filter -l%,$(1))
|
||||
strip-libs = $(filter-out -l%,$(1))
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
TE_PATH=$(OUTPUT)
|
||||
ifneq ($(subdir),)
|
||||
LK_PATH=$(OUTPUT)/../lib/lk/
|
||||
else
|
||||
LK_PATH=$(OUTPUT)
|
||||
endif
|
||||
else
|
||||
TE_PATH=$(TRACE_EVENT_DIR)
|
||||
LK_PATH=$(LK_DIR)
|
||||
endif
|
||||
|
||||
LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
|
||||
export LIBTRACEEVENT
|
||||
|
||||
LIBLK = $(LK_PATH)liblk.a
|
||||
export LIBLK
|
||||
|
||||
# python extension build directories
|
||||
PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/
|
||||
PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
|
||||
PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/
|
||||
export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
|
||||
|
||||
python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(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) $(LIBLK)
|
||||
|
||||
$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
|
||||
$(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
|
||||
--quiet build_ext; \
|
||||
mkdir -p $(OUTPUT)python && \
|
||||
cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
|
||||
#
|
||||
# No Perl scripts right now:
|
||||
#
|
||||
|
||||
SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
|
||||
|
||||
#
|
||||
# Single 'perf' binary right now:
|
||||
#
|
||||
PROGRAMS += $(OUTPUT)perf
|
||||
|
||||
# what 'all' will build and 'install' will install, in perfexecdir
|
||||
ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
|
||||
|
||||
# what 'all' will build but not install in perfexecdir
|
||||
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
|
||||
endif
|
||||
ifndef PERL_PATH
|
||||
PERL_PATH = /usr/bin/perl
|
||||
endif
|
||||
|
||||
export PERL_PATH
|
||||
|
||||
$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
|
||||
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
|
||||
|
||||
$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
|
||||
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
|
||||
|
||||
$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
|
||||
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
|
||||
|
||||
$(OUTPUT)util/pmu-bison.c: util/pmu.y
|
||||
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
|
||||
|
||||
$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
|
||||
$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
|
||||
|
||||
LIB_FILE=$(OUTPUT)libperf.a
|
||||
|
||||
LIB_H += ../../include/uapi/linux/perf_event.h
|
||||
LIB_H += ../../include/linux/rbtree.h
|
||||
LIB_H += ../../include/linux/list.h
|
||||
LIB_H += ../../include/uapi/linux/const.h
|
||||
LIB_H += ../../include/linux/hash.h
|
||||
LIB_H += ../../include/linux/stringify.h
|
||||
LIB_H += util/include/linux/bitmap.h
|
||||
LIB_H += util/include/linux/bitops.h
|
||||
LIB_H += util/include/linux/compiler.h
|
||||
LIB_H += util/include/linux/const.h
|
||||
LIB_H += util/include/linux/ctype.h
|
||||
LIB_H += util/include/linux/kernel.h
|
||||
LIB_H += util/include/linux/list.h
|
||||
LIB_H += util/include/linux/export.h
|
||||
LIB_H += util/include/linux/magic.h
|
||||
LIB_H += util/include/linux/poison.h
|
||||
LIB_H += util/include/linux/prefetch.h
|
||||
LIB_H += util/include/linux/rbtree.h
|
||||
LIB_H += util/include/linux/rbtree_augmented.h
|
||||
LIB_H += util/include/linux/string.h
|
||||
LIB_H += util/include/linux/types.h
|
||||
LIB_H += util/include/linux/linkage.h
|
||||
LIB_H += util/include/asm/asm-offsets.h
|
||||
LIB_H += util/include/asm/bug.h
|
||||
LIB_H += util/include/asm/byteorder.h
|
||||
LIB_H += util/include/asm/hweight.h
|
||||
LIB_H += util/include/asm/swab.h
|
||||
LIB_H += util/include/asm/system.h
|
||||
LIB_H += util/include/asm/uaccess.h
|
||||
LIB_H += util/include/dwarf-regs.h
|
||||
LIB_H += util/include/asm/dwarf2.h
|
||||
LIB_H += util/include/asm/cpufeature.h
|
||||
LIB_H += util/include/asm/unistd_32.h
|
||||
LIB_H += util/include/asm/unistd_64.h
|
||||
LIB_H += perf.h
|
||||
LIB_H += util/annotate.h
|
||||
LIB_H += util/cache.h
|
||||
LIB_H += util/callchain.h
|
||||
LIB_H += util/build-id.h
|
||||
LIB_H += util/debug.h
|
||||
LIB_H += util/sysfs.h
|
||||
LIB_H += util/pmu.h
|
||||
LIB_H += util/event.h
|
||||
LIB_H += util/evsel.h
|
||||
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
|
||||
LIB_H += util/quote.h
|
||||
LIB_H += util/util.h
|
||||
LIB_H += util/xyarray.h
|
||||
LIB_H += util/header.h
|
||||
LIB_H += util/help.h
|
||||
LIB_H += util/session.h
|
||||
LIB_H += util/strbuf.h
|
||||
LIB_H += util/strlist.h
|
||||
LIB_H += util/strfilter.h
|
||||
LIB_H += util/svghelper.h
|
||||
LIB_H += util/tool.h
|
||||
LIB_H += util/run-command.h
|
||||
LIB_H += util/sigchain.h
|
||||
LIB_H += util/dso.h
|
||||
LIB_H += util/symbol.h
|
||||
LIB_H += util/color.h
|
||||
LIB_H += util/values.h
|
||||
LIB_H += util/sort.h
|
||||
LIB_H += util/hist.h
|
||||
LIB_H += util/thread.h
|
||||
LIB_H += util/thread_map.h
|
||||
LIB_H += util/trace-event.h
|
||||
LIB_H += util/probe-finder.h
|
||||
LIB_H += util/dwarf-aux.h
|
||||
LIB_H += util/probe-event.h
|
||||
LIB_H += util/pstack.h
|
||||
LIB_H += util/cpumap.h
|
||||
LIB_H += util/top.h
|
||||
LIB_H += $(ARCH_INCLUDE)
|
||||
LIB_H += util/cgroup.h
|
||||
LIB_H += $(LIB_INCLUDE)traceevent/event-parse.h
|
||||
LIB_H += util/target.h
|
||||
LIB_H += util/rblist.h
|
||||
LIB_H += util/intlist.h
|
||||
LIB_H += util/perf_regs.h
|
||||
LIB_H += util/unwind.h
|
||||
LIB_H += util/vdso.h
|
||||
LIB_H += ui/helpline.h
|
||||
LIB_H += ui/progress.h
|
||||
LIB_H += ui/util.h
|
||||
LIB_H += ui/ui.h
|
||||
|
||||
LIB_OBJS += $(OUTPUT)util/abspath.o
|
||||
LIB_OBJS += $(OUTPUT)util/alias.o
|
||||
LIB_OBJS += $(OUTPUT)util/annotate.o
|
||||
LIB_OBJS += $(OUTPUT)util/build-id.o
|
||||
LIB_OBJS += $(OUTPUT)util/config.o
|
||||
LIB_OBJS += $(OUTPUT)util/ctype.o
|
||||
LIB_OBJS += $(OUTPUT)util/sysfs.o
|
||||
LIB_OBJS += $(OUTPUT)util/pmu.o
|
||||
LIB_OBJS += $(OUTPUT)util/environment.o
|
||||
LIB_OBJS += $(OUTPUT)util/event.o
|
||||
LIB_OBJS += $(OUTPUT)util/evlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/evsel.o
|
||||
LIB_OBJS += $(OUTPUT)util/exec_cmd.o
|
||||
LIB_OBJS += $(OUTPUT)util/help.o
|
||||
LIB_OBJS += $(OUTPUT)util/levenshtein.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-options.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events.o
|
||||
LIB_OBJS += $(OUTPUT)util/path.o
|
||||
LIB_OBJS += $(OUTPUT)util/rbtree.o
|
||||
LIB_OBJS += $(OUTPUT)util/bitmap.o
|
||||
LIB_OBJS += $(OUTPUT)util/hweight.o
|
||||
LIB_OBJS += $(OUTPUT)util/run-command.o
|
||||
LIB_OBJS += $(OUTPUT)util/quote.o
|
||||
LIB_OBJS += $(OUTPUT)util/strbuf.o
|
||||
LIB_OBJS += $(OUTPUT)util/string.o
|
||||
LIB_OBJS += $(OUTPUT)util/strlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/strfilter.o
|
||||
LIB_OBJS += $(OUTPUT)util/top.o
|
||||
LIB_OBJS += $(OUTPUT)util/usage.o
|
||||
LIB_OBJS += $(OUTPUT)util/wrapper.o
|
||||
LIB_OBJS += $(OUTPUT)util/sigchain.o
|
||||
LIB_OBJS += $(OUTPUT)util/dso.o
|
||||
LIB_OBJS += $(OUTPUT)util/symbol.o
|
||||
LIB_OBJS += $(OUTPUT)util/symbol-elf.o
|
||||
LIB_OBJS += $(OUTPUT)util/color.o
|
||||
LIB_OBJS += $(OUTPUT)util/pager.o
|
||||
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
|
||||
LIB_OBJS += $(OUTPUT)util/thread.o
|
||||
LIB_OBJS += $(OUTPUT)util/thread_map.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events-flex.o
|
||||
LIB_OBJS += $(OUTPUT)util/parse-events-bison.o
|
||||
LIB_OBJS += $(OUTPUT)util/pmu-flex.o
|
||||
LIB_OBJS += $(OUTPUT)util/pmu-bison.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-read.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-info.o
|
||||
LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
|
||||
LIB_OBJS += $(OUTPUT)util/svghelper.o
|
||||
LIB_OBJS += $(OUTPUT)util/sort.o
|
||||
LIB_OBJS += $(OUTPUT)util/hist.o
|
||||
LIB_OBJS += $(OUTPUT)util/probe-event.o
|
||||
LIB_OBJS += $(OUTPUT)util/util.o
|
||||
LIB_OBJS += $(OUTPUT)util/xyarray.o
|
||||
LIB_OBJS += $(OUTPUT)util/cpumap.o
|
||||
LIB_OBJS += $(OUTPUT)util/cgroup.o
|
||||
LIB_OBJS += $(OUTPUT)util/target.o
|
||||
LIB_OBJS += $(OUTPUT)util/rblist.o
|
||||
LIB_OBJS += $(OUTPUT)util/intlist.o
|
||||
LIB_OBJS += $(OUTPUT)util/vdso.o
|
||||
LIB_OBJS += $(OUTPUT)util/stat.o
|
||||
LIB_OBJS += $(OUTPUT)util/record.o
|
||||
LIB_OBJS += $(OUTPUT)util/srcline.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)ui/setup.o
|
||||
LIB_OBJS += $(OUTPUT)ui/helpline.o
|
||||
LIB_OBJS += $(OUTPUT)ui/progress.o
|
||||
LIB_OBJS += $(OUTPUT)ui/util.o
|
||||
LIB_OBJS += $(OUTPUT)ui/hist.o
|
||||
LIB_OBJS += $(OUTPUT)ui/stdio/hist.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)arch/common.o
|
||||
|
||||
LIB_OBJS += $(OUTPUT)tests/parse-events.o
|
||||
LIB_OBJS += $(OUTPUT)tests/dso-data.o
|
||||
LIB_OBJS += $(OUTPUT)tests/attr.o
|
||||
LIB_OBJS += $(OUTPUT)tests/vmlinux-kallsyms.o
|
||||
LIB_OBJS += $(OUTPUT)tests/open-syscall.o
|
||||
LIB_OBJS += $(OUTPUT)tests/open-syscall-all-cpus.o
|
||||
LIB_OBJS += $(OUTPUT)tests/open-syscall-tp-fields.o
|
||||
LIB_OBJS += $(OUTPUT)tests/mmap-basic.o
|
||||
LIB_OBJS += $(OUTPUT)tests/perf-record.o
|
||||
LIB_OBJS += $(OUTPUT)tests/rdpmc.o
|
||||
LIB_OBJS += $(OUTPUT)tests/evsel-roundtrip-name.o
|
||||
LIB_OBJS += $(OUTPUT)tests/evsel-tp-sched.o
|
||||
LIB_OBJS += $(OUTPUT)tests/pmu.o
|
||||
LIB_OBJS += $(OUTPUT)tests/hists_link.o
|
||||
LIB_OBJS += $(OUTPUT)tests/python-use.o
|
||||
LIB_OBJS += $(OUTPUT)tests/bp_signal.o
|
||||
LIB_OBJS += $(OUTPUT)tests/bp_signal_overflow.o
|
||||
LIB_OBJS += $(OUTPUT)tests/task-exit.o
|
||||
LIB_OBJS += $(OUTPUT)tests/sw-clock.o
|
||||
ifeq ($(ARCH),x86)
|
||||
LIB_OBJS += $(OUTPUT)tests/perf-time-to-tsc.o
|
||||
endif
|
||||
LIB_OBJS += $(OUTPUT)tests/code-reading.o
|
||||
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
|
||||
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
|
||||
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
|
||||
# Benchmark modules
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
|
||||
ifeq ($(RAW_ARCH),x86_64)
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o
|
||||
endif
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o
|
||||
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-help.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-list.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-record.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-report.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-top.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-script.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
|
||||
BUILTIN_OBJS += $(OUTPUT)tests/builtin-test.o
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
|
||||
|
||||
PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
|
||||
|
||||
# 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...
|
||||
|
||||
-include arch/$(ARCH)/Makefile
|
||||
|
||||
ifneq ($(OUTPUT),)
|
||||
CFLAGS += -I$(OUTPUT)
|
||||
endif
|
||||
|
||||
ifdef NO_LIBELF
|
||||
EXTLIBS := $(filter-out -lelf,$(EXTLIBS))
|
||||
|
||||
# Remove ELF/DWARF dependent codes
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS))
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/probe-event.o,$(LIB_OBJS))
|
||||
LIB_OBJS := $(filter-out $(OUTPUT)util/probe-finder.o,$(LIB_OBJS))
|
||||
|
||||
BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
|
||||
|
||||
# Use minimal symbol handling
|
||||
LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
|
||||
|
||||
else # NO_LIBELF
|
||||
ifndef NO_DWARF
|
||||
LIB_OBJS += $(OUTPUT)util/probe-finder.o
|
||||
LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
|
||||
endif # NO_DWARF
|
||||
endif # NO_LIBELF
|
||||
|
||||
ifndef NO_LIBUNWIND
|
||||
LIB_OBJS += $(OUTPUT)util/unwind.o
|
||||
endif
|
||||
LIB_OBJS += $(OUTPUT)tests/keep-tracking.o
|
||||
|
||||
ifndef NO_LIBAUDIT
|
||||
BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
|
||||
endif
|
||||
|
||||
ifndef NO_SLANG
|
||||
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
|
||||
ALL_PROGRAMS += $(OUTPUT)libperf-gtk.so
|
||||
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/browser.o
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/hists.o
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/setup.o
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/util.o
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/helpline.o
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/progress.o
|
||||
GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o
|
||||
|
||||
install-gtk: $(OUTPUT)libperf-gtk.so
|
||||
$(call QUIET_INSTALL, 'GTK UI') \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \
|
||||
$(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)'
|
||||
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
|
||||
|
||||
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
|
||||
endif
|
||||
|
||||
ifndef NO_LIBNUMA
|
||||
BUILTIN_OBJS += $(OUTPUT)bench/numa.o
|
||||
endif
|
||||
|
||||
ifdef ASCIIDOC8
|
||||
export ASCIIDOC8
|
||||
endif
|
||||
|
||||
LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
|
||||
|
||||
export INSTALL SHELL_PATH
|
||||
|
||||
### Build rules
|
||||
|
||||
SHELL = $(SHELL_PATH)
|
||||
|
||||
all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
|
||||
|
||||
please_set_SHELL_PATH_to_a_more_modern_shell:
|
||||
@$$(:)
|
||||
|
||||
shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
|
||||
strip: $(PROGRAMS) $(OUTPUT)perf
|
||||
$(STRIP) $(STRIP_OPTS) $(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)"' \
|
||||
$(CFLAGS) -c $(filter %.c,$^) -o $@
|
||||
|
||||
$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
|
||||
$(BUILTIN_OBJS) $(LIBS) -o $@
|
||||
|
||||
$(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H)
|
||||
$(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $<
|
||||
|
||||
$(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS)
|
||||
$(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS)
|
||||
|
||||
$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-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 $(CFLAGS) \
|
||||
'-DPERF_HTML_PATH="$(htmldir_SQ)"' \
|
||||
'-DPERF_MAN_PATH="$(mandir_SQ)"' \
|
||||
'-DPERF_INFO_PATH="$(infodir_SQ)"' $<
|
||||
|
||||
$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
|
||||
|
||||
$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
|
||||
$(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
|
||||
|
||||
$(SCRIPTS) : % : %.sh
|
||||
$(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
|
||||
|
||||
# These can record PERF_VERSION
|
||||
$(OUTPUT)perf.o perf.spec \
|
||||
$(SCRIPTS) \
|
||||
: $(OUTPUT)PERF-VERSION-FILE
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
#
|
||||
# If a target does not match any of the later rules then prefix it by $(OUTPUT)
|
||||
# This makes targets like 'make O=/tmp/perf perf.o' work in a natural way.
|
||||
#
|
||||
ifneq ($(OUTPUT),)
|
||||
%.o: $(OUTPUT)%.o
|
||||
@echo " # Redirected target $@ => $(OUTPUT)$@"
|
||||
util/%.o: $(OUTPUT)util/%.o
|
||||
@echo " # Redirected target $@ => $(OUTPUT)$@"
|
||||
bench/%.o: $(OUTPUT)bench/%.o
|
||||
@echo " # Redirected target $@ => $(OUTPUT)$@"
|
||||
tests/%.o: $(OUTPUT)tests/%.o
|
||||
@echo " # Redirected target $@ => $(OUTPUT)$@"
|
||||
endif
|
||||
|
||||
# These two need to be here so that when O= is not used they take precedence
|
||||
# over the general rule for .o
|
||||
|
||||
$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
|
||||
|
||||
$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
|
||||
$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
|
||||
$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
|
||||
$(OUTPUT)%.o: %.S
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
|
||||
$(OUTPUT)%.s: %.S
|
||||
$(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
|
||||
|
||||
$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-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 $(CFLAGS) \
|
||||
'-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
|
||||
$<
|
||||
|
||||
$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-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 $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
|
||||
|
||||
$(OUTPUT)ui/setup.o: ui/setup.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DLIBDIR='"$(libdir_SQ)"' $<
|
||||
|
||||
$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
|
||||
|
||||
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(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 $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow -Wno-undef -Wno-switch-default $<
|
||||
|
||||
$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
|
||||
$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default $<
|
||||
|
||||
$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
|
||||
$(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 $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
|
||||
|
||||
$(OUTPUT)perf-%: %.o $(PERFLIBS)
|
||||
$(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
|
||||
|
||||
$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
|
||||
$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
|
||||
|
||||
# we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
|
||||
# we depend the various files onto their directories.
|
||||
DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(GTK_OBJS)
|
||||
DIRECTORY_DEPS += $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
|
||||
$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
|
||||
# In the second step, we make a rule to actually create these directories
|
||||
$(sort $(dir $(DIRECTORY_DEPS))):
|
||||
$(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
|
||||
|
||||
$(LIB_FILE): $(LIB_OBJS)
|
||||
$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
|
||||
|
||||
# libtraceevent.a
|
||||
TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch])
|
||||
|
||||
$(LIBTRACEEVENT): $(TE_SOURCES)
|
||||
$(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a
|
||||
|
||||
$(LIBTRACEEVENT)-clean:
|
||||
$(call QUIET_CLEAN, libtraceevent)
|
||||
@$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null
|
||||
|
||||
LIBLK_SOURCES = $(wildcard $(LK_PATH)*.[ch])
|
||||
|
||||
# if subdir is set, we've been called from above so target has been built
|
||||
# already
|
||||
$(LIBLK): $(LIBLK_SOURCES)
|
||||
ifeq ($(subdir),)
|
||||
$(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a
|
||||
endif
|
||||
|
||||
$(LIBLK)-clean:
|
||||
ifeq ($(subdir),)
|
||||
$(call QUIET_CLEAN, liblk)
|
||||
@$(MAKE) -C $(LK_DIR) O=$(OUTPUT) clean >/dev/null
|
||||
endif
|
||||
|
||||
help:
|
||||
@echo 'Perf make targets:'
|
||||
@echo ' doc - make *all* documentation (see below)'
|
||||
@echo ' man - make manpage documentation (access with man <foo>)'
|
||||
@echo ' html - make html documentation'
|
||||
@echo ' info - make GNU info documentation (access with info <foo>)'
|
||||
@echo ' pdf - make pdf documentation'
|
||||
@echo ' TAGS - use etags to make tag information for source browsing'
|
||||
@echo ' tags - use ctags to make tag information for source browsing'
|
||||
@echo ' cscope - use cscope to make interactive browsing database'
|
||||
@echo ''
|
||||
@echo 'Perf install targets:'
|
||||
@echo ' NOTE: documentation build requires asciidoc, xmlto packages to be installed'
|
||||
@echo ' HINT: use "make prefix=<path> <install target>" to install to a particular'
|
||||
@echo ' path like make prefix=/usr/local install install-doc'
|
||||
@echo ' install - install compiled binaries'
|
||||
@echo ' install-doc - install *all* documentation'
|
||||
@echo ' install-man - install manpage documentation'
|
||||
@echo ' install-html - install html documentation'
|
||||
@echo ' install-info - install GNU info documentation'
|
||||
@echo ' install-pdf - install pdf documentation'
|
||||
@echo ''
|
||||
@echo ' quick-install-doc - alias for quick-install-man'
|
||||
@echo ' quick-install-man - install the documentation quickly'
|
||||
@echo ' quick-install-html - install the html documentation quickly'
|
||||
@echo ''
|
||||
@echo 'Perf maintainer targets:'
|
||||
@echo ' clean - clean all binary objects and build output'
|
||||
|
||||
|
||||
DOC_TARGETS := doc man html info pdf
|
||||
|
||||
INSTALL_DOC_TARGETS := $(patsubst %,install-%,$(DOC_TARGETS)) try-install-man
|
||||
INSTALL_DOC_TARGETS += quick-install-doc quick-install-man quick-install-html
|
||||
|
||||
# 'make doc' should call 'make -C Documentation all'
|
||||
$(DOC_TARGETS):
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:doc=all)
|
||||
|
||||
TAGS:
|
||||
$(RM) TAGS
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs etags -a
|
||||
|
||||
tags:
|
||||
$(RM) tags
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs ctags -a
|
||||
|
||||
cscope:
|
||||
$(RM) cscope*
|
||||
$(FIND) . -name '*.[hcS]' -print | xargs cscope -b
|
||||
|
||||
### Detect prefix changes
|
||||
TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
|
||||
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
|
||||
|
||||
$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
|
||||
@FLAGS='$(TRACK_CFLAGS)'; \
|
||||
if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
|
||||
echo 1>&2 " FLAGS: * new build flags or prefix"; \
|
||||
echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
|
||||
fi
|
||||
|
||||
### Testing rules
|
||||
|
||||
# GNU make supports exporting all variables by "export" without parameters.
|
||||
# However, the environment gets quite big, and some programs have problems
|
||||
# with that.
|
||||
|
||||
check: $(OUTPUT)common-cmds.h
|
||||
if sparse; \
|
||||
then \
|
||||
for i in *.c */*.c; \
|
||||
do \
|
||||
sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
|
||||
done; \
|
||||
else \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
### Installation rules
|
||||
|
||||
install-gtk:
|
||||
|
||||
install-bin: all install-gtk
|
||||
$(call QUIET_INSTALL, binaries) \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'; \
|
||||
$(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \
|
||||
$(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace'
|
||||
$(call QUIET_INSTALL, libexec) \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
||||
$(call QUIET_INSTALL, perf-archive) \
|
||||
$(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
|
||||
ifndef NO_LIBPERL
|
||||
$(call QUIET_INSTALL, perl-scripts) \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
|
||||
$(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
|
||||
$(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \
|
||||
$(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
|
||||
endif
|
||||
ifndef NO_LIBPYTHON
|
||||
$(call QUIET_INSTALL, python-scripts) \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'; \
|
||||
$(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
|
||||
$(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \
|
||||
$(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
|
||||
endif
|
||||
$(call QUIET_INSTALL, bash_completion-script) \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \
|
||||
$(INSTALL) bash_completion '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
|
||||
$(call QUIET_INSTALL, tests) \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
|
||||
$(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
|
||||
$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
|
||||
$(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'
|
||||
|
||||
install: install-bin try-install-man
|
||||
|
||||
install-python_ext:
|
||||
$(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
|
||||
|
||||
# 'make install-doc' should call 'make -C Documentation install'
|
||||
$(INSTALL_DOC_TARGETS):
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=)
|
||||
|
||||
### Cleaning rules
|
||||
|
||||
#
|
||||
# This is here, not in config/Makefile, because config/Makefile does
|
||||
# not get included for the clean target:
|
||||
#
|
||||
config-clean:
|
||||
$(call QUIET_CLEAN, config)
|
||||
@$(MAKE) -C config/feature-checks clean >/dev/null
|
||||
|
||||
clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean
|
||||
$(call QUIET_CLEAN, core-objs) $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) $(GTK_OBJS)
|
||||
$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf
|
||||
$(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
|
||||
$(call QUIET_CLEAN, Documentation)
|
||||
@$(MAKE) -C Documentation O=$(OUTPUT) clean >/dev/null
|
||||
$(python-clean)
|
||||
|
||||
#
|
||||
# Trick: if ../../.git does not exist - we are building out of tree for example,
|
||||
# then force version regeneration:
|
||||
#
|
||||
ifeq ($(wildcard ../../.git/HEAD),)
|
||||
GIT-HEAD-PHONY = ../../.git/HEAD
|
||||
else
|
||||
GIT-HEAD-PHONY =
|
||||
endif
|
||||
|
||||
.PHONY: all install clean config-clean strip install-gtk
|
||||
.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
|
||||
.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "../../util/types.h"
|
||||
#include <asm/perf_regs.h>
|
||||
|
||||
#ifndef ARCH_X86_64
|
||||
#ifndef HAVE_ARCH_X86_64_SUPPORT
|
||||
#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
|
||||
#else
|
||||
#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
|
||||
@ -52,7 +52,7 @@ static inline const char *perf_reg_name(int id)
|
||||
return "FS";
|
||||
case PERF_REG_X86_GS:
|
||||
return "GS";
|
||||
#ifdef ARCH_X86_64
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
case PERF_REG_X86_R8:
|
||||
return "R8";
|
||||
case PERF_REG_X86_R9:
|
||||
@ -69,7 +69,7 @@ static inline const char *perf_reg_name(int id)
|
||||
return "R14";
|
||||
case PERF_REG_X86_R15:
|
||||
return "R15";
|
||||
#endif /* ARCH_X86_64 */
|
||||
#endif /* HAVE_ARCH_X86_64_SUPPORT */
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include "perf_regs.h"
|
||||
#include "../../util/unwind.h"
|
||||
|
||||
#ifdef ARCH_X86_64
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
int unwind__arch_reg_id(int regnum)
|
||||
{
|
||||
int id;
|
||||
@ -108,4 +108,4 @@ int unwind__arch_reg_id(int regnum)
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif /* ARCH_X86_64 */
|
||||
#endif /* HAVE_ARCH_X86_64_SUPPORT */
|
||||
|
@ -1,17 +1,87 @@
|
||||
# perf completion
|
||||
|
||||
function_exists()
|
||||
# Taken from git.git's completion script.
|
||||
__my_reassemble_comp_words_by_ref()
|
||||
{
|
||||
declare -F $1 > /dev/null
|
||||
return $?
|
||||
local exclude i j first
|
||||
# Which word separators to exclude?
|
||||
exclude="${1//[^$COMP_WORDBREAKS]}"
|
||||
cword_=$COMP_CWORD
|
||||
if [ -z "$exclude" ]; then
|
||||
words_=("${COMP_WORDS[@]}")
|
||||
return
|
||||
fi
|
||||
# List of word completion separators has shrunk;
|
||||
# re-assemble words to complete.
|
||||
for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
|
||||
# Append each nonempty word consisting of just
|
||||
# word separator characters to the current word.
|
||||
first=t
|
||||
while
|
||||
[ $i -gt 0 ] &&
|
||||
[ -n "${COMP_WORDS[$i]}" ] &&
|
||||
# word consists of excluded word separators
|
||||
[ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
|
||||
do
|
||||
# Attach to the previous token,
|
||||
# unless the previous token is the command name.
|
||||
if [ $j -ge 2 ] && [ -n "$first" ]; then
|
||||
((j--))
|
||||
fi
|
||||
first=
|
||||
words_[$j]=${words_[j]}${COMP_WORDS[i]}
|
||||
if [ $i = $COMP_CWORD ]; then
|
||||
cword_=$j
|
||||
fi
|
||||
if (($i < ${#COMP_WORDS[@]} - 1)); then
|
||||
((i++))
|
||||
else
|
||||
# Done.
|
||||
return
|
||||
fi
|
||||
done
|
||||
words_[$j]=${words_[j]}${COMP_WORDS[i]}
|
||||
if [ $i = $COMP_CWORD ]; then
|
||||
cword_=$j
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function_exists __ltrim_colon_completions ||
|
||||
type _get_comp_words_by_ref &>/dev/null ||
|
||||
_get_comp_words_by_ref()
|
||||
{
|
||||
local exclude cur_ words_ cword_
|
||||
if [ "$1" = "-n" ]; then
|
||||
exclude=$2
|
||||
shift 2
|
||||
fi
|
||||
__my_reassemble_comp_words_by_ref "$exclude"
|
||||
cur_=${words_[cword_]}
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
cur)
|
||||
cur=$cur_
|
||||
;;
|
||||
prev)
|
||||
prev=${words_[$cword_-1]}
|
||||
;;
|
||||
words)
|
||||
words=("${words_[@]}")
|
||||
;;
|
||||
cword)
|
||||
cword=$cword_
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
type __ltrim_colon_completions &>/dev/null ||
|
||||
__ltrim_colon_completions()
|
||||
{
|
||||
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
|
||||
# Remove colon-word prefix from COMPREPLY items
|
||||
local colon_word=${1%${1##*:}}
|
||||
local colon_word=${1%"${1##*:}"}
|
||||
local i=${#COMPREPLY[*]}
|
||||
while [[ $((--i)) -ge 0 ]]; do
|
||||
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
|
||||
@ -19,23 +89,18 @@ __ltrim_colon_completions()
|
||||
fi
|
||||
}
|
||||
|
||||
have perf &&
|
||||
type perf &>/dev/null &&
|
||||
_perf()
|
||||
{
|
||||
local cur prev cmd
|
||||
local cur words cword prev cmd
|
||||
|
||||
COMPREPLY=()
|
||||
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
|
||||
_get_comp_words_by_ref -n =: cur words cword prev
|
||||
|
||||
cmd=${COMP_WORDS[0]}
|
||||
cmd=${words[0]}
|
||||
|
||||
# List perf subcommands or long options
|
||||
if [ $COMP_CWORD -eq 1 ]; then
|
||||
if [ $cword -eq 1 ]; then
|
||||
if [[ $cur == --* ]]; then
|
||||
COMPREPLY=( $( compgen -W '--help --version \
|
||||
--exec-path --html-path --paginate --no-pager \
|
||||
@ -45,18 +110,17 @@ _perf()
|
||||
COMPREPLY=( $( compgen -W '$cmds' -- "$cur" ) )
|
||||
fi
|
||||
# List possible events for -e option
|
||||
elif [[ $prev == "-e" && "${COMP_WORDS[1]}" == @(record|stat|top) ]]; then
|
||||
elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
|
||||
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]}
|
||||
subcmd=${words[1]}
|
||||
opts=$($cmd $subcmd --list-opts)
|
||||
COMPREPLY=( $( compgen -W '$opts' -- "$cur" ) )
|
||||
# Fall down to list regular files
|
||||
else
|
||||
_filedir
|
||||
fi
|
||||
} &&
|
||||
complete -F _perf perf
|
||||
|
||||
complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \
|
||||
|| complete -o default -o nospace -F _perf perf
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
#ifdef ARCH_X86_64
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
|
||||
#define MEMCPY_FN(fn, name, desc) \
|
||||
extern void *fn(void *, const void *, size_t);
|
||||
|
@ -58,7 +58,7 @@ struct routine routines[] = {
|
||||
{ "default",
|
||||
"Default memcpy() provided by glibc",
|
||||
memcpy },
|
||||
#ifdef ARCH_X86_64
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
|
||||
#define MEMCPY_FN(fn, name, desc) { name, desc, fn },
|
||||
#include "mem-memcpy-x86-64-asm-def.h"
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
#ifdef ARCH_X86_64
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
|
||||
#define MEMSET_FN(fn, name, desc) \
|
||||
extern void *fn(void *, int, size_t);
|
||||
|
@ -58,7 +58,7 @@ static const struct routine routines[] = {
|
||||
{ "default",
|
||||
"Default memset() provided by glibc",
|
||||
memset },
|
||||
#ifdef ARCH_X86_64
|
||||
#ifdef HAVE_ARCH_X86_64_SUPPORT
|
||||
|
||||
#define MEMSET_FN(fn, name, desc) { name, desc, fn },
|
||||
#include "mem-memset-x86-64-asm-def.h"
|
||||
|
@ -429,14 +429,14 @@ static int parse_cpu_list(const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_setup_cpu_list(void)
|
||||
static int parse_setup_cpu_list(void)
|
||||
{
|
||||
struct thread_data *td;
|
||||
char *str0, *str;
|
||||
int t;
|
||||
|
||||
if (!g->p.cpu_list_str)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks);
|
||||
|
||||
@ -500,8 +500,12 @@ static void parse_setup_cpu_list(void)
|
||||
|
||||
dprintf("CPUs: %d_%d-%d#%dx%d\n", bind_cpu_0, bind_len, bind_cpu_1, step, mul);
|
||||
|
||||
BUG_ON(bind_cpu_0 < 0 || bind_cpu_0 >= g->p.nr_cpus);
|
||||
BUG_ON(bind_cpu_1 < 0 || bind_cpu_1 >= g->p.nr_cpus);
|
||||
if (bind_cpu_0 >= g->p.nr_cpus || bind_cpu_1 >= g->p.nr_cpus) {
|
||||
printf("\nTest not applicable, system has only %d CPUs.\n", g->p.nr_cpus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BUG_ON(bind_cpu_0 < 0 || bind_cpu_1 < 0);
|
||||
BUG_ON(bind_cpu_0 > bind_cpu_1);
|
||||
|
||||
for (bind_cpu = bind_cpu_0; bind_cpu <= bind_cpu_1; bind_cpu += step) {
|
||||
@ -541,6 +545,7 @@ static void parse_setup_cpu_list(void)
|
||||
printf("# NOTE: %d tasks bound, %d tasks unbound\n", t, g->p.nr_tasks - t);
|
||||
|
||||
free(str0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_cpus_opt(const struct option *opt __maybe_unused,
|
||||
@ -561,14 +566,14 @@ static int parse_node_list(const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void parse_setup_node_list(void)
|
||||
static int parse_setup_node_list(void)
|
||||
{
|
||||
struct thread_data *td;
|
||||
char *str0, *str;
|
||||
int t;
|
||||
|
||||
if (!g->p.node_list_str)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
dprintf("g->p.nr_tasks: %d\n", g->p.nr_tasks);
|
||||
|
||||
@ -619,8 +624,12 @@ static void parse_setup_node_list(void)
|
||||
|
||||
dprintf("NODEs: %d-%d #%d\n", bind_node_0, bind_node_1, step);
|
||||
|
||||
BUG_ON(bind_node_0 < 0 || bind_node_0 >= g->p.nr_nodes);
|
||||
BUG_ON(bind_node_1 < 0 || bind_node_1 >= g->p.nr_nodes);
|
||||
if (bind_node_0 >= g->p.nr_nodes || bind_node_1 >= g->p.nr_nodes) {
|
||||
printf("\nTest not applicable, system has only %d nodes.\n", g->p.nr_nodes);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BUG_ON(bind_node_0 < 0 || bind_node_1 < 0);
|
||||
BUG_ON(bind_node_0 > bind_node_1);
|
||||
|
||||
for (bind_node = bind_node_0; bind_node <= bind_node_1; bind_node += step) {
|
||||
@ -651,6 +660,7 @@ static void parse_setup_node_list(void)
|
||||
printf("# NOTE: %d tasks mem-bound, %d tasks unbound\n", t, g->p.nr_tasks - t);
|
||||
|
||||
free(str0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_nodes_opt(const struct option *opt __maybe_unused,
|
||||
@ -1356,8 +1366,8 @@ static int init(void)
|
||||
init_thread_data();
|
||||
|
||||
tprintf("#\n");
|
||||
parse_setup_cpu_list();
|
||||
parse_setup_node_list();
|
||||
if (parse_setup_cpu_list() || parse_setup_node_list())
|
||||
return -1;
|
||||
tprintf("#\n");
|
||||
|
||||
print_summary();
|
||||
@ -1600,7 +1610,6 @@ static int run_bench_numa(const char *name, const char **argv)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
usage_with_options(numa_usage, options);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1701,8 +1710,7 @@ static int bench_all(void)
|
||||
BUG_ON(ret < 0);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (run_bench_numa(tests[i][0], tests[i] + 1))
|
||||
return -1;
|
||||
run_bench_numa(tests[i][0], tests[i] + 1);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
@ -7,9 +7,7 @@
|
||||
* Based on pipe-test-1m.c by Ingo Molnar <mingo@redhat.com>
|
||||
* http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c
|
||||
* Ported to perf by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../perf.h"
|
||||
#include "../util/util.h"
|
||||
#include "../util/parse-options.h"
|
||||
@ -28,12 +26,24 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
struct thread_data {
|
||||
int nr;
|
||||
int pipe_read;
|
||||
int pipe_write;
|
||||
pthread_t pthread;
|
||||
};
|
||||
|
||||
#define LOOPS_DEFAULT 1000000
|
||||
static int loops = LOOPS_DEFAULT;
|
||||
static int loops = LOOPS_DEFAULT;
|
||||
|
||||
/* Use processes by default: */
|
||||
static bool threaded;
|
||||
|
||||
static const struct option options[] = {
|
||||
OPT_INTEGER('l', "loop", &loops,
|
||||
"Specify number of loops"),
|
||||
OPT_INTEGER('l', "loop", &loops, "Specify number of loops"),
|
||||
OPT_BOOLEAN('T', "threaded", &threaded, "Specify threads/process based task setup"),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
@ -42,13 +52,37 @@ static const char * const bench_sched_pipe_usage[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
int bench_sched_pipe(int argc, const char **argv,
|
||||
const char *prefix __maybe_unused)
|
||||
static void *worker_thread(void *__tdata)
|
||||
{
|
||||
int pipe_1[2], pipe_2[2];
|
||||
struct thread_data *td = __tdata;
|
||||
int m = 0, i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < loops; i++) {
|
||||
if (!td->nr) {
|
||||
ret = read(td->pipe_read, &m, sizeof(int));
|
||||
BUG_ON(ret != sizeof(int));
|
||||
ret = write(td->pipe_write, &m, sizeof(int));
|
||||
BUG_ON(ret != sizeof(int));
|
||||
} else {
|
||||
ret = write(td->pipe_write, &m, sizeof(int));
|
||||
BUG_ON(ret != sizeof(int));
|
||||
ret = read(td->pipe_read, &m, sizeof(int));
|
||||
BUG_ON(ret != sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bench_sched_pipe(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
{
|
||||
struct thread_data threads[2], *td;
|
||||
int pipe_1[2], pipe_2[2];
|
||||
struct timeval start, stop, diff;
|
||||
unsigned long long result_usec = 0;
|
||||
int nr_threads = 2;
|
||||
int t;
|
||||
|
||||
/*
|
||||
* why does "ret" exist?
|
||||
@ -58,43 +92,66 @@ int bench_sched_pipe(int argc, const char **argv,
|
||||
int __maybe_unused ret, wait_stat;
|
||||
pid_t pid, retpid __maybe_unused;
|
||||
|
||||
argc = parse_options(argc, argv, options,
|
||||
bench_sched_pipe_usage, 0);
|
||||
argc = parse_options(argc, argv, options, bench_sched_pipe_usage, 0);
|
||||
|
||||
BUG_ON(pipe(pipe_1));
|
||||
BUG_ON(pipe(pipe_2));
|
||||
|
||||
pid = fork();
|
||||
assert(pid >= 0);
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
|
||||
if (!pid) {
|
||||
for (i = 0; i < loops; i++) {
|
||||
ret = read(pipe_1[0], &m, sizeof(int));
|
||||
ret = write(pipe_2[1], &m, sizeof(int));
|
||||
for (t = 0; t < nr_threads; t++) {
|
||||
td = threads + t;
|
||||
|
||||
td->nr = t;
|
||||
|
||||
if (t == 0) {
|
||||
td->pipe_read = pipe_1[0];
|
||||
td->pipe_write = pipe_2[1];
|
||||
} else {
|
||||
td->pipe_write = pipe_1[1];
|
||||
td->pipe_read = pipe_2[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (threaded) {
|
||||
|
||||
for (t = 0; t < nr_threads; t++) {
|
||||
td = threads + t;
|
||||
|
||||
ret = pthread_create(&td->pthread, NULL, worker_thread, td);
|
||||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
for (t = 0; t < nr_threads; t++) {
|
||||
td = threads + t;
|
||||
|
||||
ret = pthread_join(td->pthread, NULL);
|
||||
BUG_ON(ret);
|
||||
}
|
||||
|
||||
} else {
|
||||
for (i = 0; i < loops; i++) {
|
||||
ret = write(pipe_1[1], &m, sizeof(int));
|
||||
ret = read(pipe_2[0], &m, sizeof(int));
|
||||
pid = fork();
|
||||
assert(pid >= 0);
|
||||
|
||||
if (!pid) {
|
||||
worker_thread(threads + 0);
|
||||
exit(0);
|
||||
} else {
|
||||
worker_thread(threads + 1);
|
||||
}
|
||||
|
||||
retpid = waitpid(pid, &wait_stat, 0);
|
||||
assert((retpid == pid) && WIFEXITED(wait_stat));
|
||||
}
|
||||
|
||||
gettimeofday(&stop, NULL);
|
||||
timersub(&stop, &start, &diff);
|
||||
|
||||
if (pid) {
|
||||
retpid = waitpid(pid, &wait_stat, 0);
|
||||
assert((retpid == pid) && WIFEXITED(wait_stat));
|
||||
} else {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
switch (bench_format) {
|
||||
case BENCH_FORMAT_DEFAULT:
|
||||
printf("# Executed %d pipe operations between two tasks\n\n",
|
||||
loops);
|
||||
printf("# Executed %d pipe operations between two %s\n\n",
|
||||
loops, threaded ? "threads" : "processes");
|
||||
|
||||
result_usec = diff.tv_sec * 1000000;
|
||||
result_usec += diff.tv_usec;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "util/tool.h"
|
||||
#include "arch/common.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <linux/bitmap.h>
|
||||
|
||||
struct perf_annotate {
|
||||
@ -142,8 +143,18 @@ static void hists__find_annotations(struct hists *self,
|
||||
|
||||
if (use_browser == 2) {
|
||||
int ret;
|
||||
int (*annotate)(struct hist_entry *he,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
|
||||
ret = hist_entry__gtk_annotate(he, evsel, NULL);
|
||||
annotate = dlsym(perf_gtk_handle,
|
||||
"hist_entry__gtk_annotate");
|
||||
if (annotate == NULL) {
|
||||
ui__error("GTK browser not found!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = annotate(he, evsel, NULL);
|
||||
if (!ret || !ann->skip_missing)
|
||||
return;
|
||||
|
||||
@ -247,8 +258,17 @@ static int __cmd_annotate(struct perf_annotate *ann)
|
||||
goto out_delete;
|
||||
}
|
||||
|
||||
if (use_browser == 2)
|
||||
perf_gtk__show_annotations();
|
||||
if (use_browser == 2) {
|
||||
void (*show_annotations)(void);
|
||||
|
||||
show_annotations = dlsym(perf_gtk_handle,
|
||||
"perf_gtk__show_annotations");
|
||||
if (show_annotations == NULL) {
|
||||
ui__error("GTK browser not found!\n");
|
||||
goto out_delete;
|
||||
}
|
||||
show_annotations();
|
||||
}
|
||||
|
||||
out_delete:
|
||||
/*
|
||||
|
@ -35,7 +35,7 @@ struct bench_suite {
|
||||
/* sentinel: easy for help */
|
||||
#define suite_all { "all", "Test all benchmark suites", NULL }
|
||||
|
||||
#ifdef LIBNUMA_SUPPORT
|
||||
#ifdef HAVE_LIBNUMA_SUPPORT
|
||||
static struct bench_suite numa_suites[] = {
|
||||
{ "mem",
|
||||
"Benchmark for NUMA workloads",
|
||||
@ -80,7 +80,7 @@ struct bench_subsys {
|
||||
};
|
||||
|
||||
static struct bench_subsys subsystems[] = {
|
||||
#ifdef LIBNUMA_SUPPORT
|
||||
#ifdef HAVE_LIBNUMA_SUPPORT
|
||||
{ "numa",
|
||||
"NUMA scheduling and MM behavior",
|
||||
numa_suites },
|
||||
|
@ -6,6 +6,11 @@
|
||||
* Copyright (C) 2010, Red Hat Inc.
|
||||
* Copyright (C) 2010, Arnaldo Carvalho de Melo <acme@redhat.com>
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include "builtin.h"
|
||||
#include "perf.h"
|
||||
#include "util/cache.h"
|
||||
@ -17,6 +22,140 @@
|
||||
#include "util/session.h"
|
||||
#include "util/symbol.h"
|
||||
|
||||
static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)
|
||||
{
|
||||
char root_dir[PATH_MAX];
|
||||
char notes[PATH_MAX];
|
||||
u8 build_id[BUILD_ID_SIZE];
|
||||
char *p;
|
||||
|
||||
strlcpy(root_dir, proc_dir, sizeof(root_dir));
|
||||
|
||||
p = strrchr(root_dir, '/');
|
||||
if (!p)
|
||||
return -1;
|
||||
*p = '\0';
|
||||
|
||||
scnprintf(notes, sizeof(notes), "%s/sys/kernel/notes", root_dir);
|
||||
|
||||
if (sysfs__read_build_id(notes, build_id, sizeof(build_id)))
|
||||
return -1;
|
||||
|
||||
build_id__sprintf(build_id, sizeof(build_id), sbuildid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int build_id_cache__kcore_dir(char *dir, size_t sz)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct tm tm;
|
||||
char dt[32];
|
||||
|
||||
if (gettimeofday(&tv, NULL) || !localtime_r(&tv.tv_sec, &tm))
|
||||
return -1;
|
||||
|
||||
if (!strftime(dt, sizeof(dt), "%Y%m%d%H%M%S", &tm))
|
||||
return -1;
|
||||
|
||||
scnprintf(dir, sz, "%s%02u", dt, (unsigned)tv.tv_usec / 10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,
|
||||
size_t to_dir_sz)
|
||||
{
|
||||
char from[PATH_MAX];
|
||||
char to[PATH_MAX];
|
||||
struct dirent *dent;
|
||||
int ret = -1;
|
||||
DIR *d;
|
||||
|
||||
d = opendir(to_dir);
|
||||
if (!d)
|
||||
return -1;
|
||||
|
||||
scnprintf(from, sizeof(from), "%s/modules", from_dir);
|
||||
|
||||
while (1) {
|
||||
dent = readdir(d);
|
||||
if (!dent)
|
||||
break;
|
||||
if (dent->d_type != DT_DIR)
|
||||
continue;
|
||||
scnprintf(to, sizeof(to), "%s/%s/modules", to_dir,
|
||||
dent->d_name);
|
||||
if (!compare_proc_modules(from, to)) {
|
||||
scnprintf(to, sizeof(to), "%s/%s", to_dir,
|
||||
dent->d_name);
|
||||
strlcpy(to_dir, to, to_dir_sz);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int build_id_cache__add_kcore(const char *filename, const char *debugdir)
|
||||
{
|
||||
char dir[32], sbuildid[BUILD_ID_SIZE * 2 + 1];
|
||||
char from_dir[PATH_MAX], to_dir[PATH_MAX];
|
||||
char *p;
|
||||
|
||||
strlcpy(from_dir, filename, sizeof(from_dir));
|
||||
|
||||
p = strrchr(from_dir, '/');
|
||||
if (!p || strcmp(p + 1, "kcore"))
|
||||
return -1;
|
||||
*p = '\0';
|
||||
|
||||
if (build_id_cache__kcore_buildid(from_dir, sbuildid))
|
||||
return -1;
|
||||
|
||||
scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s",
|
||||
debugdir, sbuildid);
|
||||
|
||||
if (!build_id_cache__kcore_existing(from_dir, to_dir, sizeof(to_dir))) {
|
||||
pr_debug("same kcore found in %s\n", to_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (build_id_cache__kcore_dir(dir, sizeof(dir)))
|
||||
return -1;
|
||||
|
||||
scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s/%s",
|
||||
debugdir, sbuildid, dir);
|
||||
|
||||
if (mkdir_p(to_dir, 0755))
|
||||
return -1;
|
||||
|
||||
if (kcore_copy(from_dir, to_dir)) {
|
||||
/* Remove YYYYmmddHHMMSShh directory */
|
||||
if (!rmdir(to_dir)) {
|
||||
p = strrchr(to_dir, '/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
/* Try to remove buildid directory */
|
||||
if (!rmdir(to_dir)) {
|
||||
p = strrchr(to_dir, '/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
/* Try to remove [kernel.kcore] directory */
|
||||
rmdir(to_dir);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
pr_debug("kcore added to build-id cache directory %s\n", to_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int build_id_cache__add_file(const char *filename, const char *debugdir)
|
||||
{
|
||||
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
|
||||
@ -130,11 +269,14 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
char const *add_name_list_str = NULL,
|
||||
*remove_name_list_str = NULL,
|
||||
*missing_filename = NULL,
|
||||
*update_name_list_str = NULL;
|
||||
*update_name_list_str = NULL,
|
||||
*kcore_filename;
|
||||
|
||||
const struct option buildid_cache_options[] = {
|
||||
OPT_STRING('a', "add", &add_name_list_str,
|
||||
"file list", "file(s) to add"),
|
||||
OPT_STRING('k', "kcore", &kcore_filename,
|
||||
"file", "kcore file to add"),
|
||||
OPT_STRING('r', "remove", &remove_name_list_str, "file list",
|
||||
"file(s) to remove"),
|
||||
OPT_STRING('M', "missing", &missing_filename, "file",
|
||||
@ -217,5 +359,9 @@ int cmd_buildid_cache(int argc, const char **argv,
|
||||
}
|
||||
}
|
||||
|
||||
if (kcore_filename &&
|
||||
build_id_cache__add_kcore(kcore_filename, debugdir))
|
||||
pr_warning("Couldn't add %s\n", kcore_filename);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ static int perf_event__inject_buildid(struct perf_tool *tool,
|
||||
* account this as unresolved.
|
||||
*/
|
||||
} else {
|
||||
#ifdef LIBELF_SUPPORT
|
||||
#ifdef HAVE_LIBELF_SUPPORT
|
||||
pr_warning("no symbols found in %s, maybe "
|
||||
"install a debug package?\n",
|
||||
al.map->dso->long_name);
|
||||
|
@ -1426,8 +1426,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
||||
const struct option live_options[] = {
|
||||
OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
|
||||
"record events on existing process id"),
|
||||
OPT_UINTEGER('m', "mmap-pages", &kvm->opts.mmap_pages,
|
||||
"number of mmap data pages"),
|
||||
OPT_CALLBACK('m', "mmap-pages", &kvm->opts.mmap_pages, "pages",
|
||||
"number of mmap data pages",
|
||||
perf_evlist__parse_mmap_pages),
|
||||
OPT_INCR('v', "verbose", &verbose,
|
||||
"be more verbose (show counter open errors, etc)"),
|
||||
OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
|
||||
|
@ -56,7 +56,9 @@ struct lock_stat {
|
||||
|
||||
unsigned int nr_readlock;
|
||||
unsigned int nr_trylock;
|
||||
|
||||
/* these times are in nano sec. */
|
||||
u64 avg_wait_time;
|
||||
u64 wait_time_total;
|
||||
u64 wait_time_min;
|
||||
u64 wait_time_max;
|
||||
@ -208,6 +210,7 @@ static struct thread_stat *thread_stat_findnew_first(u32 tid)
|
||||
|
||||
SINGLE_KEY(nr_acquired)
|
||||
SINGLE_KEY(nr_contended)
|
||||
SINGLE_KEY(avg_wait_time)
|
||||
SINGLE_KEY(wait_time_total)
|
||||
SINGLE_KEY(wait_time_max)
|
||||
|
||||
@ -244,6 +247,7 @@ static struct rb_root result; /* place to store sorted data */
|
||||
struct lock_key keys[] = {
|
||||
DEF_KEY_LOCK(acquired, nr_acquired),
|
||||
DEF_KEY_LOCK(contended, nr_contended),
|
||||
DEF_KEY_LOCK(avg_wait, avg_wait_time),
|
||||
DEF_KEY_LOCK(wait_total, wait_time_total),
|
||||
DEF_KEY_LOCK(wait_min, wait_time_min),
|
||||
DEF_KEY_LOCK(wait_max, wait_time_max),
|
||||
@ -321,10 +325,12 @@ static struct lock_stat *lock_stat_findnew(void *addr, const char *name)
|
||||
|
||||
new->addr = addr;
|
||||
new->name = zalloc(sizeof(char) * strlen(name) + 1);
|
||||
if (!new->name)
|
||||
if (!new->name) {
|
||||
free(new);
|
||||
goto alloc_failed;
|
||||
strcpy(new->name, name);
|
||||
}
|
||||
|
||||
strcpy(new->name, name);
|
||||
new->wait_time_min = ULLONG_MAX;
|
||||
|
||||
list_add(&new->hash_entry, entry);
|
||||
@ -400,17 +406,17 @@ static int report_lock_acquire_event(struct perf_evsel *evsel,
|
||||
|
||||
ls = lock_stat_findnew(addr, name);
|
||||
if (!ls)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
if (ls->discard)
|
||||
return 0;
|
||||
|
||||
ts = thread_stat_findnew(sample->tid);
|
||||
if (!ts)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
seq = get_seq(ts, addr);
|
||||
if (!seq)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
switch (seq->state) {
|
||||
case SEQ_STATE_UNINITIALIZED:
|
||||
@ -446,7 +452,6 @@ static int report_lock_acquire_event(struct perf_evsel *evsel,
|
||||
list_del(&seq->list);
|
||||
free(seq);
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
BUG_ON("Unknown state of lock sequence found!\n");
|
||||
break;
|
||||
@ -473,17 +478,17 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
|
||||
|
||||
ls = lock_stat_findnew(addr, name);
|
||||
if (!ls)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
if (ls->discard)
|
||||
return 0;
|
||||
|
||||
ts = thread_stat_findnew(sample->tid);
|
||||
if (!ts)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
seq = get_seq(ts, addr);
|
||||
if (!seq)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
switch (seq->state) {
|
||||
case SEQ_STATE_UNINITIALIZED:
|
||||
@ -508,8 +513,6 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
|
||||
list_del(&seq->list);
|
||||
free(seq);
|
||||
goto end;
|
||||
break;
|
||||
|
||||
default:
|
||||
BUG_ON("Unknown state of lock sequence found!\n");
|
||||
break;
|
||||
@ -517,6 +520,7 @@ static int report_lock_acquired_event(struct perf_evsel *evsel,
|
||||
|
||||
seq->state = SEQ_STATE_ACQUIRED;
|
||||
ls->nr_acquired++;
|
||||
ls->avg_wait_time = ls->nr_contended ? ls->wait_time_total/ls->nr_contended : 0;
|
||||
seq->prev_event_time = sample->time;
|
||||
end:
|
||||
return 0;
|
||||
@ -536,17 +540,17 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
|
||||
|
||||
ls = lock_stat_findnew(addr, name);
|
||||
if (!ls)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
if (ls->discard)
|
||||
return 0;
|
||||
|
||||
ts = thread_stat_findnew(sample->tid);
|
||||
if (!ts)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
seq = get_seq(ts, addr);
|
||||
if (!seq)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
switch (seq->state) {
|
||||
case SEQ_STATE_UNINITIALIZED:
|
||||
@ -564,7 +568,6 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
|
||||
list_del(&seq->list);
|
||||
free(seq);
|
||||
goto end;
|
||||
break;
|
||||
default:
|
||||
BUG_ON("Unknown state of lock sequence found!\n");
|
||||
break;
|
||||
@ -572,6 +575,7 @@ static int report_lock_contended_event(struct perf_evsel *evsel,
|
||||
|
||||
seq->state = SEQ_STATE_CONTENDED;
|
||||
ls->nr_contended++;
|
||||
ls->avg_wait_time = ls->wait_time_total/ls->nr_contended;
|
||||
seq->prev_event_time = sample->time;
|
||||
end:
|
||||
return 0;
|
||||
@ -591,22 +595,21 @@ static int report_lock_release_event(struct perf_evsel *evsel,
|
||||
|
||||
ls = lock_stat_findnew(addr, name);
|
||||
if (!ls)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
if (ls->discard)
|
||||
return 0;
|
||||
|
||||
ts = thread_stat_findnew(sample->tid);
|
||||
if (!ts)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
seq = get_seq(ts, addr);
|
||||
if (!seq)
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
|
||||
switch (seq->state) {
|
||||
case SEQ_STATE_UNINITIALIZED:
|
||||
goto end;
|
||||
break;
|
||||
case SEQ_STATE_ACQUIRED:
|
||||
break;
|
||||
case SEQ_STATE_READ_ACQUIRED:
|
||||
@ -624,7 +627,6 @@ static int report_lock_release_event(struct perf_evsel *evsel,
|
||||
ls->discard = 1;
|
||||
bad_hist[BROKEN_RELEASE]++;
|
||||
goto free_seq;
|
||||
break;
|
||||
default:
|
||||
BUG_ON("Unknown state of lock sequence found!\n");
|
||||
break;
|
||||
@ -690,7 +692,7 @@ static void print_bad_events(int bad, int total)
|
||||
|
||||
pr_info("\n=== output for debug===\n\n");
|
||||
pr_info("bad: %d, total: %d\n", bad, total);
|
||||
pr_info("bad rate: %f %%\n", (double)bad / (double)total * 100);
|
||||
pr_info("bad rate: %.2f %%\n", (double)bad / (double)total * 100);
|
||||
pr_info("histogram of events caused bad sequence\n");
|
||||
for (i = 0; i < BROKEN_MAX; i++)
|
||||
pr_info(" %10s: %d\n", name[i], bad_hist[i]);
|
||||
@ -707,6 +709,7 @@ static void print_result(void)
|
||||
pr_info("%10s ", "acquired");
|
||||
pr_info("%10s ", "contended");
|
||||
|
||||
pr_info("%15s ", "avg wait (ns)");
|
||||
pr_info("%15s ", "total wait (ns)");
|
||||
pr_info("%15s ", "max wait (ns)");
|
||||
pr_info("%15s ", "min wait (ns)");
|
||||
@ -738,6 +741,7 @@ static void print_result(void)
|
||||
pr_info("%10u ", st->nr_acquired);
|
||||
pr_info("%10u ", st->nr_contended);
|
||||
|
||||
pr_info("%15" PRIu64 " ", st->avg_wait_time);
|
||||
pr_info("%15" PRIu64 " ", st->wait_time_total);
|
||||
pr_info("%15" PRIu64 " ", st->wait_time_max);
|
||||
pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ?
|
||||
@ -822,34 +826,6 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct perf_evsel_str_handler lock_tracepoints[] = {
|
||||
{ "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
|
||||
{ "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_contended", perf_evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
|
||||
};
|
||||
|
||||
static int read_events(void)
|
||||
{
|
||||
struct perf_tool eops = {
|
||||
.sample = process_sample_event,
|
||||
.comm = perf_event__process_comm,
|
||||
.ordered_samples = true,
|
||||
};
|
||||
session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
|
||||
if (!session) {
|
||||
pr_err("Initializing perf session failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
|
||||
pr_err("Initializing perf session tracepoint handlers failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return perf_session__process_events(session, &eops);
|
||||
}
|
||||
|
||||
static void sort_result(void)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -862,18 +838,54 @@ static void sort_result(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int __cmd_report(void)
|
||||
static const struct perf_evsel_str_handler lock_tracepoints[] = {
|
||||
{ "lock:lock_acquire", perf_evsel__process_lock_acquire, }, /* CONFIG_LOCKDEP */
|
||||
{ "lock:lock_acquired", perf_evsel__process_lock_acquired, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_contended", perf_evsel__process_lock_contended, }, /* CONFIG_LOCKDEP, CONFIG_LOCK_STAT */
|
||||
{ "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
|
||||
};
|
||||
|
||||
static int __cmd_report(bool display_info)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
struct perf_tool eops = {
|
||||
.sample = process_sample_event,
|
||||
.comm = perf_event__process_comm,
|
||||
.ordered_samples = true,
|
||||
};
|
||||
|
||||
session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
|
||||
if (!session) {
|
||||
pr_err("Initializing perf session failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!perf_session__has_traces(session, "lock record"))
|
||||
goto out_delete;
|
||||
|
||||
if (perf_session__set_tracepoints_handlers(session, lock_tracepoints)) {
|
||||
pr_err("Initializing perf session tracepoint handlers failed\n");
|
||||
goto out_delete;
|
||||
}
|
||||
|
||||
if (select_key())
|
||||
goto out_delete;
|
||||
|
||||
err = perf_session__process_events(session, &eops);
|
||||
if (err)
|
||||
goto out_delete;
|
||||
|
||||
setup_pager();
|
||||
if (display_info) /* used for info subcommand */
|
||||
err = dump_info();
|
||||
else {
|
||||
sort_result();
|
||||
print_result();
|
||||
}
|
||||
|
||||
if ((select_key() != 0) ||
|
||||
(read_events() != 0))
|
||||
return -1;
|
||||
|
||||
sort_result();
|
||||
print_result();
|
||||
|
||||
return 0;
|
||||
out_delete:
|
||||
perf_session__delete(session);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __cmd_record(int argc, const char **argv)
|
||||
@ -881,7 +893,7 @@ static int __cmd_record(int argc, const char **argv)
|
||||
const char *record_args[] = {
|
||||
"record", "-R", "-m", "1024", "-c", "1",
|
||||
};
|
||||
unsigned int rec_argc, i, j;
|
||||
unsigned int rec_argc, i, j, ret;
|
||||
const char **rec_argv;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(lock_tracepoints); i++) {
|
||||
@ -898,7 +910,7 @@ static int __cmd_record(int argc, const char **argv)
|
||||
rec_argc += 2 * ARRAY_SIZE(lock_tracepoints);
|
||||
|
||||
rec_argv = calloc(rec_argc + 1, sizeof(char *));
|
||||
if (rec_argv == NULL)
|
||||
if (!rec_argv)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(record_args); i++)
|
||||
@ -914,7 +926,9 @@ static int __cmd_record(int argc, const char **argv)
|
||||
|
||||
BUG_ON(i != rec_argc);
|
||||
|
||||
return cmd_record(i, rec_argv, NULL);
|
||||
ret = cmd_record(i, rec_argv, NULL);
|
||||
free(rec_argv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
@ -934,7 +948,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
};
|
||||
const struct option report_options[] = {
|
||||
OPT_STRING('k', "key", &sort_key, "acquired",
|
||||
"key for sorting (acquired / contended / wait_total / wait_max / wait_min)"),
|
||||
"key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
|
||||
/* TODO: type */
|
||||
OPT_END()
|
||||
};
|
||||
@ -972,7 +986,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
if (argc)
|
||||
usage_with_options(report_usage, report_options);
|
||||
}
|
||||
__cmd_report();
|
||||
rc = __cmd_report(false);
|
||||
} else if (!strcmp(argv[0], "script")) {
|
||||
/* Aliased to 'perf script' */
|
||||
return cmd_script(argc, argv, prefix);
|
||||
@ -985,11 +999,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
}
|
||||
/* recycling report_lock_ops */
|
||||
trace_handler = &report_lock_ops;
|
||||
setup_pager();
|
||||
if (read_events() != 0)
|
||||
rc = -1;
|
||||
else
|
||||
rc = dump_info();
|
||||
rc = __cmd_report(true);
|
||||
} else {
|
||||
usage_with_options(lock_usage, lock_options);
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ static int opt_set_target(const struct option *opt, const char *str,
|
||||
if (str && !params.target) {
|
||||
if (!strcmp(opt->long_name, "exec"))
|
||||
params.uprobes = true;
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
else if (!strcmp(opt->long_name, "module"))
|
||||
params.uprobes = false;
|
||||
#endif
|
||||
@ -187,7 +187,7 @@ static int opt_set_target(const struct option *opt, const char *str,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
static int opt_show_lines(const struct option *opt __maybe_unused,
|
||||
const char *str, int unset __maybe_unused)
|
||||
{
|
||||
@ -257,7 +257,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
|
||||
"perf probe [<options>] --del '[GROUP:]EVENT' ...",
|
||||
"perf probe --list",
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
"perf probe [<options>] --line 'LINEDESC'",
|
||||
"perf probe [<options>] --vars 'PROBEPOINT'",
|
||||
#endif
|
||||
@ -271,7 +271,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
OPT_CALLBACK('d', "del", NULL, "[GROUP:]EVENT", "delete a probe event.",
|
||||
opt_del_probe_event),
|
||||
OPT_CALLBACK('a', "add", NULL,
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
"[EVENT=]FUNC[@SRC][+OFF|%return|:RL|;PT]|SRC:AL|SRC;PT"
|
||||
" [[NAME=]ARG ...]",
|
||||
#else
|
||||
@ -283,7 +283,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"\t\tFUNC:\tFunction name\n"
|
||||
"\t\tOFF:\tOffset from function entry (in byte)\n"
|
||||
"\t\t%return:\tPut the probe at function return\n"
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
"\t\tSRC:\tSource code path\n"
|
||||
"\t\tRL:\tRelative line number from function entry.\n"
|
||||
"\t\tAL:\tAbsolute line number in file.\n"
|
||||
@ -296,7 +296,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
opt_add_probe_event),
|
||||
OPT_BOOLEAN('f', "force", ¶ms.force_add, "forcibly add events"
|
||||
" with existing name"),
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
OPT_CALLBACK('L', "line", NULL,
|
||||
"FUNC[:RLN[+NUM|-RLN2]]|SRC:ALN[+NUM|-ALN2]",
|
||||
"Show source code lines.", opt_show_lines),
|
||||
@ -408,7 +408,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
if (params.show_lines && !params.uprobes) {
|
||||
if (params.mod_events) {
|
||||
pr_err(" Error: Don't use --line with"
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <sched.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifndef HAVE_ON_EXIT
|
||||
#ifndef HAVE_ON_EXIT_SUPPORT
|
||||
#ifndef ATEXIT_MAX
|
||||
#define ATEXIT_MAX 32
|
||||
#endif
|
||||
@ -70,7 +70,6 @@ struct perf_record {
|
||||
struct perf_session *session;
|
||||
const char *progname;
|
||||
int output;
|
||||
unsigned int page_size;
|
||||
int realtime_prio;
|
||||
bool no_buildid;
|
||||
bool no_buildid_cache;
|
||||
@ -119,7 +118,7 @@ static int perf_record__mmap_read(struct perf_record *rec,
|
||||
{
|
||||
unsigned int head = perf_mmap__read_head(md);
|
||||
unsigned int old = md->prev;
|
||||
unsigned char *data = md->base + rec->page_size;
|
||||
unsigned char *data = md->base + page_size;
|
||||
unsigned long size;
|
||||
void *buf;
|
||||
int rc = 0;
|
||||
@ -234,10 +233,6 @@ static int perf_record__open(struct perf_record *rec)
|
||||
"or try again with a smaller value of -m/--mmap_pages.\n"
|
||||
"(current value: %d)\n", opts->mmap_pages);
|
||||
rc = -errno;
|
||||
} else if (!is_power_of_2(opts->mmap_pages) &&
|
||||
(opts->mmap_pages != UINT_MAX)) {
|
||||
pr_err("--mmap_pages/-m value must be a power of two.");
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno));
|
||||
rc = -errno;
|
||||
@ -360,8 +355,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||
|
||||
rec->progname = argv[0];
|
||||
|
||||
rec->page_size = sysconf(_SC_PAGE_SIZE);
|
||||
|
||||
on_exit(perf_record__sig_exit, rec);
|
||||
signal(SIGCHLD, sig_handler);
|
||||
signal(SIGINT, sig_handler);
|
||||
@ -687,7 +680,7 @@ parse_branch_stack(const struct option *opt, const char *str, int unset)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef LIBUNWIND_SUPPORT
|
||||
#ifdef HAVE_LIBUNWIND_SUPPORT
|
||||
static int get_stack_size(char *str, unsigned long *_size)
|
||||
{
|
||||
char *endptr;
|
||||
@ -713,7 +706,7 @@ static int get_stack_size(char *str, unsigned long *_size)
|
||||
max_size, str);
|
||||
return -1;
|
||||
}
|
||||
#endif /* LIBUNWIND_SUPPORT */
|
||||
#endif /* HAVE_LIBUNWIND_SUPPORT */
|
||||
|
||||
int record_parse_callchain_opt(const struct option *opt,
|
||||
const char *arg, int unset)
|
||||
@ -751,7 +744,7 @@ int record_parse_callchain_opt(const struct option *opt,
|
||||
"needed for -g fp\n");
|
||||
break;
|
||||
|
||||
#ifdef LIBUNWIND_SUPPORT
|
||||
#ifdef HAVE_LIBUNWIND_SUPPORT
|
||||
/* Dwarf style */
|
||||
} else if (!strncmp(name, "dwarf", sizeof("dwarf"))) {
|
||||
const unsigned long default_stack_dump_size = 8192;
|
||||
@ -771,7 +764,7 @@ int record_parse_callchain_opt(const struct option *opt,
|
||||
if (!ret)
|
||||
pr_debug("callchain: stack dump size %d\n",
|
||||
opts->stack_dump_size);
|
||||
#endif /* LIBUNWIND_SUPPORT */
|
||||
#endif /* HAVE_LIBUNWIND_SUPPORT */
|
||||
} else {
|
||||
pr_err("callchain: Unknown -g option "
|
||||
"value: %s\n", arg);
|
||||
@ -818,7 +811,7 @@ static struct perf_record record = {
|
||||
|
||||
#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
|
||||
|
||||
#ifdef LIBUNWIND_SUPPORT
|
||||
#ifdef HAVE_LIBUNWIND_SUPPORT
|
||||
const char record_callchain_help[] = CALLCHAIN_HELP "[fp] dwarf";
|
||||
#else
|
||||
const char record_callchain_help[] = CALLCHAIN_HELP "[fp]";
|
||||
@ -857,8 +850,9 @@ const struct option record_options[] = {
|
||||
OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
|
||||
"child tasks do not inherit counters"),
|
||||
OPT_UINTEGER('F', "freq", &record.opts.user_freq, "profile at this frequency"),
|
||||
OPT_UINTEGER('m', "mmap-pages", &record.opts.mmap_pages,
|
||||
"number of mmap data pages"),
|
||||
OPT_CALLBACK('m', "mmap-pages", &record.opts.mmap_pages, "pages",
|
||||
"number of mmap data pages",
|
||||
perf_evlist__parse_mmap_pages),
|
||||
OPT_BOOLEAN(0, "group", &record.opts.group,
|
||||
"put the counters into a counter group"),
|
||||
OPT_CALLBACK_DEFAULT('g', "call-graph", &record.opts,
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "util/hist.h"
|
||||
#include "arch/common.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <linux/bitmap.h>
|
||||
|
||||
struct perf_report {
|
||||
@ -591,8 +592,19 @@ static int __cmd_report(struct perf_report *rep)
|
||||
ret = 0;
|
||||
|
||||
} else if (use_browser == 2) {
|
||||
perf_evlist__gtk_browse_hists(session->evlist, help,
|
||||
NULL, rep->min_percent);
|
||||
int (*hist_browser)(struct perf_evlist *,
|
||||
const char *,
|
||||
struct hist_browser_timer *,
|
||||
float min_pcnt);
|
||||
|
||||
hist_browser = dlsym(perf_gtk_handle,
|
||||
"perf_evlist__gtk_browse_hists");
|
||||
if (hist_browser == NULL) {
|
||||
ui__error("GTK browser not found!\n");
|
||||
return ret;
|
||||
}
|
||||
hist_browser(session->evlist, help, NULL,
|
||||
rep->min_percent);
|
||||
}
|
||||
} else
|
||||
perf_evlist__tty_browse_hists(session->evlist, rep, help);
|
||||
|
@ -706,10 +706,13 @@ static void nsec_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
|
||||
{
|
||||
double msecs = avg / 1e6;
|
||||
const char *fmt = csv_output ? "%.6f%s%s" : "%18.6f%s%-25s";
|
||||
char name[25];
|
||||
|
||||
aggr_printout(evsel, cpu, nr);
|
||||
|
||||
fprintf(output, fmt, msecs, csv_sep, perf_evsel__name(evsel));
|
||||
scnprintf(name, sizeof(name), "%s%s",
|
||||
perf_evsel__name(evsel), csv_output ? "" : " (msec)");
|
||||
fprintf(output, fmt, msecs, csv_sep, name);
|
||||
|
||||
if (evsel->cgrp)
|
||||
fprintf(output, "%s%s", csv_sep, evsel->cgrp->name);
|
||||
@ -930,11 +933,10 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
|
||||
|
||||
if (perf_evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
|
||||
total = avg_stats(&runtime_cycles_stats[cpu]);
|
||||
if (total)
|
||||
if (total) {
|
||||
ratio = avg / total;
|
||||
|
||||
fprintf(output, " # %5.2f insns per cycle ", ratio);
|
||||
|
||||
fprintf(output, " # %5.2f insns per cycle ", ratio);
|
||||
}
|
||||
total = avg_stats(&runtime_stalled_cycles_front_stats[cpu]);
|
||||
total = max(total, avg_stats(&runtime_stalled_cycles_back_stats[cpu]));
|
||||
|
||||
@ -997,10 +999,10 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
|
||||
} else if (perf_evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
|
||||
total = avg_stats(&runtime_nsecs_stats[cpu]);
|
||||
|
||||
if (total)
|
||||
ratio = 1.0 * avg / total;
|
||||
|
||||
fprintf(output, " # %8.3f GHz ", ratio);
|
||||
if (total) {
|
||||
ratio = avg / total;
|
||||
fprintf(output, " # %8.3f GHz ", ratio);
|
||||
}
|
||||
} else if (transaction_run &&
|
||||
perf_evsel__cmp(evsel, nth_evsel(T_CYCLES_IN_TX))) {
|
||||
total = avg_stats(&runtime_cycles_stats[cpu]);
|
||||
@ -1230,7 +1232,11 @@ static void print_stat(int argc, const char **argv)
|
||||
if (!csv_output) {
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, " Performance counter stats for ");
|
||||
if (!perf_target__has_task(&target)) {
|
||||
if (target.system_wide)
|
||||
fprintf(output, "\'system wide");
|
||||
else if (target.cpu_list)
|
||||
fprintf(output, "\'CPU(s) %s", target.cpu_list);
|
||||
else if (!perf_target__has_task(&target)) {
|
||||
fprintf(output, "\'%s", argv[0]);
|
||||
for (i = 1; i < argc; i++)
|
||||
fprintf(output, " %s", argv[i]);
|
||||
@ -1656,8 +1662,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
} else if (big_num_opt == 0) /* User passed --no-big-num */
|
||||
big_num = false;
|
||||
|
||||
if (!argc && !perf_target__has_task(&target))
|
||||
if (!argc && perf_target__none(&target))
|
||||
usage_with_options(stat_usage, options);
|
||||
|
||||
if (run_count < 0) {
|
||||
usage_with_options(stat_usage, options);
|
||||
} else if (run_count == 0) {
|
||||
|
@ -1073,10 +1073,13 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"list of cpus to monitor"),
|
||||
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
|
||||
"file", "vmlinux pathname"),
|
||||
OPT_BOOLEAN(0, "ignore-vmlinux", &symbol_conf.ignore_vmlinux,
|
||||
"don't load vmlinux even if found"),
|
||||
OPT_BOOLEAN('K', "hide_kernel_symbols", &top.hide_kernel_symbols,
|
||||
"hide kernel symbols"),
|
||||
OPT_UINTEGER('m', "mmap-pages", &opts->mmap_pages,
|
||||
"number of mmap data pages"),
|
||||
OPT_CALLBACK('m', "mmap-pages", &opts->mmap_pages, "pages",
|
||||
"number of mmap data pages",
|
||||
perf_evlist__parse_mmap_pages),
|
||||
OPT_INTEGER('r', "realtime", &top.realtime_prio,
|
||||
"collect data with this RT SCHED_FIFO priority"),
|
||||
OPT_INTEGER('d', "delay", &top.delay_secs,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,7 +23,7 @@ ifeq ($(ARCH),x86_64)
|
||||
endif
|
||||
ifeq (${IS_X86_64}, 1)
|
||||
RAW_ARCH := x86_64
|
||||
CFLAGS += -DARCH_X86_64
|
||||
CFLAGS += -DHAVE_ARCH_X86_64_SUPPORT
|
||||
ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
|
||||
endif
|
||||
NO_PERF_REGS := 0
|
||||
@ -31,7 +31,7 @@ ifeq ($(ARCH),x86_64)
|
||||
endif
|
||||
|
||||
ifeq ($(NO_PERF_REGS),0)
|
||||
CFLAGS += -DHAVE_PERF_REGS
|
||||
CFLAGS += -DHAVE_PERF_REGS_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(src-perf),)
|
||||
@ -51,7 +51,6 @@ LIB_INCLUDE := $(srctree)/tools/lib/
|
||||
# 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)),)
|
||||
@ -67,10 +66,7 @@ ifneq ($(WERROR),0)
|
||||
CFLAGS += -Werror
|
||||
endif
|
||||
|
||||
ifeq ("$(origin DEBUG)", "command line")
|
||||
PERF_DEBUG = $(DEBUG)
|
||||
endif
|
||||
ifndef PERF_DEBUG
|
||||
ifeq ($(DEBUG),0)
|
||||
CFLAGS += -O6
|
||||
endif
|
||||
|
||||
@ -89,20 +85,125 @@ CFLAGS += -std=gnu99
|
||||
|
||||
EXTLIBS = -lelf -lpthread -lrt -lm -ldl
|
||||
|
||||
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
|
||||
ifneq ($(OUTPUT),)
|
||||
OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
|
||||
$(shell mkdir -p $(OUTPUT_FEATURES))
|
||||
endif
|
||||
|
||||
feature_check = $(eval $(feature_check_code))
|
||||
define feature_check_code
|
||||
feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) LDFLAGS=$(LDFLAGS) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0)
|
||||
endef
|
||||
|
||||
feature_set = $(eval $(feature_set_code))
|
||||
define feature_set_code
|
||||
feature-$(1) := 1
|
||||
endef
|
||||
|
||||
#
|
||||
# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output:
|
||||
#
|
||||
|
||||
#
|
||||
# Note that this is not a complete list of all feature tests, just
|
||||
# those that are typically built on a fully configured system.
|
||||
#
|
||||
# [ Feature tests not mentioned here have to be built explicitly in
|
||||
# the rule that uses them - an example for that is the 'bionic'
|
||||
# feature check. ]
|
||||
#
|
||||
CORE_FEATURE_TESTS = \
|
||||
backtrace \
|
||||
dwarf \
|
||||
fortify-source \
|
||||
glibc \
|
||||
gtk2 \
|
||||
gtk2-infobar \
|
||||
libaudit \
|
||||
libbfd \
|
||||
libelf \
|
||||
libelf-getphdrnum \
|
||||
libelf-mmap \
|
||||
libnuma \
|
||||
libperl \
|
||||
libpython \
|
||||
libpython-version \
|
||||
libslang \
|
||||
libunwind \
|
||||
on-exit \
|
||||
stackprotector \
|
||||
stackprotector-all
|
||||
|
||||
#
|
||||
# So here we detect whether test-all was rebuilt, to be able
|
||||
# to skip the print-out of the long features list if the file
|
||||
# existed before and after it was built:
|
||||
#
|
||||
ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),)
|
||||
test-all-failed := 1
|
||||
else
|
||||
test-all-failed := 0
|
||||
endif
|
||||
|
||||
#
|
||||
# Special fast-path for the 'all features are available' case:
|
||||
#
|
||||
$(call feature_check,all,$(MSG))
|
||||
|
||||
#
|
||||
# Just in case the build freshly failed, make sure we print the
|
||||
# feature matrix:
|
||||
#
|
||||
ifeq ($(feature-all), 0)
|
||||
test-all-failed := 1
|
||||
endif
|
||||
|
||||
ifeq ($(test-all-failed),1)
|
||||
$(info )
|
||||
$(info Auto-detecting system features:)
|
||||
endif
|
||||
|
||||
ifeq ($(feature-all), 1)
|
||||
#
|
||||
# test-all.c passed - just set all the core feature flags to 1:
|
||||
#
|
||||
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat)))
|
||||
else
|
||||
$(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1)
|
||||
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat)))
|
||||
endif
|
||||
|
||||
#
|
||||
# Print the result of the feature test:
|
||||
#
|
||||
feature_print = $(eval $(feature_print_code)) $(info $(MSG))
|
||||
|
||||
define feature_print_code
|
||||
ifeq ($(feature-$(1)), 1)
|
||||
MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1))
|
||||
else
|
||||
MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1))
|
||||
endif
|
||||
endef
|
||||
|
||||
#
|
||||
# Only print out our features if we rebuilt the testcases or if a test failed:
|
||||
#
|
||||
ifeq ($(test-all-failed), 1)
|
||||
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_print,$(feat)))
|
||||
$(info )
|
||||
endif
|
||||
|
||||
ifeq ($(feature-stackprotector-all), 1)
|
||||
CFLAGS += -fstack-protector-all
|
||||
endif
|
||||
|
||||
ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
|
||||
ifeq ($(feature-stackprotector), 1)
|
||||
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)
|
||||
ifeq ($(DEBUG),0)
|
||||
ifeq ($(feature-fortify-source), 1)
|
||||
CFLAGS += -D_FORTIFY_SOURCE=2
|
||||
endif
|
||||
endif
|
||||
@ -128,84 +229,74 @@ CFLAGS += -I$(LIB_INCLUDE)
|
||||
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))
|
||||
$(feature_check,bionic)
|
||||
ifeq ($(feature-bionic), 1)
|
||||
BIONIC := 1
|
||||
EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
|
||||
EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
|
||||
endif
|
||||
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);
|
||||
ifeq ($(feature-libelf), 0)
|
||||
ifeq ($(feature-glibc), 1)
|
||||
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
|
||||
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
|
||||
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
|
||||
# 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 -lz -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
|
||||
ifneq ($(feature-dwarf), 1)
|
||||
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 # libelf support
|
||||
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
|
||||
ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y)
|
||||
CFLAGS += -DHAVE_ELF_GETPHDRNUM
|
||||
endif
|
||||
CFLAGS += -DHAVE_LIBELF_SUPPORT
|
||||
|
||||
# include ARCH specific config
|
||||
-include $(src-perf)/arch/$(ARCH)/Makefile
|
||||
ifeq ($(feature-libelf-mmap), 1)
|
||||
CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
|
||||
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);
|
||||
NO_DWARF := 1
|
||||
else
|
||||
CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
|
||||
LDFLAGS += $(LIBDW_LDFLAGS)
|
||||
EXTLIBS += -lelf -ldw
|
||||
endif # PERF_HAVE_DWARF_REGS
|
||||
endif # NO_DWARF
|
||||
ifeq ($(feature-libelf-getphdrnum), 1)
|
||||
CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT
|
||||
endif
|
||||
|
||||
endif # NO_LIBELF
|
||||
# include ARCH specific config
|
||||
-include $(src-perf)/arch/$(ARCH)/Makefile
|
||||
|
||||
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
|
||||
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 += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS)
|
||||
LDFLAGS += $(LIBDW_LDFLAGS)
|
||||
EXTLIBS += -lelf -ldw
|
||||
endif # PERF_HAVE_DWARF_REGS
|
||||
endif # NO_DWARF
|
||||
endif # NO_LIBELF
|
||||
|
||||
# There's only x86 (both 32 and 64) support for CFI unwind so far
|
||||
@ -214,34 +305,35 @@ ifneq ($(ARCH),x86)
|
||||
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
|
||||
#
|
||||
# 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
|
||||
|
||||
ifneq ($(feature-libunwind), 1)
|
||||
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
|
||||
NO_LIBUNWIND := 1
|
||||
endif
|
||||
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
|
||||
CFLAGS += -DHAVE_LIBUNWIND_SUPPORT
|
||||
EXTLIBS += $(LIBUNWIND_LIBS)
|
||||
CFLAGS += $(LIBUNWIND_CFLAGS)
|
||||
LDFLAGS += $(LIBUNWIND_LDFLAGS)
|
||||
endif # NO_LIBUNWIND
|
||||
endif
|
||||
|
||||
ifndef NO_LIBAUDIT
|
||||
FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
|
||||
ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
|
||||
ifneq ($(feature-libaudit), 1)
|
||||
msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
|
||||
NO_LIBAUDIT := 1
|
||||
else
|
||||
CFLAGS += -DLIBAUDIT_SUPPORT
|
||||
CFLAGS += -DHAVE_LIBAUDIT_SUPPORT
|
||||
EXTLIBS += -laudit
|
||||
endif
|
||||
endif
|
||||
@ -251,30 +343,30 @@ ifdef NO_NEWT
|
||||
endif
|
||||
|
||||
ifndef NO_SLANG
|
||||
FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
|
||||
ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
|
||||
ifneq ($(feature-libslang), 1)
|
||||
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
|
||||
CFLAGS += -DHAVE_SLANG_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)
|
||||
ifneq ($(feature-gtk2), 1)
|
||||
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
|
||||
ifeq ($(feature-gtk2-infobar), 1)
|
||||
GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT
|
||||
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)
|
||||
CFLAGS += -DHAVE_GTK2_SUPPORT
|
||||
GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
|
||||
GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
|
||||
EXTLIBS += -ldl
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -290,7 +382,7 @@ else
|
||||
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)
|
||||
ifneq ($(feature-libperl), 1)
|
||||
CFLAGS += -DNO_LIBPERL
|
||||
NO_LIBPERL := 1
|
||||
else
|
||||
@ -335,11 +427,11 @@ else
|
||||
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)
|
||||
ifneq ($(feature-libpython), 1)
|
||||
$(call disable-python,Python.h (for Python 2.x))
|
||||
else
|
||||
|
||||
ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
|
||||
ifneq ($(feature-libpython-version), 1)
|
||||
$(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)
|
||||
@ -362,33 +454,30 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(feature-libbfd), 1)
|
||||
EXTLIBS += -lbfd
|
||||
endif
|
||||
|
||||
ifdef NO_DEMANGLE
|
||||
CFLAGS += -DNO_DEMANGLE
|
||||
else
|
||||
ifdef HAVE_CPLUS_DEMANGLE
|
||||
ifdef HAVE_CPLUS_DEMANGLE_SUPPORT
|
||||
EXTLIBS += -liberty
|
||||
CFLAGS += -DHAVE_CPLUS_DEMANGLE
|
||||
CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
|
||||
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)
|
||||
ifneq ($(feature-libbfd), 1)
|
||||
$(feature_check,liberty)
|
||||
ifeq ($(feature-liberty), 1)
|
||||
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)
|
||||
$(feature_check,liberty-z)
|
||||
ifeq ($(feature-liberty-z), 1)
|
||||
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)
|
||||
$(feature_check,cplus-demangle)
|
||||
ifeq ($(feature-cplus-demangle), 1)
|
||||
EXTLIBS += -liberty
|
||||
CFLAGS += -DHAVE_CPLUS_DEMANGLE
|
||||
CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT
|
||||
else
|
||||
msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
|
||||
CFLAGS += -DNO_DEMANGLE
|
||||
@ -399,31 +488,28 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_STRLCPY
|
||||
ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
|
||||
CFLAGS += -DHAVE_STRLCPY
|
||||
endif
|
||||
ifneq ($(filter -lbfd,$(EXTLIBS)),)
|
||||
CFLAGS += -DHAVE_LIBBFD_SUPPORT
|
||||
endif
|
||||
|
||||
ifndef NO_ON_EXIT
|
||||
ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
|
||||
CFLAGS += -DHAVE_ON_EXIT
|
||||
ifeq ($(feature-on-exit), 1)
|
||||
CFLAGS += -DHAVE_ON_EXIT_SUPPORT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_BACKTRACE
|
||||
ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
|
||||
CFLAGS += -DBACKTRACE_SUPPORT
|
||||
ifeq ($(feature-backtrace), 1)
|
||||
CFLAGS += -DHAVE_BACKTRACE_SUPPORT
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef NO_LIBNUMA
|
||||
FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
|
||||
ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
|
||||
ifeq ($(feature-libnuma), 0)
|
||||
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
|
||||
CFLAGS += -DHAVE_LIBNUMA_SUPPORT
|
||||
EXTLIBS += -lnuma
|
||||
endif
|
||||
endif
|
||||
@ -459,7 +545,12 @@ else
|
||||
sysconfdir = $(prefix)/etc
|
||||
ETC_PERFCONFIG = etc/perfconfig
|
||||
endif
|
||||
ifeq ($(IS_X86_64),1)
|
||||
lib = lib64
|
||||
else
|
||||
lib = lib
|
||||
endif
|
||||
libdir = $(prefix)/$(lib)
|
||||
|
||||
# Shell quote (do not use $(call) to accommodate ancient setups);
|
||||
ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
|
||||
@ -472,6 +563,7 @@ template_dir_SQ = $(subst ','\'',$(template_dir))
|
||||
htmldir_SQ = $(subst ','\'',$(htmldir))
|
||||
prefix_SQ = $(subst ','\'',$(prefix))
|
||||
sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
|
||||
libdir_SQ = $(subst ','\'',$(libdir))
|
||||
|
||||
ifneq ($(filter /%,$(firstword $(perfexecdir))),)
|
||||
perfexec_instdir = $(perfexecdir)
|
||||
|
144
tools/perf/config/feature-checks/Makefile
Normal file
144
tools/perf/config/feature-checks/Makefile
Normal file
@ -0,0 +1,144 @@
|
||||
|
||||
FILES= \
|
||||
test-all \
|
||||
test-backtrace \
|
||||
test-bionic \
|
||||
test-dwarf \
|
||||
test-fortify-source \
|
||||
test-glibc \
|
||||
test-gtk2 \
|
||||
test-gtk2-infobar \
|
||||
test-hello \
|
||||
test-libaudit \
|
||||
test-libbfd \
|
||||
test-liberty \
|
||||
test-liberty-z \
|
||||
test-cplus-demangle \
|
||||
test-libelf \
|
||||
test-libelf-getphdrnum \
|
||||
test-libelf-mmap \
|
||||
test-libnuma \
|
||||
test-libperl \
|
||||
test-libpython \
|
||||
test-libpython-version \
|
||||
test-libslang \
|
||||
test-libunwind \
|
||||
test-on-exit \
|
||||
test-stackprotector-all \
|
||||
test-stackprotector
|
||||
|
||||
CC := $(CC) -MD
|
||||
|
||||
all: $(FILES)
|
||||
|
||||
BUILD = $(CC) $(LDFLAGS) -o $(OUTPUT)$@ $@.c
|
||||
|
||||
###############################
|
||||
|
||||
test-all:
|
||||
$(BUILD) -Werror -fstack-protector -fstack-protector-all -O2 -Werror -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -lunwind -lunwind-x86_64 -lelf -laudit -I/usr/include/slang -lslang $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) $(FLAGS_PERL_EMBED) $(FLAGS_PYTHON_EMBED) -DPACKAGE='"perf"' -lbfd -ldl
|
||||
|
||||
test-hello:
|
||||
$(BUILD)
|
||||
|
||||
test-stackprotector-all:
|
||||
$(BUILD) -Werror -fstack-protector-all
|
||||
|
||||
test-stackprotector:
|
||||
$(BUILD) -Werror -fstack-protector -Wstack-protector
|
||||
|
||||
test-fortify-source:
|
||||
$(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2
|
||||
|
||||
test-bionic:
|
||||
$(BUILD)
|
||||
|
||||
test-libelf:
|
||||
$(BUILD) -lelf
|
||||
|
||||
test-glibc:
|
||||
$(BUILD)
|
||||
|
||||
test-dwarf:
|
||||
$(BUILD) -ldw
|
||||
|
||||
test-libelf-mmap:
|
||||
$(BUILD) -lelf
|
||||
|
||||
test-libelf-getphdrnum:
|
||||
$(BUILD) -lelf
|
||||
|
||||
test-libnuma:
|
||||
$(BUILD) -lnuma
|
||||
|
||||
test-libunwind:
|
||||
$(BUILD) -lunwind -lunwind-x86_64 -lelf
|
||||
|
||||
test-libaudit:
|
||||
$(BUILD) -laudit
|
||||
|
||||
test-libslang:
|
||||
$(BUILD) -I/usr/include/slang -lslang
|
||||
|
||||
test-gtk2:
|
||||
$(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
|
||||
|
||||
test-gtk2-infobar:
|
||||
$(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
|
||||
|
||||
grep-libs = $(filter -l%,$(1))
|
||||
strip-libs = $(filter-out -l%,$(1))
|
||||
|
||||
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)
|
||||
|
||||
test-libperl:
|
||||
$(BUILD) $(FLAGS_PERL_EMBED)
|
||||
|
||||
override PYTHON := python
|
||||
override PYTHON_CONFIG := python-config
|
||||
|
||||
escape-for-shell-sq = $(subst ','\'',$(1))
|
||||
shell-sq = '$(escape-for-shell-sq)'
|
||||
|
||||
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)
|
||||
|
||||
test-libpython:
|
||||
$(BUILD) $(FLAGS_PYTHON_EMBED)
|
||||
|
||||
test-libpython-version:
|
||||
$(BUILD) $(FLAGS_PYTHON_EMBED)
|
||||
|
||||
test-libbfd:
|
||||
$(BUILD) -DPACKAGE='"perf"' -lbfd -ldl
|
||||
|
||||
test-liberty:
|
||||
$(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty
|
||||
|
||||
test-liberty-z:
|
||||
$(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz
|
||||
|
||||
test-cplus-demangle:
|
||||
$(BUILD) -liberty
|
||||
|
||||
test-on-exit:
|
||||
$(BUILD)
|
||||
|
||||
test-backtrace:
|
||||
$(BUILD)
|
||||
|
||||
-include *.d
|
||||
|
||||
###############################
|
||||
|
||||
clean:
|
||||
rm -f $(FILES) *.d
|
106
tools/perf/config/feature-checks/test-all.c
Normal file
106
tools/perf/config/feature-checks/test-all.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* test-all.c: Try to build all the main testcases at once.
|
||||
*
|
||||
* A well-configured system will have all the prereqs installed, so we can speed
|
||||
* up auto-detection on such systems.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Quirk: Python and Perl headers cannot be in arbitrary places, so keep
|
||||
* these 3 testcases at the top:
|
||||
*/
|
||||
#define main main_test_libpython
|
||||
# include "test-libpython.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libpython_version
|
||||
# include "test-libpython-version.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libperl
|
||||
# include "test-libperl.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_hello
|
||||
# include "test-hello.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libelf
|
||||
# include "test-libelf.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libelf_mmap
|
||||
# include "test-libelf-mmap.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_glibc
|
||||
# include "test-glibc.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_dwarf
|
||||
# include "test-dwarf.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libelf_getphdrnum
|
||||
# include "test-libelf-getphdrnum.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libunwind
|
||||
# include "test-libunwind.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libaudit
|
||||
# include "test-libaudit.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libslang
|
||||
# include "test-libslang.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_gtk2
|
||||
# include "test-gtk2.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_gtk2_infobar
|
||||
# include "test-gtk2-infobar.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libbfd
|
||||
# include "test-libbfd.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_on_exit
|
||||
# include "test-on-exit.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_backtrace
|
||||
# include "test-backtrace.c"
|
||||
#undef main
|
||||
|
||||
#define main main_test_libnuma
|
||||
# include "test-libnuma.c"
|
||||
#undef main
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
main_test_libpython();
|
||||
main_test_libpython_version();
|
||||
main_test_libperl();
|
||||
main_test_hello();
|
||||
main_test_libelf();
|
||||
main_test_libelf_mmap();
|
||||
main_test_glibc();
|
||||
main_test_dwarf();
|
||||
main_test_libelf_getphdrnum();
|
||||
main_test_libunwind();
|
||||
main_test_libaudit();
|
||||
main_test_libslang();
|
||||
main_test_gtk2(argc, argv);
|
||||
main_test_gtk2_infobar(argc, argv);
|
||||
main_test_libbfd();
|
||||
main_test_on_exit();
|
||||
main_test_backtrace();
|
||||
main_test_libnuma();
|
||||
|
||||
return 0;
|
||||
}
|
13
tools/perf/config/feature-checks/test-backtrace.c
Normal file
13
tools/perf/config/feature-checks/test-backtrace.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
void *backtrace_fns[10];
|
||||
size_t entries;
|
||||
|
||||
entries = backtrace(backtrace_fns, 10);
|
||||
backtrace_symbols_fd(backtrace_fns, entries, 1);
|
||||
|
||||
return 0;
|
||||
}
|
6
tools/perf/config/feature-checks/test-bionic.c
Normal file
6
tools/perf/config/feature-checks/test-bionic.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <android/api-level.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return __ANDROID_API__;
|
||||
}
|
14
tools/perf/config/feature-checks/test-cplus-demangle.c
Normal file
14
tools/perf/config/feature-checks/test-cplus-demangle.c
Normal file
@ -0,0 +1,14 @@
|
||||
extern int printf(const char *format, ...);
|
||||
extern char *cplus_demangle(const char *, int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char symbol[4096] = "FieldName__9ClassNameFd";
|
||||
char *tmp;
|
||||
|
||||
tmp = cplus_demangle(symbol, 0);
|
||||
|
||||
printf("demangled symbol: {%s}\n", tmp);
|
||||
|
||||
return 0;
|
||||
}
|
10
tools/perf/config/feature-checks/test-dwarf.c
Normal file
10
tools/perf/config/feature-checks/test-dwarf.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <dwarf.h>
|
||||
#include <elfutils/libdw.h>
|
||||
#include <elfutils/version.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Dwarf *dbg = dwarf_begin(0, DWARF_C_READ);
|
||||
|
||||
return (long)dbg;
|
||||
}
|
6
tools/perf/config/feature-checks/test-fortify-source.c
Normal file
6
tools/perf/config/feature-checks/test-fortify-source.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return puts("hi");
|
||||
}
|
8
tools/perf/config/feature-checks/test-glibc.c
Normal file
8
tools/perf/config/feature-checks/test-glibc.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <gnu/libc-version.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char *version = gnu_get_libc_version();
|
||||
|
||||
return (long)version;
|
||||
}
|
11
tools/perf/config/feature-checks/test-gtk2-infobar.c
Normal file
11
tools/perf/config/feature-checks/test-gtk2-infobar.c
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||
#include <gtk/gtk.h>
|
||||
#pragma GCC diagnostic error "-Wstrict-prototypes"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
gtk_init(&argc, &argv);
|
||||
gtk_info_bar_new();
|
||||
|
||||
return 0;
|
||||
}
|
10
tools/perf/config/feature-checks/test-gtk2.c
Normal file
10
tools/perf/config/feature-checks/test-gtk2.c
Normal file
@ -0,0 +1,10 @@
|
||||
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||
#include <gtk/gtk.h>
|
||||
#pragma GCC diagnostic error "-Wstrict-prototypes"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
return 0;
|
||||
}
|
6
tools/perf/config/feature-checks/test-hello.c
Normal file
6
tools/perf/config/feature-checks/test-hello.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return puts("hi");
|
||||
}
|
10
tools/perf/config/feature-checks/test-libaudit.c
Normal file
10
tools/perf/config/feature-checks/test-libaudit.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <libaudit.h>
|
||||
|
||||
extern int printf(const char *format, ...);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("error message: %s\n", audit_errno_to_name(0));
|
||||
|
||||
return audit_open();
|
||||
}
|
15
tools/perf/config/feature-checks/test-libbfd.c
Normal file
15
tools/perf/config/feature-checks/test-libbfd.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <bfd.h>
|
||||
|
||||
extern int printf(const char *format, ...);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char symbol[4096] = "FieldName__9ClassNameFd";
|
||||
char *tmp;
|
||||
|
||||
tmp = bfd_demangle(0, symbol, 0);
|
||||
|
||||
printf("demangled symbol: {%s}\n", tmp);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
#include <libelf.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
size_t dst;
|
||||
|
||||
return elf_getphdrnum(0, &dst);
|
||||
}
|
8
tools/perf/config/feature-checks/test-libelf-mmap.c
Normal file
8
tools/perf/config/feature-checks/test-libelf-mmap.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <libelf.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0);
|
||||
|
||||
return (long)elf;
|
||||
}
|
8
tools/perf/config/feature-checks/test-libelf.c
Normal file
8
tools/perf/config/feature-checks/test-libelf.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <libelf.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Elf *elf = elf_begin(0, ELF_C_READ, 0);
|
||||
|
||||
return (long)elf;
|
||||
}
|
9
tools/perf/config/feature-checks/test-libnuma.c
Normal file
9
tools/perf/config/feature-checks/test-libnuma.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <numa.h>
|
||||
#include <numaif.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
numa_available();
|
||||
|
||||
return 0;
|
||||
}
|
9
tools/perf/config/feature-checks/test-libperl.c
Normal file
9
tools/perf/config/feature-checks/test-libperl.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
perl_alloc();
|
||||
|
||||
return 0;
|
||||
}
|
10
tools/perf/config/feature-checks/test-libpython-version.c
Normal file
10
tools/perf/config/feature-checks/test-libpython-version.c
Normal file
@ -0,0 +1,10 @@
|
||||
#include <Python.h>
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
#error
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
8
tools/perf/config/feature-checks/test-libpython.c
Normal file
8
tools/perf/config/feature-checks/test-libpython.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <Python.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Py_Initialize();
|
||||
|
||||
return 0;
|
||||
}
|
6
tools/perf/config/feature-checks/test-libslang.c
Normal file
6
tools/perf/config/feature-checks/test-libslang.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <slang.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return SLsmg_init_smg();
|
||||
}
|
27
tools/perf/config/feature-checks/test-libunwind.c
Normal file
27
tools/perf/config/feature-checks/test-libunwind.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <libunwind.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
|
||||
unw_word_t ip,
|
||||
unw_dyn_info_t *di,
|
||||
unw_proc_info_t *pi,
|
||||
int need_unwind_info, void *arg);
|
||||
|
||||
|
||||
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
|
||||
|
||||
static unw_accessors_t accessors;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unw_addr_space_t addr_space;
|
||||
|
||||
addr_space = unw_create_addr_space(&accessors, 0);
|
||||
if (addr_space)
|
||||
return 0;
|
||||
|
||||
unw_init_remote(NULL, addr_space, NULL);
|
||||
dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
15
tools/perf/config/feature-checks/test-on-exit.c
Normal file
15
tools/perf/config/feature-checks/test-on-exit.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
static void exit_fn(int status, void *__data)
|
||||
{
|
||||
printf("exit status: %d, data: %d\n", status, *(int *)__data);
|
||||
}
|
||||
|
||||
static int data = 123;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
on_exit(exit_fn, &data);
|
||||
|
||||
return 321;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return puts("hi");
|
||||
}
|
6
tools/perf/config/feature-checks/test-stackprotector.c
Normal file
6
tools/perf/config/feature-checks/test-stackprotector.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return puts("hi");
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return puts("hi");
|
||||
}
|
@ -1,246 +0,0 @@
|
||||
define SOURCE_HELLO
|
||||
#include <stdio.h>
|
||||
int main(void)
|
||||
{
|
||||
return puts(\"hi\");
|
||||
}
|
||||
endef
|
||||
|
||||
ifndef NO_DWARF
|
||||
define SOURCE_DWARF
|
||||
#include <dwarf.h>
|
||||
#include <elfutils/libdw.h>
|
||||
#include <elfutils/version.h>
|
||||
#ifndef _ELFUTILS_PREREQ
|
||||
#error
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Dwarf *dbg = dwarf_begin(0, DWARF_C_READ);
|
||||
return (long)dbg;
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
define SOURCE_LIBELF
|
||||
#include <libelf.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Elf *elf = elf_begin(0, ELF_C_READ, 0);
|
||||
return (long)elf;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_GLIBC
|
||||
#include <gnu/libc-version.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char *version = gnu_get_libc_version();
|
||||
return (long)version;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_BIONIC
|
||||
#include <android/api-level.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return __ANDROID_API__;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_ELF_MMAP
|
||||
#include <libelf.h>
|
||||
int main(void)
|
||||
{
|
||||
Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0);
|
||||
return (long)elf;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_ELF_GETPHDRNUM
|
||||
#include <libelf.h>
|
||||
int main(void)
|
||||
{
|
||||
size_t dst;
|
||||
return elf_getphdrnum(0, &dst);
|
||||
}
|
||||
endef
|
||||
|
||||
ifndef NO_SLANG
|
||||
define SOURCE_SLANG
|
||||
#include <slang.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return SLsmg_init_smg();
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
ifndef NO_GTK2
|
||||
define SOURCE_GTK2
|
||||
#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
|
||||
#include <gtk/gtk.h>
|
||||
#pragma GCC diagnostic error \"-Wstrict-prototypes\"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
gtk_init(&argc, &argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_GTK2_INFOBAR
|
||||
#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
|
||||
#include <gtk/gtk.h>
|
||||
#pragma GCC diagnostic error \"-Wstrict-prototypes\"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
gtk_info_bar_new();
|
||||
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
ifndef NO_LIBPERL
|
||||
define SOURCE_PERL_EMBED
|
||||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
perl_alloc();
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
ifndef NO_LIBPYTHON
|
||||
define SOURCE_PYTHON_VERSION
|
||||
#include <Python.h>
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
#error
|
||||
#endif
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
define SOURCE_PYTHON_EMBED
|
||||
#include <Python.h>
|
||||
int main(void)
|
||||
{
|
||||
Py_Initialize();
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
define SOURCE_BFD
|
||||
#include <bfd.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
bfd_demangle(0, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_CPLUS_DEMANGLE
|
||||
extern char *cplus_demangle(const char *, int);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
cplus_demangle(0, 0);
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_STRLCPY
|
||||
#include <stdlib.h>
|
||||
extern size_t strlcpy(char *dest, const char *src, size_t size);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
strlcpy(NULL, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
|
||||
ifndef NO_LIBUNWIND
|
||||
define SOURCE_LIBUNWIND
|
||||
#include <libunwind.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
|
||||
unw_word_t ip,
|
||||
unw_dyn_info_t *di,
|
||||
unw_proc_info_t *pi,
|
||||
int need_unwind_info, void *arg);
|
||||
|
||||
|
||||
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unw_addr_space_t addr_space;
|
||||
addr_space = unw_create_addr_space(NULL, 0);
|
||||
unw_init_remote(NULL, addr_space, NULL);
|
||||
dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
ifndef NO_BACKTRACE
|
||||
define SOURCE_BACKTRACE
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
backtrace(NULL, 0);
|
||||
backtrace_symbols(NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
ifndef NO_LIBAUDIT
|
||||
define SOURCE_LIBAUDIT
|
||||
#include <libaudit.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf(\"error message: %s\", audit_errno_to_name(0));
|
||||
return audit_open();
|
||||
}
|
||||
endef
|
||||
endif
|
||||
|
||||
define SOURCE_ON_EXIT
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return on_exit(NULL, NULL);
|
||||
}
|
||||
endef
|
||||
|
||||
define SOURCE_LIBNUMA
|
||||
#include <numa.h>
|
||||
#include <numaif.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
numa_available();
|
||||
return 0;
|
||||
}
|
||||
endef
|
@ -179,16 +179,9 @@ _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_e
|
||||
_gea_warn = $(warning The path '$(1)' is not executable.)
|
||||
_gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
|
||||
|
||||
# try-cc
|
||||
# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
|
||||
ifneq ($(V),1)
|
||||
TRY_CC_OUTPUT= > /dev/null 2>&1
|
||||
ifneq ($(findstring $(MAKEFLAGS),s),s)
|
||||
ifneq ($(V),1)
|
||||
QUIET_CLEAN = @printf ' CLEAN %s\n' $1;
|
||||
QUIET_INSTALL = @printf ' INSTALL %s\n' $1;
|
||||
endif
|
||||
endif
|
||||
TRY_CC_MSG=echo " CHK $(3)" 1>&2;
|
||||
|
||||
try-cc = $(shell sh -c \
|
||||
'TMP="$(OUTPUT)$(TMPOUT).$$$$"; \
|
||||
$(TRY_CC_MSG) \
|
||||
echo "$(1)" | \
|
||||
$(CC) -x c - $(2) -o "$$TMP" $(TRY_CC_OUTPUT) && echo y; \
|
||||
rm -f "$$TMP"')
|
||||
|
@ -49,14 +49,14 @@ static struct cmd_struct commands[] = {
|
||||
{ "version", cmd_version, 0 },
|
||||
{ "script", cmd_script, 0 },
|
||||
{ "sched", cmd_sched, 0 },
|
||||
#ifdef LIBELF_SUPPORT
|
||||
#ifdef HAVE_LIBELF_SUPPORT
|
||||
{ "probe", cmd_probe, 0 },
|
||||
#endif
|
||||
{ "kmem", cmd_kmem, 0 },
|
||||
{ "lock", cmd_lock, 0 },
|
||||
{ "kvm", cmd_kvm, 0 },
|
||||
{ "test", cmd_test, 0 },
|
||||
#ifdef LIBAUDIT_SUPPORT
|
||||
#ifdef HAVE_LIBAUDIT_SUPPORT
|
||||
{ "trace", cmd_trace, 0 },
|
||||
#endif
|
||||
{ "inject", cmd_inject, 0 },
|
||||
@ -456,6 +456,7 @@ int main(int argc, const char **argv)
|
||||
{
|
||||
const char *cmd;
|
||||
|
||||
/* The page_size is placed in util object. */
|
||||
page_size = sysconf(_SC_PAGE_SIZE);
|
||||
|
||||
cmd = perf_extract_argv0_path(argv[0]);
|
||||
@ -480,7 +481,14 @@ int main(int argc, const char **argv)
|
||||
fprintf(stderr, "cannot handle %s internally", cmd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBAUDIT_SUPPORT
|
||||
if (!prefixcmp(cmd, "trace")) {
|
||||
set_buildid_dir();
|
||||
setup_path();
|
||||
argv[0] = "trace";
|
||||
return cmd_trace(argc, argv, NULL);
|
||||
}
|
||||
#endif
|
||||
/* Look for flags.. */
|
||||
argv++;
|
||||
argc--;
|
||||
|
@ -35,6 +35,7 @@ static char *test_file(int size)
|
||||
if (size != write(fd, buf, size))
|
||||
templ = NULL;
|
||||
|
||||
free(buf);
|
||||
close(fd);
|
||||
return templ;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ int test__PERF_RECORD(void)
|
||||
};
|
||||
cpu_set_t cpu_mask;
|
||||
size_t cpu_mask_size = sizeof(cpu_mask);
|
||||
struct perf_evlist *evlist = perf_evlist__new();
|
||||
struct perf_evlist *evlist = perf_evlist__new_default();
|
||||
struct perf_evsel *evsel;
|
||||
struct perf_sample sample;
|
||||
const char *cmd = "sleep";
|
||||
@ -65,16 +65,6 @@ int test__PERF_RECORD(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* We need at least one evsel in the evlist, use the default
|
||||
* one: "cycles".
|
||||
*/
|
||||
err = perf_evlist__add_default(evlist);
|
||||
if (err < 0) {
|
||||
pr_debug("Not enough memory to create evsel\n");
|
||||
goto out_delete_evlist;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create maps of threads and cpus to monitor. In this case
|
||||
* we start with all threads and cpus (-1, -1) but then in
|
||||
|
@ -37,20 +37,11 @@ int test__task_exit(void)
|
||||
signal(SIGCHLD, sig_handler);
|
||||
signal(SIGUSR1, sig_handler);
|
||||
|
||||
evlist = perf_evlist__new();
|
||||
evlist = perf_evlist__new_default();
|
||||
if (evlist == NULL) {
|
||||
pr_debug("perf_evlist__new\n");
|
||||
pr_debug("perf_evlist__new_default\n");
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* We need at least one evsel in the evlist, use the default
|
||||
* one: "cycles".
|
||||
*/
|
||||
err = perf_evlist__add_default(evlist);
|
||||
if (err < 0) {
|
||||
pr_debug("Not enough memory to create evsel\n");
|
||||
goto out_free_evlist;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create maps of threads and cpus to monitor. In this case
|
||||
@ -117,7 +108,6 @@ int test__task_exit(void)
|
||||
perf_evlist__close(evlist);
|
||||
out_delete_maps:
|
||||
perf_evlist__delete_maps(evlist);
|
||||
out_free_evlist:
|
||||
perf_evlist__delete(evlist);
|
||||
return err;
|
||||
}
|
||||
|
@ -442,35 +442,37 @@ static bool annotate_browser__callq(struct annotate_browser *browser,
|
||||
{
|
||||
struct map_symbol *ms = browser->b.priv;
|
||||
struct disasm_line *dl = browser->selection;
|
||||
struct symbol *sym = ms->sym;
|
||||
struct annotation *notes;
|
||||
struct symbol *target;
|
||||
u64 ip;
|
||||
struct addr_map_symbol target = {
|
||||
.map = ms->map,
|
||||
.addr = map__objdump_2mem(ms->map, dl->ops.target.addr),
|
||||
};
|
||||
char title[SYM_TITLE_MAX_SIZE];
|
||||
|
||||
if (!ins__is_call(dl->ins))
|
||||
return false;
|
||||
|
||||
ip = ms->map->map_ip(ms->map, dl->ops.target.addr);
|
||||
target = map__find_symbol(ms->map, ip, NULL);
|
||||
if (target == NULL) {
|
||||
if (map_groups__find_ams(&target, NULL) ||
|
||||
map__rip_2objdump(target.map, target.map->map_ip(target.map,
|
||||
target.addr)) !=
|
||||
dl->ops.target.addr) {
|
||||
ui_helpline__puts("The called function was not found.");
|
||||
return true;
|
||||
}
|
||||
|
||||
notes = symbol__annotation(target);
|
||||
notes = symbol__annotation(target.sym);
|
||||
pthread_mutex_lock(¬es->lock);
|
||||
|
||||
if (notes->src == NULL && symbol__alloc_hist(target) < 0) {
|
||||
if (notes->src == NULL && symbol__alloc_hist(target.sym) < 0) {
|
||||
pthread_mutex_unlock(¬es->lock);
|
||||
ui__warning("Not enough memory for annotating '%s' symbol!\n",
|
||||
target->name);
|
||||
target.sym->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(¬es->lock);
|
||||
symbol__tui_annotate(target, ms->map, evsel, hbt);
|
||||
sym_title(sym, ms->map, title, sizeof(title));
|
||||
symbol__tui_annotate(target.sym, target.map, evsel, hbt);
|
||||
sym_title(ms->sym, ms->map, title, sizeof(title));
|
||||
ui_browser__show_title(&browser->b, title);
|
||||
return true;
|
||||
}
|
||||
|
@ -154,9 +154,9 @@ static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int symbol__gtk_annotate(struct symbol *sym, struct map *map,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt)
|
||||
static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *notebook;
|
||||
@ -226,6 +226,13 @@ int symbol__gtk_annotate(struct symbol *sym, struct map *map,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hist_entry__gtk_annotate(struct hist_entry *he,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt)
|
||||
{
|
||||
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
|
||||
}
|
||||
|
||||
void perf_gtk__show_annotations(void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
@ -43,7 +43,7 @@ const char *perf_gtk__get_percent_color(double percent)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GTK_INFO_BAR
|
||||
#ifdef HAVE_GTK_INFO_BAR_SUPPORT
|
||||
GtkWidget *perf_gtk__setup_info_bar(void)
|
||||
{
|
||||
GtkWidget *info_bar;
|
||||
|
@ -12,7 +12,7 @@ struct perf_gtk_context {
|
||||
GtkWidget *main_window;
|
||||
GtkWidget *notebook;
|
||||
|
||||
#ifdef HAVE_GTK_INFO_BAR
|
||||
#ifdef HAVE_GTK_INFO_BAR_SUPPORT
|
||||
GtkWidget *info_bar;
|
||||
GtkWidget *message_label;
|
||||
#endif
|
||||
@ -20,6 +20,9 @@ struct perf_gtk_context {
|
||||
guint statbar_ctx_id;
|
||||
};
|
||||
|
||||
int perf_gtk__init(void);
|
||||
void perf_gtk__exit(bool wait_for_ok);
|
||||
|
||||
extern struct perf_gtk_context *pgctx;
|
||||
|
||||
static inline bool perf_gtk__is_active_context(struct perf_gtk_context *ctx)
|
||||
@ -39,7 +42,7 @@ void perf_gtk__resize_window(GtkWidget *window);
|
||||
const char *perf_gtk__get_percent_color(double percent);
|
||||
GtkWidget *perf_gtk__setup_statusbar(void);
|
||||
|
||||
#ifdef HAVE_GTK_INFO_BAR
|
||||
#ifdef HAVE_GTK_INFO_BAR_SUPPORT
|
||||
GtkWidget *perf_gtk__setup_info_bar(void);
|
||||
#else
|
||||
static inline GtkWidget *perf_gtk__setup_info_bar(void)
|
||||
@ -48,4 +51,17 @@ static inline GtkWidget *perf_gtk__setup_info_bar(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
struct perf_evsel;
|
||||
struct perf_evlist;
|
||||
struct hist_entry;
|
||||
struct hist_browser_timer;
|
||||
|
||||
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
|
||||
struct hist_browser_timer *hbt,
|
||||
float min_pcnt);
|
||||
int hist_entry__gtk_annotate(struct hist_entry *he,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
void perf_gtk__show_annotations(void);
|
||||
|
||||
#endif /* _PERF_GTK_H_ */
|
||||
|
@ -53,7 +53,7 @@ static int perf_gtk__error(const char *format, va_list args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_GTK_INFO_BAR
|
||||
#ifdef HAVE_GTK_INFO_BAR_SUPPORT
|
||||
static int perf_gtk__warning_info_bar(const char *format, va_list args)
|
||||
{
|
||||
char *msg;
|
||||
@ -105,7 +105,7 @@ static int perf_gtk__warning_statusbar(const char *format, va_list args)
|
||||
|
||||
struct perf_error_ops perf_gtk_eops = {
|
||||
.error = perf_gtk__error,
|
||||
#ifdef HAVE_GTK_INFO_BAR
|
||||
#ifdef HAVE_GTK_INFO_BAR_SUPPORT
|
||||
.warning = perf_gtk__warning_info_bar,
|
||||
#else
|
||||
.warning = perf_gtk__warning_statusbar,
|
||||
|
@ -1,10 +1,64 @@
|
||||
#include <pthread.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "../util/cache.h"
|
||||
#include "../util/debug.h"
|
||||
#include "../util/hist.h"
|
||||
|
||||
pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
void *perf_gtk_handle;
|
||||
|
||||
#ifdef HAVE_GTK2_SUPPORT
|
||||
static int setup_gtk_browser(void)
|
||||
{
|
||||
int (*perf_ui_init)(void);
|
||||
|
||||
if (perf_gtk_handle)
|
||||
return 0;
|
||||
|
||||
perf_gtk_handle = dlopen(PERF_GTK_DSO, RTLD_LAZY);
|
||||
if (perf_gtk_handle == NULL) {
|
||||
char buf[PATH_MAX];
|
||||
scnprintf(buf, sizeof(buf), "%s/%s", LIBDIR, PERF_GTK_DSO);
|
||||
perf_gtk_handle = dlopen(buf, RTLD_LAZY);
|
||||
}
|
||||
if (perf_gtk_handle == NULL)
|
||||
return -1;
|
||||
|
||||
perf_ui_init = dlsym(perf_gtk_handle, "perf_gtk__init");
|
||||
if (perf_ui_init == NULL)
|
||||
goto out_close;
|
||||
|
||||
if (perf_ui_init() == 0)
|
||||
return 0;
|
||||
|
||||
out_close:
|
||||
dlclose(perf_gtk_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void exit_gtk_browser(bool wait_for_ok)
|
||||
{
|
||||
void (*perf_ui_exit)(bool);
|
||||
|
||||
if (perf_gtk_handle == NULL)
|
||||
return;
|
||||
|
||||
perf_ui_exit = dlsym(perf_gtk_handle, "perf_gtk__exit");
|
||||
if (perf_ui_exit == NULL)
|
||||
goto out_close;
|
||||
|
||||
perf_ui_exit(wait_for_ok);
|
||||
|
||||
out_close:
|
||||
dlclose(perf_gtk_handle);
|
||||
|
||||
perf_gtk_handle = NULL;
|
||||
}
|
||||
#else
|
||||
static inline int setup_gtk_browser(void) { return -1; }
|
||||
static inline void exit_gtk_browser(bool wait_for_ok __maybe_unused) {}
|
||||
#endif
|
||||
|
||||
void setup_browser(bool fallback_to_pager)
|
||||
{
|
||||
@ -17,8 +71,11 @@ void setup_browser(bool fallback_to_pager)
|
||||
|
||||
switch (use_browser) {
|
||||
case 2:
|
||||
if (perf_gtk__init() == 0)
|
||||
if (setup_gtk_browser() == 0)
|
||||
break;
|
||||
printf("GTK browser requested but could not find %s\n",
|
||||
PERF_GTK_DSO);
|
||||
sleep(1);
|
||||
/* fall through */
|
||||
case 1:
|
||||
use_browser = 1;
|
||||
@ -39,7 +96,7 @@ void exit_browser(bool wait_for_ok)
|
||||
{
|
||||
switch (use_browser) {
|
||||
case 2:
|
||||
perf_gtk__exit(wait_for_ok);
|
||||
exit_gtk_browser(wait_for_ok);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
@ -6,13 +6,14 @@
|
||||
#include <linux/compiler.h>
|
||||
|
||||
extern pthread_mutex_t ui__lock;
|
||||
extern void *perf_gtk_handle;
|
||||
|
||||
extern int use_browser;
|
||||
|
||||
void setup_browser(bool fallback_to_pager);
|
||||
void exit_browser(bool wait_for_ok);
|
||||
|
||||
#ifdef SLANG_SUPPORT
|
||||
#ifdef HAVE_SLANG_SUPPORT
|
||||
int ui__init(void);
|
||||
void ui__exit(bool wait_for_ok);
|
||||
#else
|
||||
@ -23,17 +24,6 @@ static inline int ui__init(void)
|
||||
static inline void ui__exit(bool wait_for_ok __maybe_unused) {}
|
||||
#endif
|
||||
|
||||
#ifdef GTK2_SUPPORT
|
||||
int perf_gtk__init(void);
|
||||
void perf_gtk__exit(bool wait_for_ok);
|
||||
#else
|
||||
static inline int perf_gtk__init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline void perf_gtk__exit(bool wait_for_ok __maybe_unused) {}
|
||||
#endif
|
||||
|
||||
void ui__refresh_dimensions(bool force);
|
||||
|
||||
#endif /* _PERF_UI_H_ */
|
||||
|
@ -40,7 +40,7 @@ else
|
||||
VC=unset
|
||||
fi
|
||||
test "$VN" = "$VC" || {
|
||||
echo >&2 "PERF_VERSION = $VN"
|
||||
echo >&2 " PERF_VERSION = $VN"
|
||||
echo "#define PERF_VERSION \"$VN\"" >$GVF
|
||||
}
|
||||
|
||||
|
@ -825,20 +825,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map,
|
||||
dl->ops.target.offset = dl->ops.target.addr -
|
||||
map__rip_2objdump(map, sym->start);
|
||||
|
||||
/*
|
||||
* kcore has no symbols, so add the call target name if it is on the
|
||||
* same map.
|
||||
*/
|
||||
/* kcore has no symbols, so add the call target name */
|
||||
if (dl->ins && ins__is_call(dl->ins) && !dl->ops.target.name) {
|
||||
struct symbol *s;
|
||||
u64 ip = dl->ops.target.addr;
|
||||
struct addr_map_symbol target = {
|
||||
.map = map,
|
||||
.addr = dl->ops.target.addr,
|
||||
};
|
||||
|
||||
if (ip >= map->start && ip <= map->end) {
|
||||
ip = map->map_ip(map, ip);
|
||||
s = map__find_symbol(map, ip, NULL);
|
||||
if (s && s->start == ip)
|
||||
dl->ops.target.name = strdup(s->name);
|
||||
}
|
||||
if (!map_groups__find_ams(&target, NULL) &&
|
||||
target.sym->start == target.al_addr)
|
||||
dl->ops.target.name = strdup(target.sym->name);
|
||||
}
|
||||
|
||||
disasm__add(¬es->src->source, dl);
|
||||
@ -879,6 +875,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
|
||||
FILE *file;
|
||||
int err = 0;
|
||||
char symfs_filename[PATH_MAX];
|
||||
struct kcore_extract kce;
|
||||
bool delete_extract = false;
|
||||
|
||||
if (filename) {
|
||||
snprintf(symfs_filename, sizeof(symfs_filename), "%s%s",
|
||||
@ -940,6 +938,23 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
|
||||
pr_debug("annotating [%p] %30s : [%p] %30s\n",
|
||||
dso, dso->long_name, sym, sym->name);
|
||||
|
||||
if (dso__is_kcore(dso)) {
|
||||
kce.kcore_filename = symfs_filename;
|
||||
kce.addr = map__rip_2objdump(map, sym->start);
|
||||
kce.offs = sym->start;
|
||||
kce.len = sym->end + 1 - sym->start;
|
||||
if (!kcore_extract__create(&kce)) {
|
||||
delete_extract = true;
|
||||
strlcpy(symfs_filename, kce.extract_filename,
|
||||
sizeof(symfs_filename));
|
||||
if (free_filename) {
|
||||
free(filename);
|
||||
free_filename = false;
|
||||
}
|
||||
filename = symfs_filename;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(command, sizeof(command),
|
||||
"%s %s%s --start-address=0x%016" PRIx64
|
||||
" --stop-address=0x%016" PRIx64
|
||||
@ -972,6 +987,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
|
||||
|
||||
pclose(file);
|
||||
out_free_filename:
|
||||
if (delete_extract)
|
||||
kcore_extract__delete(&kce);
|
||||
if (free_filename)
|
||||
free(filename);
|
||||
return err;
|
||||
@ -1070,7 +1087,7 @@ static void symbol__free_source_line(struct symbol *sym, int len)
|
||||
(sizeof(src_line->p) * (src_line->nr_pcnt - 1));
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
free(src_line->path);
|
||||
free_srcline(src_line->path);
|
||||
src_line = (void *)src_line + sizeof_src_line;
|
||||
}
|
||||
|
||||
@ -1081,13 +1098,11 @@ static void symbol__free_source_line(struct symbol *sym, int len)
|
||||
/* Get the filename:line for the colored entries */
|
||||
static int symbol__get_source_line(struct symbol *sym, struct map *map,
|
||||
struct perf_evsel *evsel,
|
||||
struct rb_root *root, int len,
|
||||
const char *filename)
|
||||
struct rb_root *root, int len)
|
||||
{
|
||||
u64 start;
|
||||
int i, k;
|
||||
int evidx = evsel->idx;
|
||||
char cmd[PATH_MAX * 2];
|
||||
struct source_line *src_line;
|
||||
struct annotation *notes = symbol__annotation(sym);
|
||||
struct sym_hist *h = annotation__histogram(notes, evidx);
|
||||
@ -1115,10 +1130,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
|
||||
start = map__rip_2objdump(map, sym->start);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
char *path = NULL;
|
||||
size_t line_len;
|
||||
u64 offset;
|
||||
FILE *fp;
|
||||
double percent_max = 0.0;
|
||||
|
||||
src_line->nr_pcnt = nr_pcnt;
|
||||
@ -1135,23 +1147,9 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
|
||||
goto next;
|
||||
|
||||
offset = start + i;
|
||||
sprintf(cmd, "addr2line -e %s %016" PRIx64, filename, offset);
|
||||
fp = popen(cmd, "r");
|
||||
if (!fp)
|
||||
goto next;
|
||||
|
||||
if (getline(&path, &line_len, fp) < 0 || !line_len)
|
||||
goto next_close;
|
||||
|
||||
src_line->path = malloc(sizeof(char) * line_len + 1);
|
||||
if (!src_line->path)
|
||||
goto next_close;
|
||||
|
||||
strcpy(src_line->path, path);
|
||||
src_line->path = get_srcline(map->dso, offset);
|
||||
insert_source_line(&tmp_root, src_line);
|
||||
|
||||
next_close:
|
||||
pclose(fp);
|
||||
next:
|
||||
src_line = (void *)src_line + sizeof_src_line;
|
||||
}
|
||||
@ -1192,7 +1190,7 @@ static void print_summary(struct rb_root *root, const char *filename)
|
||||
|
||||
path = src_line->path;
|
||||
color = get_percent_color(percent_max);
|
||||
color_fprintf(stdout, color, " %s", path);
|
||||
color_fprintf(stdout, color, " %s\n", path);
|
||||
|
||||
node = rb_next(node);
|
||||
}
|
||||
@ -1356,7 +1354,6 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
|
||||
bool full_paths, int min_pcnt, int max_lines)
|
||||
{
|
||||
struct dso *dso = map->dso;
|
||||
const char *filename = dso->long_name;
|
||||
struct rb_root source_line = RB_ROOT;
|
||||
u64 len;
|
||||
|
||||
@ -1366,9 +1363,8 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
|
||||
len = symbol__size(sym);
|
||||
|
||||
if (print_lines) {
|
||||
symbol__get_source_line(sym, map, evsel, &source_line,
|
||||
len, filename);
|
||||
print_summary(&source_line, filename);
|
||||
symbol__get_source_line(sym, map, evsel, &source_line, len);
|
||||
print_summary(&source_line, dso->long_name);
|
||||
}
|
||||
|
||||
symbol__annotate_printf(sym, map, evsel, full_paths,
|
||||
|
@ -150,7 +150,7 @@ int symbol__tty_annotate(struct symbol *sym, struct map *map,
|
||||
struct perf_evsel *evsel, bool print_lines,
|
||||
bool full_paths, int min_pcnt, int max_lines);
|
||||
|
||||
#ifdef SLANG_SUPPORT
|
||||
#ifdef HAVE_SLANG_SUPPORT
|
||||
int symbol__tui_annotate(struct symbol *sym, struct map *map,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
@ -165,30 +165,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GTK2_SUPPORT
|
||||
int symbol__gtk_annotate(struct symbol *sym, struct map *map,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
|
||||
static inline int hist_entry__gtk_annotate(struct hist_entry *he,
|
||||
struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt)
|
||||
{
|
||||
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evsel, hbt);
|
||||
}
|
||||
|
||||
void perf_gtk__show_annotations(void);
|
||||
#else
|
||||
static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
|
||||
struct perf_evsel *evsel __maybe_unused,
|
||||
struct hist_browser_timer *hbt __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void perf_gtk__show_annotations(void) {}
|
||||
#endif
|
||||
|
||||
extern const char *disassembler_style;
|
||||
|
||||
#endif /* __PERF_ANNOTATE_H */
|
||||
|
@ -70,8 +70,7 @@ extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2
|
||||
extern char *perf_pathdup(const char *fmt, ...)
|
||||
__attribute__((format (printf, 1, 2)));
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* Matches the libc/libbsd function attribute so we declare this unconditionally: */
|
||||
extern size_t strlcpy(char *dest, const char *src, size_t size);
|
||||
#endif
|
||||
|
||||
#endif /* __PERF_CACHE_H */
|
||||
|
@ -7,19 +7,20 @@
|
||||
char dso__symtab_origin(const struct dso *dso)
|
||||
{
|
||||
static const char origin[] = {
|
||||
[DSO_BINARY_TYPE__KALLSYMS] = 'k',
|
||||
[DSO_BINARY_TYPE__VMLINUX] = 'v',
|
||||
[DSO_BINARY_TYPE__JAVA_JIT] = 'j',
|
||||
[DSO_BINARY_TYPE__DEBUGLINK] = 'l',
|
||||
[DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
|
||||
[DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
|
||||
[DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
|
||||
[DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
|
||||
[DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
|
||||
[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
|
||||
[DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
|
||||
[DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
|
||||
[DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
|
||||
[DSO_BINARY_TYPE__KALLSYMS] = 'k',
|
||||
[DSO_BINARY_TYPE__VMLINUX] = 'v',
|
||||
[DSO_BINARY_TYPE__JAVA_JIT] = 'j',
|
||||
[DSO_BINARY_TYPE__DEBUGLINK] = 'l',
|
||||
[DSO_BINARY_TYPE__BUILD_ID_CACHE] = 'B',
|
||||
[DSO_BINARY_TYPE__FEDORA_DEBUGINFO] = 'f',
|
||||
[DSO_BINARY_TYPE__UBUNTU_DEBUGINFO] = 'u',
|
||||
[DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO] = 'o',
|
||||
[DSO_BINARY_TYPE__BUILDID_DEBUGINFO] = 'b',
|
||||
[DSO_BINARY_TYPE__SYSTEM_PATH_DSO] = 'd',
|
||||
[DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE] = 'K',
|
||||
[DSO_BINARY_TYPE__GUEST_KALLSYMS] = 'g',
|
||||
[DSO_BINARY_TYPE__GUEST_KMODULE] = 'G',
|
||||
[DSO_BINARY_TYPE__GUEST_VMLINUX] = 'V',
|
||||
};
|
||||
|
||||
if (dso == NULL || dso->symtab_type == DSO_BINARY_TYPE__NOT_FOUND)
|
||||
@ -64,6 +65,28 @@ int dso__binary_type_file(struct dso *dso, enum dso_binary_type type,
|
||||
symbol_conf.symfs, dso->long_name);
|
||||
break;
|
||||
|
||||
case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
|
||||
{
|
||||
char *last_slash;
|
||||
size_t len;
|
||||
size_t dir_size;
|
||||
|
||||
last_slash = dso->long_name + dso->long_name_len;
|
||||
while (last_slash != dso->long_name && *last_slash != '/')
|
||||
last_slash--;
|
||||
|
||||
len = scnprintf(file, size, "%s", symbol_conf.symfs);
|
||||
dir_size = last_slash - dso->long_name + 2;
|
||||
if (dir_size > (size - len)) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
len += scnprintf(file + len, dir_size, "%s", dso->long_name);
|
||||
len += scnprintf(file + len , size - len, ".debug%s",
|
||||
last_slash);
|
||||
break;
|
||||
}
|
||||
|
||||
case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
|
||||
if (!dso->has_build_id) {
|
||||
ret = -1;
|
||||
@ -427,6 +450,7 @@ struct dso *dso__new(const char *name)
|
||||
dso->rel = 0;
|
||||
dso->sorted_by_name = 0;
|
||||
dso->has_build_id = 0;
|
||||
dso->has_srcline = 1;
|
||||
dso->kernel = DSO_TYPE_USER;
|
||||
dso->needs_swap = DSO_SWAP__UNSET;
|
||||
INIT_LIST_HEAD(&dso->node);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <stdbool.h>
|
||||
#include "types.h"
|
||||
#include "map.h"
|
||||
#include "build-id.h"
|
||||
|
||||
enum dso_binary_type {
|
||||
DSO_BINARY_TYPE__KALLSYMS = 0,
|
||||
@ -23,6 +24,7 @@ enum dso_binary_type {
|
||||
DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE,
|
||||
DSO_BINARY_TYPE__KCORE,
|
||||
DSO_BINARY_TYPE__GUEST_KCORE,
|
||||
DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO,
|
||||
DSO_BINARY_TYPE__NOT_FOUND,
|
||||
};
|
||||
|
||||
@ -81,6 +83,7 @@ struct dso {
|
||||
enum dso_binary_type data_type;
|
||||
u8 adjust_symbols:1;
|
||||
u8 has_build_id:1;
|
||||
u8 has_srcline:1;
|
||||
u8 hit:1;
|
||||
u8 annotate_warned:1;
|
||||
u8 sname_alloc:1;
|
||||
|
@ -61,6 +61,12 @@ struct read_event {
|
||||
u64 id;
|
||||
};
|
||||
|
||||
struct throttle_event {
|
||||
struct perf_event_header header;
|
||||
u64 time;
|
||||
u64 id;
|
||||
u64 stream_id;
|
||||
};
|
||||
|
||||
#define PERF_SAMPLE_MASK \
|
||||
(PERF_SAMPLE_IP | PERF_SAMPLE_TID | \
|
||||
@ -69,6 +75,9 @@ struct read_event {
|
||||
PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD | \
|
||||
PERF_SAMPLE_IDENTIFIER)
|
||||
|
||||
/* perf sample has 16 bits size limit */
|
||||
#define PERF_SAMPLE_MAX_SIZE (1 << 16)
|
||||
|
||||
struct sample_event {
|
||||
struct perf_event_header header;
|
||||
u64 array[];
|
||||
@ -178,6 +187,7 @@ union perf_event {
|
||||
struct fork_event fork;
|
||||
struct lost_event lost;
|
||||
struct read_event read;
|
||||
struct throttle_event throttle;
|
||||
struct sample_event sample;
|
||||
struct attr_event attr;
|
||||
struct event_type_event event_type;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "parse-events.h"
|
||||
#include "parse-options.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
@ -49,6 +50,18 @@ struct perf_evlist *perf_evlist__new(void)
|
||||
return evlist;
|
||||
}
|
||||
|
||||
struct perf_evlist *perf_evlist__new_default(void)
|
||||
{
|
||||
struct perf_evlist *evlist = perf_evlist__new();
|
||||
|
||||
if (evlist && perf_evlist__add_default(evlist)) {
|
||||
perf_evlist__delete(evlist);
|
||||
evlist = NULL;
|
||||
}
|
||||
|
||||
return evlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* perf_evlist__set_id_pos - set the positions of event ids.
|
||||
* @evlist: selected event list
|
||||
@ -527,7 +540,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
|
||||
if ((old & md->mask) + size != ((old + size) & md->mask)) {
|
||||
unsigned int offset = old;
|
||||
unsigned int len = min(sizeof(*event), size), cpy;
|
||||
void *dst = &md->event_copy;
|
||||
void *dst = md->event_copy;
|
||||
|
||||
do {
|
||||
cpy = min(md->mask + 1 - (offset & md->mask), len);
|
||||
@ -537,7 +550,7 @@ union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
|
||||
len -= cpy;
|
||||
} while (len);
|
||||
|
||||
event = &md->event_copy;
|
||||
event = (union perf_event *) md->event_copy;
|
||||
}
|
||||
|
||||
old += size;
|
||||
@ -672,6 +685,59 @@ static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, in
|
||||
return -1;
|
||||
}
|
||||
|
||||
static size_t perf_evlist__mmap_size(unsigned long pages)
|
||||
{
|
||||
/* 512 kiB: default amount of unprivileged mlocked memory */
|
||||
if (pages == UINT_MAX)
|
||||
pages = (512 * 1024) / page_size;
|
||||
else if (!is_power_of_2(pages))
|
||||
return 0;
|
||||
|
||||
return (pages + 1) * page_size;
|
||||
}
|
||||
|
||||
int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
|
||||
int unset __maybe_unused)
|
||||
{
|
||||
unsigned int pages, val, *mmap_pages = opt->value;
|
||||
size_t size;
|
||||
static struct parse_tag tags[] = {
|
||||
{ .tag = 'B', .mult = 1 },
|
||||
{ .tag = 'K', .mult = 1 << 10 },
|
||||
{ .tag = 'M', .mult = 1 << 20 },
|
||||
{ .tag = 'G', .mult = 1 << 30 },
|
||||
{ .tag = 0 },
|
||||
};
|
||||
|
||||
val = parse_tag_value(str, tags);
|
||||
if (val != (unsigned int) -1) {
|
||||
/* we got file size value */
|
||||
pages = PERF_ALIGN(val, page_size) / page_size;
|
||||
if (!is_power_of_2(pages)) {
|
||||
pages = next_pow2(pages);
|
||||
pr_info("rounding mmap pages size to %u (%u pages)\n",
|
||||
pages * page_size, pages);
|
||||
}
|
||||
} else {
|
||||
/* we got pages count value */
|
||||
char *eptr;
|
||||
pages = strtoul(str, &eptr, 10);
|
||||
if (*eptr != '\0') {
|
||||
pr_err("failed to parse --mmap_pages/-m value\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
size = perf_evlist__mmap_size(pages);
|
||||
if (!size) {
|
||||
pr_err("--mmap_pages/-m value must be a power of two.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*mmap_pages = pages;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** perf_evlist__mmap - Create per cpu maps to receive events
|
||||
*
|
||||
* @evlist - list of events
|
||||
@ -695,14 +761,6 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
|
||||
const struct thread_map *threads = evlist->threads;
|
||||
int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE), mask;
|
||||
|
||||
/* 512 kiB: default amount of unprivileged mlocked memory */
|
||||
if (pages == UINT_MAX)
|
||||
pages = (512 * 1024) / page_size;
|
||||
else if (!is_power_of_2(pages))
|
||||
return -EINVAL;
|
||||
|
||||
mask = pages * page_size - 1;
|
||||
|
||||
if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -710,7 +768,9 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
|
||||
return -ENOMEM;
|
||||
|
||||
evlist->overwrite = overwrite;
|
||||
evlist->mmap_len = (pages + 1) * page_size;
|
||||
evlist->mmap_len = perf_evlist__mmap_size(pages);
|
||||
pr_debug("mmap size %luB\n", evlist->mmap_len);
|
||||
mask = evlist->mmap_len - page_size - 1;
|
||||
|
||||
list_for_each_entry(evsel, &evlist->entries, node) {
|
||||
if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
|
||||
|
@ -21,7 +21,7 @@ struct perf_mmap {
|
||||
void *base;
|
||||
int mask;
|
||||
unsigned int prev;
|
||||
union perf_event event_copy;
|
||||
char event_copy[PERF_SAMPLE_MAX_SIZE];
|
||||
};
|
||||
|
||||
struct perf_evlist {
|
||||
@ -31,7 +31,7 @@ struct perf_evlist {
|
||||
int nr_groups;
|
||||
int nr_fds;
|
||||
int nr_mmaps;
|
||||
int mmap_len;
|
||||
size_t mmap_len;
|
||||
int id_pos;
|
||||
int is_pos;
|
||||
u64 combined_sample_type;
|
||||
@ -53,6 +53,7 @@ struct perf_evsel_str_handler {
|
||||
};
|
||||
|
||||
struct perf_evlist *perf_evlist__new(void);
|
||||
struct perf_evlist *perf_evlist__new_default(void);
|
||||
void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
|
||||
struct thread_map *threads);
|
||||
void perf_evlist__exit(struct perf_evlist *evlist);
|
||||
@ -103,6 +104,10 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
|
||||
bool want_signal);
|
||||
int perf_evlist__start_workload(struct perf_evlist *evlist);
|
||||
|
||||
int perf_evlist__parse_mmap_pages(const struct option *opt,
|
||||
const char *str,
|
||||
int unset);
|
||||
|
||||
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
|
||||
bool overwrite);
|
||||
void perf_evlist__munmap(struct perf_evlist *evlist);
|
||||
|
@ -1456,6 +1456,9 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
|
||||
array = (void *)array + sz;
|
||||
OVERFLOW_CHECK_u64(array);
|
||||
data->user_stack.size = *array++;
|
||||
if (WARN_ONCE(data->user_stack.size > sz,
|
||||
"user stack dump failure\n"))
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ do
|
||||
}' "Documentation/perf-$cmd.txt"
|
||||
done
|
||||
|
||||
echo "#ifdef LIBELF_SUPPORT"
|
||||
echo "#ifdef HAVE_LIBELF_SUPPORT"
|
||||
sed -n -e 's/^perf-\([^ ]*\)[ ].* full.*/\1/p' command-list.txt |
|
||||
sort |
|
||||
while read cmd
|
||||
@ -35,5 +35,5 @@ do
|
||||
p
|
||||
}' "Documentation/perf-$cmd.txt"
|
||||
done
|
||||
echo "#endif /* LIBELF_SUPPORT */"
|
||||
echo "#endif /* HAVE_LIBELF_SUPPORT */"
|
||||
echo "};"
|
||||
|
@ -535,6 +535,7 @@ void hist_entry__free(struct hist_entry *he)
|
||||
{
|
||||
free(he->branch_info);
|
||||
free(he->mem_info);
|
||||
free_srcline(he->srcline);
|
||||
free(he);
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ struct hist_browser_timer {
|
||||
int refresh;
|
||||
};
|
||||
|
||||
#ifdef SLANG_SUPPORT
|
||||
#ifdef HAVE_SLANG_SUPPORT
|
||||
#include "../ui/keysyms.h"
|
||||
int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
@ -228,20 +228,5 @@ static inline int script_browse(const char *script_opt __maybe_unused)
|
||||
#define K_SWITCH_INPUT_DATA -3000
|
||||
#endif
|
||||
|
||||
#ifdef GTK2_SUPPORT
|
||||
int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
|
||||
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,
|
||||
float min_pcnt __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int hists__sort_list_width(struct hists *self);
|
||||
#endif /* __PERF_HIST_H */
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef _PERF_DWARF_REGS_H_
|
||||
#define _PERF_DWARF_REGS_H_
|
||||
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
const char *get_arch_regstr(unsigned int n);
|
||||
#endif
|
||||
|
||||
|
@ -2,20 +2,29 @@
|
||||
#define _PERF_LINUX_COMPILER_H_
|
||||
|
||||
#ifndef __always_inline
|
||||
#define __always_inline inline
|
||||
# define __always_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#define __user
|
||||
|
||||
#ifndef __attribute_const__
|
||||
#define __attribute_const__
|
||||
# define __attribute_const__
|
||||
#endif
|
||||
|
||||
#ifndef __maybe_unused
|
||||
#define __maybe_unused __attribute__((unused))
|
||||
# define __maybe_unused __attribute__((unused))
|
||||
#endif
|
||||
|
||||
#ifndef __packed
|
||||
# define __packed __attribute__((__packed__))
|
||||
#endif
|
||||
#define __packed __attribute__((__packed__))
|
||||
|
||||
#ifndef __force
|
||||
#define __force
|
||||
# define __force
|
||||
#endif
|
||||
|
||||
#ifndef __weak
|
||||
# define __weak __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,7 @@ static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
|
||||
|
||||
if (node != NULL) {
|
||||
node->i = i;
|
||||
node->priv = NULL;
|
||||
rc = &node->rb_node;
|
||||
}
|
||||
|
||||
@ -57,22 +58,36 @@ void intlist__remove(struct intlist *ilist, struct int_node *node)
|
||||
rblist__remove_node(&ilist->rblist, &node->rb_node);
|
||||
}
|
||||
|
||||
struct int_node *intlist__find(struct intlist *ilist, int i)
|
||||
static struct int_node *__intlist__findnew(struct intlist *ilist,
|
||||
int i, bool create)
|
||||
{
|
||||
struct int_node *node;
|
||||
struct int_node *node = NULL;
|
||||
struct rb_node *rb_node;
|
||||
|
||||
if (ilist == NULL)
|
||||
return NULL;
|
||||
|
||||
node = NULL;
|
||||
rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
|
||||
if (create)
|
||||
rb_node = rblist__findnew(&ilist->rblist, (void *)((long)i));
|
||||
else
|
||||
rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
|
||||
|
||||
if (rb_node)
|
||||
node = container_of(rb_node, struct int_node, rb_node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
struct int_node *intlist__find(struct intlist *ilist, int i)
|
||||
{
|
||||
return __intlist__findnew(ilist, i, false);
|
||||
}
|
||||
|
||||
struct int_node *intlist__findnew(struct intlist *ilist, int i)
|
||||
{
|
||||
return __intlist__findnew(ilist, i, true);
|
||||
}
|
||||
|
||||
static int intlist__parse_list(struct intlist *ilist, const char *s)
|
||||
{
|
||||
char *sep;
|
||||
|
@ -9,6 +9,7 @@
|
||||
struct int_node {
|
||||
struct rb_node rb_node;
|
||||
int i;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct intlist {
|
||||
@ -23,6 +24,7 @@ int intlist__add(struct intlist *ilist, int i);
|
||||
|
||||
struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx);
|
||||
struct int_node *intlist__find(struct intlist *ilist, int i);
|
||||
struct int_node *intlist__findnew(struct intlist *ilist, int i);
|
||||
|
||||
static inline bool intlist__has_entry(struct intlist *ilist, int i)
|
||||
{
|
||||
|
@ -46,6 +46,23 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct machine *machine__new_host(void)
|
||||
{
|
||||
struct machine *machine = malloc(sizeof(*machine));
|
||||
|
||||
if (machine != NULL) {
|
||||
machine__init(machine, "", HOST_KERNEL_ID);
|
||||
|
||||
if (machine__create_kernel_maps(machine) < 0)
|
||||
goto out_delete;
|
||||
}
|
||||
|
||||
return machine;
|
||||
out_delete:
|
||||
free(machine);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void dsos__delete(struct list_head *dsos)
|
||||
{
|
||||
struct dso *pos, *n;
|
||||
@ -776,75 +793,44 @@ static int machine__set_modules_path(struct machine *machine)
|
||||
return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
|
||||
}
|
||||
|
||||
static int machine__create_module(void *arg, const char *name, u64 start)
|
||||
{
|
||||
struct machine *machine = arg;
|
||||
struct map *map;
|
||||
|
||||
map = machine__new_module(machine, start, name);
|
||||
if (map == NULL)
|
||||
return -1;
|
||||
|
||||
dso__kernel_module_get_build_id(map->dso, machine->root_dir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int machine__create_modules(struct machine *machine)
|
||||
{
|
||||
char *line = NULL;
|
||||
size_t n;
|
||||
FILE *file;
|
||||
struct map *map;
|
||||
const char *modules;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (machine__is_default_guest(machine))
|
||||
if (machine__is_default_guest(machine)) {
|
||||
modules = symbol_conf.default_guest_modules;
|
||||
else {
|
||||
sprintf(path, "%s/proc/modules", machine->root_dir);
|
||||
} else {
|
||||
snprintf(path, PATH_MAX, "%s/proc/modules", machine->root_dir);
|
||||
modules = path;
|
||||
}
|
||||
|
||||
if (symbol__restricted_filename(modules, "/proc/modules"))
|
||||
return -1;
|
||||
|
||||
file = fopen(modules, "r");
|
||||
if (file == NULL)
|
||||
if (modules__parse(modules, machine, machine__create_module))
|
||||
return -1;
|
||||
|
||||
while (!feof(file)) {
|
||||
char name[PATH_MAX];
|
||||
u64 start;
|
||||
char *sep;
|
||||
int line_len;
|
||||
if (!machine__set_modules_path(machine))
|
||||
return 0;
|
||||
|
||||
line_len = getline(&line, &n, file);
|
||||
if (line_len < 0)
|
||||
break;
|
||||
pr_debug("Problems setting modules path maps, continuing anyway...\n");
|
||||
|
||||
if (!line)
|
||||
goto out_failure;
|
||||
|
||||
line[--line_len] = '\0'; /* \n */
|
||||
|
||||
sep = strrchr(line, 'x');
|
||||
if (sep == NULL)
|
||||
continue;
|
||||
|
||||
hex2u64(sep + 1, &start);
|
||||
|
||||
sep = strchr(line, ' ');
|
||||
if (sep == NULL)
|
||||
continue;
|
||||
|
||||
*sep = '\0';
|
||||
|
||||
snprintf(name, sizeof(name), "[%s]", line);
|
||||
map = machine__new_module(machine, start, name);
|
||||
if (map == NULL)
|
||||
goto out_delete_line;
|
||||
dso__kernel_module_get_build_id(map->dso, machine->root_dir);
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(file);
|
||||
|
||||
if (machine__set_modules_path(machine) < 0) {
|
||||
pr_debug("Problems setting modules path maps, continuing anyway...\n");
|
||||
}
|
||||
return 0;
|
||||
|
||||
out_delete_line:
|
||||
free(line);
|
||||
out_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int machine__create_kernel_maps(struct machine *machine)
|
||||
@ -1376,3 +1362,26 @@ int machine__resolve_callchain(struct machine *machine,
|
||||
sample);
|
||||
|
||||
}
|
||||
|
||||
int machine__for_each_thread(struct machine *machine,
|
||||
int (*fn)(struct thread *thread, void *p),
|
||||
void *priv)
|
||||
{
|
||||
struct rb_node *nd;
|
||||
struct thread *thread;
|
||||
int rc = 0;
|
||||
|
||||
for (nd = rb_first(&machine->threads); nd; nd = rb_next(nd)) {
|
||||
thread = rb_entry(nd, struct thread, rb_node);
|
||||
rc = fn(thread, priv);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
list_for_each_entry(thread, &machine->dead_threads, node) {
|
||||
rc = fn(thread, priv);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size);
|
||||
void machines__set_symbol_filter(struct machines *machines,
|
||||
symbol_filter_t symbol_filter);
|
||||
|
||||
struct machine *machine__new_host(void);
|
||||
int machine__init(struct machine *machine, const char *root_dir, pid_t pid);
|
||||
void machine__exit(struct machine *machine);
|
||||
void machine__delete_dead_threads(struct machine *machine);
|
||||
@ -165,4 +166,8 @@ void machines__destroy_kernel_maps(struct machines *machines);
|
||||
|
||||
size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp);
|
||||
|
||||
int machine__for_each_thread(struct machine *machine,
|
||||
int (*fn)(struct thread *thread, void *p),
|
||||
void *priv);
|
||||
|
||||
#endif /* __PERF_MACHINE_H */
|
||||
|
@ -172,7 +172,7 @@ int map__load(struct map *map, symbol_filter_t filter)
|
||||
pr_warning(", continuing without symbols\n");
|
||||
return -1;
|
||||
} else if (nr == 0) {
|
||||
#ifdef LIBELF_SUPPORT
|
||||
#ifdef HAVE_LIBELF_SUPPORT
|
||||
const size_t len = strlen(name);
|
||||
const size_t real_len = len - sizeof(DSO__DELETED);
|
||||
|
||||
@ -252,10 +252,16 @@ size_t map__fprintf_dsoname(struct map *map, FILE *fp)
|
||||
return fprintf(fp, "%s", dsoname);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* map__rip_2objdump - convert symbol start address to objdump address.
|
||||
* @map: memory map
|
||||
* @rip: symbol start address
|
||||
*
|
||||
* objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
|
||||
* map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
|
||||
* relative to section start.
|
||||
*
|
||||
* Return: Address suitable for passing to "objdump --start-address="
|
||||
*/
|
||||
u64 map__rip_2objdump(struct map *map, u64 rip)
|
||||
{
|
||||
@ -268,6 +274,29 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
|
||||
return map->unmap_ip(map, rip);
|
||||
}
|
||||
|
||||
/**
|
||||
* map__objdump_2mem - convert objdump address to a memory address.
|
||||
* @map: memory map
|
||||
* @ip: objdump address
|
||||
*
|
||||
* Closely related to map__rip_2objdump(), this function takes an address from
|
||||
* objdump and converts it to a memory address. Note this assumes that @map
|
||||
* contains the address. To be sure the result is valid, check it forwards
|
||||
* e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
|
||||
*
|
||||
* Return: Memory address.
|
||||
*/
|
||||
u64 map__objdump_2mem(struct map *map, u64 ip)
|
||||
{
|
||||
if (!map->dso->adjust_symbols)
|
||||
return map->unmap_ip(map, ip);
|
||||
|
||||
if (map->dso->rel)
|
||||
return map->unmap_ip(map, ip + map->pgoff);
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
void map_groups__init(struct map_groups *mg)
|
||||
{
|
||||
int i;
|
||||
@ -371,6 +400,23 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter)
|
||||
{
|
||||
if (ams->addr < ams->map->start || ams->addr > ams->map->end) {
|
||||
if (ams->map->groups == NULL)
|
||||
return -1;
|
||||
ams->map = map_groups__find(ams->map->groups, ams->map->type,
|
||||
ams->addr);
|
||||
if (ams->map == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
|
||||
ams->sym = map__find_symbol(ams->map, ams->al_addr, filter);
|
||||
|
||||
return ams->sym ? 0 : -1;
|
||||
}
|
||||
|
||||
size_t __map_groups__fprintf_maps(struct map_groups *mg,
|
||||
enum map_type type, int verbose, FILE *fp)
|
||||
{
|
||||
|
@ -84,6 +84,9 @@ static inline u64 identity__map_ip(struct map *map __maybe_unused, u64 ip)
|
||||
/* rip/ip <-> addr suitable for passing to `objdump --start-address=` */
|
||||
u64 map__rip_2objdump(struct map *map, u64 rip);
|
||||
|
||||
/* objdump address -> memory address */
|
||||
u64 map__objdump_2mem(struct map *map, u64 ip);
|
||||
|
||||
struct symbol;
|
||||
|
||||
typedef int (*symbol_filter_t)(struct map *map, struct symbol *sym);
|
||||
@ -167,6 +170,10 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
|
||||
struct map **mapp,
|
||||
symbol_filter_t filter);
|
||||
|
||||
struct addr_map_symbol;
|
||||
|
||||
int map_groups__find_ams(struct addr_map_symbol *ams, symbol_filter_t filter);
|
||||
|
||||
static inline
|
||||
struct symbol *map_groups__find_function_by_name(struct map_groups *mg,
|
||||
const char *name, struct map **mapp,
|
||||
|
@ -126,6 +126,37 @@ modifier_bp [rwx]{1,3}
|
||||
|
||||
}
|
||||
|
||||
<config>{
|
||||
config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
|
||||
config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
|
||||
config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
|
||||
name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
|
||||
period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
|
||||
branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
|
||||
, { return ','; }
|
||||
"/" { BEGIN(INITIAL); return '/'; }
|
||||
{name_minus} { return str(yyscanner, PE_NAME); }
|
||||
}
|
||||
|
||||
<mem>{
|
||||
{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
|
||||
: { return ':'; }
|
||||
{num_dec} { return value(yyscanner, 10); }
|
||||
{num_hex} { return value(yyscanner, 16); }
|
||||
/*
|
||||
* We need to separate 'mem:' scanner part, in order to get specific
|
||||
* modifier bits parsed out. Otherwise we would need to handle PE_NAME
|
||||
* and we'd need to parse it manually. During the escape from <mem>
|
||||
* state we need to put the escaping char back, so we dont miss it.
|
||||
*/
|
||||
. { unput(*yytext); BEGIN(INITIAL); }
|
||||
/*
|
||||
* We destroy the scanner after reaching EOF,
|
||||
* but anyway just to be sure get back to INIT state.
|
||||
*/
|
||||
<<EOF>> { BEGIN(INITIAL); }
|
||||
}
|
||||
|
||||
cpu-cycles|cycles { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES); }
|
||||
stalled-cycles-frontend|idle-cycles-frontend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND); }
|
||||
stalled-cycles-backend|idle-cycles-backend { return sym(yyscanner, PERF_TYPE_HARDWARE, PERF_COUNT_HW_STALLED_CYCLES_BACKEND); }
|
||||
@ -162,18 +193,6 @@ speculative-read|speculative-load |
|
||||
refs|Reference|ops|access |
|
||||
misses|miss { return str(yyscanner, PE_NAME_CACHE_OP_RESULT); }
|
||||
|
||||
<config>{
|
||||
config { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG); }
|
||||
config1 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG1); }
|
||||
config2 { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_CONFIG2); }
|
||||
name { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_NAME); }
|
||||
period { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD); }
|
||||
branch_type { return term(yyscanner, PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE); }
|
||||
, { return ','; }
|
||||
"/" { BEGIN(INITIAL); return '/'; }
|
||||
{name_minus} { return str(yyscanner, PE_NAME); }
|
||||
}
|
||||
|
||||
mem: { BEGIN(mem); return PE_PREFIX_MEM; }
|
||||
r{num_raw_hex} { return raw(yyscanner); }
|
||||
{num_dec} { return value(yyscanner, 10); }
|
||||
@ -189,25 +208,7 @@ r{num_raw_hex} { return raw(yyscanner); }
|
||||
"}" { return '}'; }
|
||||
= { return '='; }
|
||||
\n { }
|
||||
|
||||
<mem>{
|
||||
{modifier_bp} { return str(yyscanner, PE_MODIFIER_BP); }
|
||||
: { return ':'; }
|
||||
{num_dec} { return value(yyscanner, 10); }
|
||||
{num_hex} { return value(yyscanner, 16); }
|
||||
/*
|
||||
* We need to separate 'mem:' scanner part, in order to get specific
|
||||
* modifier bits parsed out. Otherwise we would need to handle PE_NAME
|
||||
* and we'd need to parse it manually. During the escape from <mem>
|
||||
* state we need to put the escaping char back, so we dont miss it.
|
||||
*/
|
||||
. { unput(*yytext); BEGIN(INITIAL); }
|
||||
/*
|
||||
* We destroy the scanner after reaching EOF,
|
||||
* but anyway just to be sure get back to INIT state.
|
||||
*/
|
||||
<<EOF>> { BEGIN(INITIAL); }
|
||||
}
|
||||
. { }
|
||||
|
||||
%%
|
||||
|
||||
|
@ -22,19 +22,23 @@ static const char *get_perf_dir(void)
|
||||
return ".";
|
||||
}
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
/*
|
||||
* If libc has strlcpy() then that version will override this
|
||||
* implementation:
|
||||
*/
|
||||
size_t __weak strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t ret = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (ret >= size) ? size - 1 : ret;
|
||||
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *get_pathname(void)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __PERF_REGS_H
|
||||
#define __PERF_REGS_H
|
||||
|
||||
#ifdef HAVE_PERF_REGS
|
||||
#ifdef HAVE_PERF_REGS_SUPPORT
|
||||
#include <perf_regs.h>
|
||||
#else
|
||||
#define PERF_REGS_MASK 0
|
||||
@ -10,5 +10,5 @@ static inline const char *perf_reg_name(int id __maybe_unused)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* HAVE_PERF_REGS */
|
||||
#endif /* HAVE_PERF_REGS_SUPPORT */
|
||||
#endif /* __PERF_REGS_H */
|
||||
|
@ -201,7 +201,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
/* Open new debuginfo of given module */
|
||||
static struct debuginfo *open_debuginfo(const char *module)
|
||||
{
|
||||
@ -630,7 +630,7 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* !DWARF_SUPPORT */
|
||||
#else /* !HAVE_DWARF_SUPPORT */
|
||||
|
||||
static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
|
||||
struct perf_probe_point *pp)
|
||||
|
@ -14,7 +14,7 @@ static inline int is_c_varname(const char *name)
|
||||
return isalpha(name[0]) || name[0] == '_';
|
||||
}
|
||||
|
||||
#ifdef DWARF_SUPPORT
|
||||
#ifdef HAVE_DWARF_SUPPORT
|
||||
|
||||
#include "dwarf-aux.h"
|
||||
|
||||
@ -105,6 +105,6 @@ struct line_finder {
|
||||
int found;
|
||||
};
|
||||
|
||||
#endif /* DWARF_SUPPORT */
|
||||
#endif /* HAVE_DWARF_SUPPORT */
|
||||
|
||||
#endif /*_PROBE_FINDER_H */
|
||||
|
@ -33,13 +33,6 @@ int eprintf(int level, const char *fmt, ...)
|
||||
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
|
||||
#endif
|
||||
|
||||
struct throttle_event {
|
||||
struct perf_event_header header;
|
||||
u64 time;
|
||||
u64 id;
|
||||
u64 stream_id;
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC initperf(void);
|
||||
|
||||
#define member_def(type, member, ptype, help) \
|
||||
@ -1036,6 +1029,7 @@ PyMODINIT_FUNC initperf(void)
|
||||
pyrf_cpu_map__setup_types() < 0)
|
||||
return;
|
||||
|
||||
/* The page_size is placed in util object. */
|
||||
page_size = sysconf(_SC_PAGE_SIZE);
|
||||
|
||||
Py_INCREF(&pyrf_evlist__type);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user