From 89fe808ae777728da6e1d78b7d13562792310d17 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 12:07:11 +0200 Subject: [PATCH 001/161] tools/perf: Standardize feature support define names to: HAVE_{FEATURE}_SUPPORT Standardize all the feature flags based on the HAVE_{FEATURE}_SUPPORT naming convention: HAVE_ARCH_X86_64_SUPPORT HAVE_BACKTRACE_SUPPORT HAVE_CPLUS_DEMANGLE_SUPPORT HAVE_DWARF_SUPPORT HAVE_ELF_GETPHDRNUM_SUPPORT HAVE_GTK2_SUPPORT HAVE_GTK_INFO_BAR_SUPPORT HAVE_LIBAUDIT_SUPPORT HAVE_LIBELF_MMAP_SUPPORT HAVE_LIBELF_SUPPORT HAVE_LIBNUMA_SUPPORT HAVE_LIBUNWIND_SUPPORT HAVE_ON_EXIT_SUPPORT HAVE_PERF_REGS_SUPPORT HAVE_SLANG_SUPPORT HAVE_STRLCPY_SUPPORT Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-u3zvqejddfZhtrbYbfhi3spa@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/arch/x86/include/perf_regs.h | 6 +-- tools/perf/arch/x86/util/unwind.c | 4 +- tools/perf/bench/mem-memcpy-arch.h | 2 +- tools/perf/bench/mem-memcpy.c | 2 +- tools/perf/bench/mem-memset-arch.h | 2 +- tools/perf/bench/mem-memset.c | 2 +- tools/perf/builtin-bench.c | 4 +- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-probe.c | 14 +++---- tools/perf/builtin-record.c | 12 +++--- tools/perf/config/Makefile | 54 ++++++++++++------------- tools/perf/perf.c | 4 +- tools/perf/ui/gtk/browser.c | 2 +- tools/perf/ui/gtk/gtk.h | 4 +- tools/perf/ui/gtk/util.c | 4 +- tools/perf/ui/ui.h | 4 +- tools/perf/util/annotate.h | 4 +- tools/perf/util/cache.h | 2 +- tools/perf/util/generate-cmdlist.sh | 4 +- tools/perf/util/hist.h | 4 +- tools/perf/util/include/dwarf-regs.h | 2 +- tools/perf/util/map.c | 2 +- tools/perf/util/path.c | 2 +- tools/perf/util/perf_regs.h | 4 +- tools/perf/util/probe-event.c | 4 +- tools/perf/util/probe-finder.h | 4 +- tools/perf/util/symbol-elf.c | 2 +- tools/perf/util/symbol.h | 8 ++-- tools/perf/util/unwind.h | 4 +- tools/perf/util/util.c | 4 +- 30 files changed, 86 insertions(+), 86 deletions(-) diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h index 7fcdcdbee917..e84ca76aae77 100644 --- a/tools/perf/arch/x86/include/perf_regs.h +++ b/tools/perf/arch/x86/include/perf_regs.h @@ -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; } diff --git a/tools/perf/arch/x86/util/unwind.c b/tools/perf/arch/x86/util/unwind.c index 78d956eff96f..456a88cf5b37 100644 --- a/tools/perf/arch/x86/util/unwind.c +++ b/tools/perf/arch/x86/util/unwind.c @@ -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 */ diff --git a/tools/perf/bench/mem-memcpy-arch.h b/tools/perf/bench/mem-memcpy-arch.h index a72e36cb5394..57b4ed871459 100644 --- a/tools/perf/bench/mem-memcpy-arch.h +++ b/tools/perf/bench/mem-memcpy-arch.h @@ -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); diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c index 8cdca43016b2..5ce71d3b72cf 100644 --- a/tools/perf/bench/mem-memcpy.c +++ b/tools/perf/bench/mem-memcpy.c @@ -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" diff --git a/tools/perf/bench/mem-memset-arch.h b/tools/perf/bench/mem-memset-arch.h index a040fa77665b..633800cb0dcb 100644 --- a/tools/perf/bench/mem-memset-arch.h +++ b/tools/perf/bench/mem-memset-arch.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); diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c index 4a2f12081964..9af79d2b18e5 100644 --- a/tools/perf/bench/mem-memset.c +++ b/tools/perf/bench/mem-memset.c @@ -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" diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index 77298bf892b8..33af80fa49cf 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -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 }, diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index afe377b2884f..f51a9637f69b 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -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); diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index e8a66f9a6715..89acc17cf2a0 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -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" diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index a78db3f31b25..cf36ba2a1591 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -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 @@ -687,7 +687,7 @@ error: return ret; } -#ifdef LIBUNWIND_SUPPORT +#ifdef HAVE_LIBUNWIND_SUPPORT static int get_stack_size(char *str, unsigned long *_size) { char *endptr; @@ -713,7 +713,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 +751,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 +771,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 +818,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]"; diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5f6f9b3271bb..34be7432d567 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -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),) @@ -175,13 +175,13 @@ endif # SOURCE_LIBELF endif # NO_LIBELF ifndef NO_LIBELF -CFLAGS += -DLIBELF_SUPPORT +CFLAGS += -DHAVE_LIBELF_SUPPORT FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y) - CFLAGS += -DLIBELF_MMAP +ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) + CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT endif -ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM),y) - CFLAGS += -DHAVE_ELF_GETPHDRNUM +ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM_SUPPORT),y) + CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT endif # include ARCH specific config @@ -192,7 +192,7 @@ 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) + CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) EXTLIBS += -lelf -ldw endif # PERF_HAVE_DWARF_REGS @@ -201,10 +201,10 @@ endif # NO_DWARF endif # NO_LIBELF ifndef NO_LIBELF -CFLAGS += -DLIBELF_SUPPORT +CFLAGS += -DHAVE_LIBELF_SUPPORT FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y) - CFLAGS += -DLIBELF_MMAP +ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) + CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT endif # try-cc endif # NO_LIBELF @@ -229,7 +229,7 @@ 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) @@ -241,7 +241,7 @@ ifndef NO_LIBAUDIT 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 @@ -258,7 +258,7 @@ ifndef NO_SLANG 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 @@ -269,10 +269,10 @@ ifndef NO_GTK2 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 ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR_SUPPORT),y) + CFLAGS += -DHAVE_GTK_INFO_BAR_SUPPORT endif - CFLAGS += -DGTK2_SUPPORT + CFLAGS += -DHAVE_GTK2_SUPPORT CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null) EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null) endif @@ -365,9 +365,9 @@ 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) @@ -388,7 +388,7 @@ else has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle) ifeq ($(has_cplus_demangle),y) 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 @@ -400,20 +400,20 @@ else endif ifndef NO_STRLCPY - ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y) - CFLAGS += -DHAVE_STRLCPY + ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY_SUPPORT),y) + CFLAGS += -DHAVE_STRLCPY_SUPPORT endif endif ifndef NO_ON_EXIT - ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y) - CFLAGS += -DHAVE_ON_EXIT + ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT_SUPPORT),y) + CFLAGS += -DHAVE_ON_EXIT_SUPPORT endif endif ifndef NO_BACKTRACE - ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y) - CFLAGS += -DBACKTRACE_SUPPORT + ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DHAVE_BACKTRACE_SUPPORT),y) + CFLAGS += -DHAVE_BACKTRACE_SUPPORT endif endif @@ -423,7 +423,7 @@ ifndef NO_LIBNUMA 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 diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 85e1aed95204..245020cc6180 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -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 }, diff --git a/tools/perf/ui/gtk/browser.c b/tools/perf/ui/gtk/browser.c index c95012cdb438..c24d91221290 100644 --- a/tools/perf/ui/gtk/browser.c +++ b/tools/perf/ui/gtk/browser.c @@ -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; diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index 3d96785ef155..a72acbc565e0 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -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 @@ -39,7 +39,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) diff --git a/tools/perf/ui/gtk/util.c b/tools/perf/ui/gtk/util.c index c06942a41c78..696c1fbe4248 100644 --- a/tools/perf/ui/gtk/util.c +++ b/tools/perf/ui/gtk/util.c @@ -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, diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h index 70cb0d4eb8aa..1349d142a005 100644 --- a/tools/perf/ui/ui.h +++ b/tools/perf/ui/ui.h @@ -12,7 +12,7 @@ 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,7 +23,7 @@ static inline int ui__init(void) static inline void ui__exit(bool wait_for_ok __maybe_unused) {} #endif -#ifdef GTK2_SUPPORT +#ifdef HAVE_GTK2_SUPPORT int perf_gtk__init(void); void perf_gtk__exit(bool wait_for_ok); #else diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index af755156d278..f0699e9bcc6f 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -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,7 +165,7 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, } #endif -#ifdef GTK2_SUPPORT +#ifdef HAVE_GTK2_SUPPORT int symbol__gtk_annotate(struct symbol *sym, struct map *map, struct perf_evsel *evsel, struct hist_browser_timer *hbt); diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 26e367239873..442953c1ce85 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -70,7 +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 +#ifndef HAVE_STRLCPY_SUPPORT extern size_t strlcpy(char *dest, const char *src, size_t size); #endif diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh index 3ac38031d534..36a885d2cd22 100755 --- a/tools/perf/util/generate-cmdlist.sh +++ b/tools/perf/util/generate-cmdlist.sh @@ -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 "};" diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 6a048c09cd64..ed4f90ebe0d5 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -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,7 +228,7 @@ static inline int script_browse(const char *script_opt __maybe_unused) #define K_SWITCH_INPUT_DATA -3000 #endif -#ifdef GTK2_SUPPORT +#ifdef HAVE_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); diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h index cf6727e99c44..8f149655f497 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.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 diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 4f6680d2043b..17ee458a0870 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -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); diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c index a8c49548ca48..f3958743b743 100644 --- a/tools/perf/util/path.c +++ b/tools/perf/util/path.c @@ -22,7 +22,7 @@ static const char *get_perf_dir(void) return "."; } -#ifndef HAVE_STRLCPY +#ifndef HAVE_STRLCPY_SUPPORT size_t strlcpy(char *dest, const char *src, size_t size) { size_t ret = strlen(src); diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 5a4f2b6f3738..a3d42cd74919 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -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 */ diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index aa04bf9c9ad7..779b2dacd43f 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -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) diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index 3b7d63018960..3f0c29dd6ac5 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -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 */ diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index a9c829be5216..c37693052800 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -8,7 +8,7 @@ #include "symbol.h" #include "debug.h" -#ifndef HAVE_ELF_GETPHDRNUM +#ifndef HAVE_ELF_GETPHDRNUM_SUPPORT static int elf_getphdrnum(Elf *elf, size_t *dst) { GElf_Ehdr gehdr; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index fd5b70ea2981..2a97bb1a8097 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -13,7 +13,7 @@ #include <libgen.h> #include "build-id.h" -#ifdef LIBELF_SUPPORT +#ifdef HAVE_LIBELF_SUPPORT #include <libelf.h> #include <gelf.h> #endif @@ -21,7 +21,7 @@ #include "dso.h" -#ifdef HAVE_CPLUS_DEMANGLE +#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT extern char *cplus_demangle(const char *, int); static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i) @@ -46,7 +46,7 @@ static inline char *bfd_demangle(void __maybe_unused *v, * libelf 0.8.x and earlier do not support ELF_C_READ_MMAP; * for newer versions we can use mmap to reduce memory usage: */ -#ifdef LIBELF_MMAP +#ifdef HAVE_LIBELF_MMAP_SUPPORT # define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP #else # define PERF_ELF_C_READ_MMAP ELF_C_READ @@ -178,7 +178,7 @@ struct symsrc { int fd; enum dso_binary_type type; -#ifdef LIBELF_SUPPORT +#ifdef HAVE_LIBELF_SUPPORT Elf *elf; GElf_Ehdr ehdr; diff --git a/tools/perf/util/unwind.h b/tools/perf/util/unwind.h index cb6bc503a792..ec0c71a2ca2e 100644 --- a/tools/perf/util/unwind.h +++ b/tools/perf/util/unwind.h @@ -13,7 +13,7 @@ struct unwind_entry { typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg); -#ifdef LIBUNWIND_SUPPORT +#ifdef HAVE_LIBUNWIND_SUPPORT int unwind__get_entries(unwind_entry_cb_t cb, void *arg, struct machine *machine, struct thread *thread, @@ -31,5 +31,5 @@ unwind__get_entries(unwind_entry_cb_t cb __maybe_unused, { return 0; } -#endif /* LIBUNWIND_SUPPORT */ +#endif /* HAVE_LIBUNWIND_SUPPORT */ #endif /* __UNWIND_H */ diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 6d17b18e915d..ccfdeb62f576 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,7 +1,7 @@ #include "../perf.h" #include "util.h" #include <sys/mman.h> -#ifdef BACKTRACE_SUPPORT +#ifdef HAVE_BACKTRACE_SUPPORT #include <execinfo.h> #endif #include <stdio.h> @@ -204,7 +204,7 @@ int hex2u64(const char *ptr, u64 *long_val) } /* Obtain a backtrace and print it to stdout. */ -#ifdef BACKTRACE_SUPPORT +#ifdef HAVE_BACKTRACE_SUPPORT void dump_stack(void) { void *array[16]; From b6aa9979416e2e98a800925d60ad00e83bc7cb7a Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 10:08:24 +0200 Subject: [PATCH 002/161] tools/perf/build: Add feature check core code Start the split-out of the feature check code by adding a list of features to be tested, and rules to process that list by building its matching feature-check file in config/feature-checks/test-<feature>.c. Add 'hello' as the initial feature. This structure will allow us to build split-out feature checks in parallel and thus speed up feature detection dramatically. No change in functionality: no feature check is used by the build rules yet. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-pixkihgscFaohfFigq5yt9gs@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 16 ++++++++++++++++ tools/perf/config/feature-checks/Makefile | 16 ++++++++++++++++ tools/perf/config/feature-checks/test-hello.c | 6 ++++++ 3 files changed, 38 insertions(+) create mode 100644 tools/perf/config/feature-checks/Makefile create mode 100644 tools/perf/config/feature-checks/test-hello.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 34be7432d567..daefe2dfacad 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -89,6 +89,22 @@ CFLAGS += -std=gnu99 EXTLIBS = -lelf -lpthread -lrt -lm -ldl +feature_check = $(eval $(feature_check_code)); $(info CHK: config/feature-checks/test-$(1)) +define feature_check_code + feature-$(2) := $(shell make -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) +endef + +# +# Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output: +# +$(info Testing features:) +$(shell make -i -j -C config/feature-checks >/dev/null 2>&1) +$(info done) + +FEATURE_TESTS = hello + +$(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) + ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) CFLAGS += -fstack-protector-all endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile new file mode 100644 index 000000000000..b3f6372ad8b0 --- /dev/null +++ b/tools/perf/config/feature-checks/Makefile @@ -0,0 +1,16 @@ + +FILES=test-hello + +all: $(FILES) + +BUILD = $(CC) -o $(OUTPUT)$@ $@.c + +############################### + +test-hello: test-hello.c + $(BUILD) + +############################### + +clean: + rm -f $(FILES) diff --git a/tools/perf/config/feature-checks/test-hello.c b/tools/perf/config/feature-checks/test-hello.c new file mode 100644 index 000000000000..c9f398d87868 --- /dev/null +++ b/tools/perf/config/feature-checks/test-hello.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} From 8b6eb56a9570001634df1d2c7f38e7179a357362 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 13:51:28 +0200 Subject: [PATCH 003/161] tools/perf/build: Add 'autodep' functionality, generate feature test dependencies automatically Use GCC's -MD feature to generate a dependency file for each feature test .c file, and include that .d file in the config/feature-checks/Makefile. This allows us to do two things: - speed up feature tests - detect removal or changes in build dependencies - including system libraries/headers Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-Jfma8pmPnnqzpxjbs3hpgmsj@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/feature-checks/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index b3f6372ad8b0..4708ccadfc54 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -1,16 +1,20 @@ FILES=test-hello +CC := $(CC) -MD + all: $(FILES) BUILD = $(CC) -o $(OUTPUT)$@ $@.c ############################### -test-hello: test-hello.c +test-hello: $(BUILD) +-include *.d */*.d + ############################### clean: - rm -f $(FILES) + rm -f $(FILES) *.d From 3ae069cfda88349fa61de9631f878d39ab60764f Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 13:37:10 +0200 Subject: [PATCH 004/161] tools/perf/build: Split out feature check: 'libnuma' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-vixsrpggxFjhz7kppqgrGr6s@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 7 ++++--- tools/perf/config/feature-checks/Makefile | 7 ++++++- tools/perf/config/feature-checks/test-libnuma.c | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libnuma.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index daefe2dfacad..f39fc224b52e 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -101,7 +101,9 @@ $(info Testing features:) $(shell make -i -j -C config/feature-checks >/dev/null 2>&1) $(info done) -FEATURE_TESTS = hello +FEATURE_TESTS = \ + hello \ + libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -434,8 +436,7 @@ ifndef NO_BACKTRACE 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 4708ccadfc54..6a42ad24d64f 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -1,5 +1,7 @@ -FILES=test-hello +FILES= \ + test-hello \ + test-libnuma CC := $(CC) -MD @@ -12,6 +14,9 @@ BUILD = $(CC) -o $(OUTPUT)$@ $@.c test-hello: $(BUILD) +test-libnuma: + $(BUILD) -lnuma + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libnuma.c b/tools/perf/config/feature-checks/test-libnuma.c new file mode 100644 index 000000000000..70510a923e5a --- /dev/null +++ b/tools/perf/config/feature-checks/test-libnuma.c @@ -0,0 +1,8 @@ +#include <numa.h> +#include <numaif.h> + +int main(void) +{ + numa_available(); + return 0; +} From 90ac5422b617fcab0c6f02249502ffc17dfbf6e3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 13:48:44 +0200 Subject: [PATCH 005/161] tools/perf/build: Split out feature check: 'stackprotector-all' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-gupddm9clctVYws3lyexfdhg@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-stackprotector-all.c | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-stackprotector-all.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index f39fc224b52e..1a6737144149 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -103,11 +103,12 @@ $(info done) FEATURE_TESTS = \ hello \ + stackprotector-all \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) -ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) +ifeq ($(feature-stackprotector-all), 1) CFLAGS += -fstack-protector-all endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 6a42ad24d64f..7538c148b40c 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -1,6 +1,7 @@ FILES= \ test-hello \ + test-stackprotector-all \ test-libnuma CC := $(CC) -MD @@ -14,6 +15,9 @@ BUILD = $(CC) -o $(OUTPUT)$@ $@.c test-hello: $(BUILD) +test-stackprotector-all: + $(BUILD) -Werror -fstack-protector-all + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-stackprotector-all.c b/tools/perf/config/feature-checks/test-stackprotector-all.c new file mode 100644 index 000000000000..c9f398d87868 --- /dev/null +++ b/tools/perf/config/feature-checks/test-stackprotector-all.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} From 430be5ab0a50a9116c689b2b2ea7acd7a635aabe Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 09:47:00 +0200 Subject: [PATCH 006/161] tools/perf/build: Split out feature check: 'stackprotector' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-eyLYjhskzn6qxkoyjtjic4ap@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-stackprotector.c | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-stackprotector.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 1a6737144149..9f94912ccf63 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -104,6 +104,7 @@ $(info done) FEATURE_TESTS = \ hello \ stackprotector-all \ + stackprotector \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -112,7 +113,7 @@ 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 7538c148b40c..46b7650983cb 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -2,6 +2,7 @@ FILES= \ test-hello \ test-stackprotector-all \ + test-stackprotector \ test-libnuma CC := $(CC) -MD @@ -18,6 +19,9 @@ test-hello: test-stackprotector-all: $(BUILD) -Werror -fstack-protector-all +test-stackprotector: + $(BUILD) -Werror -fstack-protector + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-stackprotector.c b/tools/perf/config/feature-checks/test-stackprotector.c new file mode 100644 index 000000000000..c9f398d87868 --- /dev/null +++ b/tools/perf/config/feature-checks/test-stackprotector.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} From c25104452de94102810e86323eabb7d9a4cad083 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 13:58:12 +0200 Subject: [PATCH 007/161] tools/perf/build: Split out feature check: 'volatile-register-var' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-5dOevlybbwvbk3zTbcxrrqet@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ .../perf/config/feature-checks/test-volatile-register-var.c | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-volatile-register-var.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 9f94912ccf63..a3de2f8bd61a 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -105,6 +105,7 @@ FEATURE_TESTS = \ hello \ stackprotector-all \ stackprotector \ + volatile-register-var \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -117,7 +118,7 @@ ifeq ($(feature-stackprotector), 1) CFLAGS += -Wstack-protector endif -ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y) +ifeq ($(feature-volatile-register-var), 1) CFLAGS += -Wvolatile-register-var endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 46b7650983cb..5693299b4806 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -3,6 +3,7 @@ FILES= \ test-hello \ test-stackprotector-all \ test-stackprotector \ + test-volatile-register-var \ test-libnuma CC := $(CC) -MD @@ -22,6 +23,9 @@ test-stackprotector-all: test-stackprotector: $(BUILD) -Werror -fstack-protector +test-volatile-register-var: + $(BUILD) -Werror -Wvolatile-register-var + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-volatile-register-var.c b/tools/perf/config/feature-checks/test-volatile-register-var.c new file mode 100644 index 000000000000..c9f398d87868 --- /dev/null +++ b/tools/perf/config/feature-checks/test-volatile-register-var.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} From 1ea6f99efd8ae61fce68c97a9cf9f722cfbca3ad Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 09:38:28 +0200 Subject: [PATCH 008/161] tools/perf/build: Split out feature check: 'fortify-source' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-wicrcLCy2wkalka7iwsuzgpb@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-fortify-source.c | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-fortify-source.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index a3de2f8bd61a..7a614f92ce8c 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -106,6 +106,7 @@ FEATURE_TESTS = \ stackprotector-all \ stackprotector \ volatile-register-var \ + fortify-source \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -123,7 +124,7 @@ ifeq ($(feature-volatile-register-var), 1) endif ifndef PERF_DEBUG - ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y) + ifeq ($(feature-fortify-source), 1) CFLAGS += -D_FORTIFY_SOURCE=2 endif endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 5693299b4806..529317e6009b 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -4,6 +4,7 @@ FILES= \ test-stackprotector-all \ test-stackprotector \ test-volatile-register-var \ + test-fortify-source \ test-libnuma CC := $(CC) -MD @@ -26,6 +27,9 @@ test-stackprotector: test-volatile-register-var: $(BUILD) -Werror -Wvolatile-register-var +test-fortify-source: + $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-fortify-source.c b/tools/perf/config/feature-checks/test-fortify-source.c new file mode 100644 index 000000000000..c9f398d87868 --- /dev/null +++ b/tools/perf/config/feature-checks/test-fortify-source.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(void) +{ + return puts("hi"); +} From 78e9d6550807aedfc1f81c199bd4681c09d80ac5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:11:46 +0200 Subject: [PATCH 009/161] tools/perf/build: Split out feature check: 'bionic' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-xjfVewprrfhlo2wuzbnpVb1k@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 12 +++++++----- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-bionic.c | 6 ++++++ 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-bionic.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 7a614f92ce8c..09e2ecc4b056 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -107,6 +107,7 @@ FEATURE_TESTS = \ stackprotector \ volatile-register-var \ fortify-source \ + bionic \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -150,12 +151,13 @@ 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 529317e6009b..191df97a031d 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -5,6 +5,7 @@ FILES= \ test-stackprotector \ test-volatile-register-var \ test-fortify-source \ + test-bionic \ test-libnuma CC := $(CC) -MD @@ -30,6 +31,9 @@ test-volatile-register-var: test-fortify-source: $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 +test-bionic: + $(BUILD) + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-bionic.c b/tools/perf/config/feature-checks/test-bionic.c new file mode 100644 index 000000000000..eac24e9513eb --- /dev/null +++ b/tools/perf/config/feature-checks/test-bionic.c @@ -0,0 +1,6 @@ +#include <android/api-level.h> + +int main(void) +{ + return __ANDROID_API__; +} From 50eed7a71ebaf6676be8c497192b978f07581326 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:11:16 +0200 Subject: [PATCH 010/161] tools/perf/build: Clean up the libelf logic in config/Makefile Nest the rules properly. No change in functionality. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-dDgivr9xtjrof2vmoyOfwxkj@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 58 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 09e2ecc4b056..a2e0e1b200c3 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -164,38 +164,38 @@ ifdef NO_LIBELF 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); + FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) + ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y) + FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS) + ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y) + LIBC_SUPPORT := 1 + endif + ifeq ($(BIONIC),1) + LIBC_SUPPORT := 1 + endif + ifeq ($(LIBC_SUPPORT),1) + msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev); - NO_LIBELF := 1 - NO_DWARF := 1 - NO_DEMANGLE := 1 + 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 + 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 endif # NO_LIBELF ifndef NO_LIBELF From 8f7f8005f526c23d3e5537f5ab68c1c3fb422453 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:20:25 +0200 Subject: [PATCH 011/161] tools/perf/build: Split out feature check: 'libelf' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-qznhihaasbysfqO7ffvRsf9q@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-libelf.c | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libelf.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index a2e0e1b200c3..68654281b973 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -108,6 +108,7 @@ FEATURE_TESTS = \ volatile-register-var \ fortify-source \ bionic \ + libelf \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -164,8 +165,7 @@ ifdef NO_LIBELF NO_DEMANGLE := 1 NO_LIBUNWIND := 1 else - FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) - ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y) + ifeq ($(feature-libelf), 0) FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS) ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y) LIBC_SUPPORT := 1 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 191df97a031d..789a38d21a34 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -6,6 +6,7 @@ FILES= \ test-volatile-register-var \ test-fortify-source \ test-bionic \ + test-libelf \ test-libnuma CC := $(CC) -MD @@ -34,6 +35,9 @@ test-fortify-source: test-bionic: $(BUILD) +test-libelf: + $(BUILD) -lelf + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-libelf.c b/tools/perf/config/feature-checks/test-libelf.c new file mode 100644 index 000000000000..1a08f9717344 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libelf.c @@ -0,0 +1,7 @@ +#include <libelf.h> + +int main(void) +{ + Elf *elf = elf_begin(0, ELF_C_READ, 0); + return (long)elf; +} From e12762cfd9b4ec8f9bb5863eea403253175df9f1 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 10:34:20 +0200 Subject: [PATCH 012/161] tools/perf/build: Split out feature check: 'glibc' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-nqnnsptw7ivOzhzbNjiun7ds@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-glibc.c | 8 ++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-glibc.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 68654281b973..8cd0fd82967c 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -109,6 +109,7 @@ FEATURE_TESTS = \ fortify-source \ bionic \ libelf \ + glibc \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -166,8 +167,7 @@ ifdef NO_LIBELF NO_LIBUNWIND := 1 else ifeq ($(feature-libelf), 0) - FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS) - ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y) + ifeq ($(feature-glibc), 1) LIBC_SUPPORT := 1 endif ifeq ($(BIONIC),1) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 789a38d21a34..c0569c7edb89 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -7,6 +7,7 @@ FILES= \ test-fortify-source \ test-bionic \ test-libelf \ + test-glibc \ test-libnuma CC := $(CC) -MD @@ -38,6 +39,9 @@ test-bionic: test-libelf: $(BUILD) -lelf +test-glibc: + $(BUILD) + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-glibc.c b/tools/perf/config/feature-checks/test-glibc.c new file mode 100644 index 000000000000..13c66a58f2ec --- /dev/null +++ b/tools/perf/config/feature-checks/test-glibc.c @@ -0,0 +1,8 @@ +#include <gnu/libc-version.h> + +int main(void) +{ + const char *version = gnu_get_libc_version(); + return (long)version; +} + From 8295d4e27262dc49177e70dcc8ba34fa26343cf2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 10:35:39 +0200 Subject: [PATCH 013/161] tools/perf/build: Split out feature check: 'dwarf' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-dsx0fn9mjwfprizboANvtuup@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-dwarf.c | 9 +++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-dwarf.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 8cd0fd82967c..89630b8c8d59 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -110,6 +110,7 @@ FEATURE_TESTS = \ bionic \ libelf \ glibc \ + dwarf \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -190,8 +191,7 @@ else 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) + 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index c0569c7edb89..566a71dd6168 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -8,6 +8,7 @@ FILES= \ test-bionic \ test-libelf \ test-glibc \ + test-dwarf \ test-libnuma CC := $(CC) -MD @@ -42,6 +43,9 @@ test-libelf: test-glibc: $(BUILD) +test-dwarf: + $(BUILD) -ldw + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-dwarf.c b/tools/perf/config/feature-checks/test-dwarf.c new file mode 100644 index 000000000000..783dfcd9a5c4 --- /dev/null +++ b/tools/perf/config/feature-checks/test-dwarf.c @@ -0,0 +1,9 @@ +#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; +} From fb3d333b3faa6bf975f00973c6a6271b2ab93c0c Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 10:05:51 +0200 Subject: [PATCH 014/161] tools/perf/build: Clean up the mmap logic in config/Makefile Nest the rules properly. No change in functionality. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-wwktuHl4Ra5lyrrretkxmxqf@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 51 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 89630b8c8d59..8a27de27f7c2 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -199,37 +199,38 @@ else endif # NO_LIBELF ifndef NO_LIBELF -CFLAGS += -DHAVE_LIBELF_SUPPORT -FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) - CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT -endif -ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM_SUPPORT),y) - CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT -endif + CFLAGS += -DHAVE_LIBELF_SUPPORT + FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -# include ARCH specific config --include $(src-perf)/arch/$(ARCH)/Makefile + ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) + 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 += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) - LDFLAGS += $(LIBDW_LDFLAGS) - EXTLIBS += -lelf -ldw -endif # PERF_HAVE_DWARF_REGS -endif # NO_DWARF + ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM_SUPPORT),y) + CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT + endif + # include ARCH specific config + -include $(src-perf)/arch/$(ARCH)/Makefile + + ifndef NO_DWARF + ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) + msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); + NO_DWARF := 1 + else + CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) + LDFLAGS += $(LIBDW_LDFLAGS) + EXTLIBS += -lelf -ldw + endif # PERF_HAVE_DWARF_REGS + endif # NO_DWARF endif # NO_LIBELF ifndef NO_LIBELF -CFLAGS += -DHAVE_LIBELF_SUPPORT -FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) - CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT -endif # try-cc + CFLAGS += -DHAVE_LIBELF_SUPPORT + FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) + ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) + CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT + endif # try-cc endif # NO_LIBELF # There's only x86 (both 32 and 64) support for CFI unwind so far From 8869b17ee0bdd0da3d1f7d7ced284ab444c2c6d8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:02:28 +0200 Subject: [PATCH 015/161] tools/perf/build: Split out feature check: 'libelf-mmap' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-9fxnxjcmrgbSvipxlwsdQ8fg@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 6 +++--- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-libelf-mmap.c | 7 +++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libelf-mmap.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 8a27de27f7c2..bf1f021d2467 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -111,6 +111,7 @@ FEATURE_TESTS = \ libelf \ glibc \ dwarf \ + libelf-mmap \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -202,7 +203,7 @@ ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) - ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) + ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT endif @@ -227,8 +228,7 @@ endif # NO_LIBELF ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT - FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) - ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DHAVE_LIBELF_MMAP_SUPPORT),y) + ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT endif # try-cc endif # NO_LIBELF diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 566a71dd6168..bf96e34509f4 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -9,6 +9,7 @@ FILES= \ test-libelf \ test-glibc \ test-dwarf \ + test-libelf-mmap \ test-libnuma CC := $(CC) -MD @@ -46,6 +47,9 @@ test-glibc: test-dwarf: $(BUILD) -ldw +test-libelf-mmap: + $(BUILD) -lelf + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-libelf-mmap.c b/tools/perf/config/feature-checks/test-libelf-mmap.c new file mode 100644 index 000000000000..1c648159c705 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libelf-mmap.c @@ -0,0 +1,7 @@ +#include <libelf.h> +# +int main(void) +{ + Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0); + return (long)elf; +} From b7bcef6f8e61580e883672b6c97148d4f89e9874 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:35:27 +0200 Subject: [PATCH 016/161] tools/perf/build: Split out feature check: 'libelf-getphdrnum' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-wa9qstb8erbjreLxiHepzjfw@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 5 +++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-libelf-getphdrnum.c | 7 +++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libelf-getphdrnum.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index bf1f021d2467..718b47611340 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -112,6 +112,7 @@ FEATURE_TESTS = \ glibc \ dwarf \ libelf-mmap \ + libelf-getphdrnum \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -207,7 +208,7 @@ ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT endif - ifeq ($(call try-cc,$(SOURCE_ELF_GETPHDRNUM),$(FLAGS_LIBELF),-DHAVE_ELF_GETPHDRNUM_SUPPORT),y) + ifeq ($(feature-libelf-getphdrnum), 1) CFLAGS += -DHAVE_ELF_GETPHDRNUM_SUPPORT endif @@ -230,7 +231,7 @@ ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT - endif # try-cc + endif endif # NO_LIBELF # There's only x86 (both 32 and 64) support for CFI unwind so far diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index bf96e34509f4..83b3a02b64d8 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -10,6 +10,7 @@ FILES= \ test-glibc \ test-dwarf \ test-libelf-mmap \ + test-libelf-getphdrnum \ test-libnuma CC := $(CC) -MD @@ -50,6 +51,9 @@ test-dwarf: test-libelf-mmap: $(BUILD) -lelf +test-libelf-getphdrnum: + $(BUILD) -lelf + test-libnuma: $(BUILD) -lnuma diff --git a/tools/perf/config/feature-checks/test-libelf-getphdrnum.c b/tools/perf/config/feature-checks/test-libelf-getphdrnum.c new file mode 100644 index 000000000000..58eca5332520 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libelf-getphdrnum.c @@ -0,0 +1,7 @@ +#include <libelf.h> +# +int main(void) +{ + size_t dst; + return elf_getphdrnum(0, &dst); +} From 308e1e700a1337b89c7530a4f4cdde5ccb52fb4e Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 10:30:47 +0200 Subject: [PATCH 017/161] tools/perf/build: Clean up the libunwind logic in config/Makefile Nest the rules properly. No change in functionality. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-jjlmizjmhockUs04wqnScnkl@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 718b47611340..0d7558790a02 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -240,19 +240,19 @@ 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 -endif + # for linking with debug library, run like: + # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ + ifdef LIBUNWIND_DIR + LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include + LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib + endif -FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS) -ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y) - msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99); - NO_LIBUNWIND := 1 -endif # Libunwind support -endif # NO_LIBUNWIND + 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 +endif ifndef NO_LIBUNWIND CFLAGS += -DHAVE_LIBUNWIND_SUPPORT From 058f952de9b3075cd888dc3cea60691db0ec4d3f Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:45:44 +0200 Subject: [PATCH 018/161] tools/perf/build: Split out feature check: 'libunwind' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-vTiatsVyva3tfgh3vhxaidxl@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 13 +++++++----- tools/perf/config/feature-checks/Makefile | 4 ++++ .../config/feature-checks/test-libunwind.c | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libunwind.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 0d7558790a02..d684a292536e 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -113,6 +113,7 @@ FEATURE_TESTS = \ dwarf \ libelf-mmap \ libelf-getphdrnum \ + libunwind \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -240,15 +241,17 @@ ifneq ($(ARCH),x86) endif ifndef NO_LIBUNWIND - # for linking with debug library, run like: - # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ + # + # For linking with debug library, run like: + # + # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ + # ifdef LIBUNWIND_DIR LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib endif - FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS) - ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y) + ifneq ($(feature-libunwind), 1) msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99); NO_LIBUNWIND := 1 endif @@ -259,7 +262,7 @@ ifndef NO_LIBUNWIND EXTLIBS += $(LIBUNWIND_LIBS) CFLAGS += $(LIBUNWIND_CFLAGS) LDFLAGS += $(LIBUNWIND_LDFLAGS) -endif # NO_LIBUNWIND +endif ifndef NO_LIBAUDIT FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 83b3a02b64d8..d6d9570a038f 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -11,6 +11,7 @@ FILES= \ test-dwarf \ test-libelf-mmap \ test-libelf-getphdrnum \ + test-libunwind \ test-libnuma CC := $(CC) -MD @@ -57,6 +58,9 @@ test-libelf-getphdrnum: test-libnuma: $(BUILD) -lnuma +test-libunwind: + $(BUILD) -lunwind -lunwind-x86_64 -lelf + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libunwind.c b/tools/perf/config/feature-checks/test-libunwind.c new file mode 100644 index 000000000000..562274695c76 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libunwind.c @@ -0,0 +1,20 @@ +#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; +} From d795a658eb0ab5ab0b86cda5abe28954b0a08471 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:55:31 +0200 Subject: [PATCH 019/161] tools/perf/build: Split out feature check: 'libaudit' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-orhejqtjao3vf4wxwBUdzhaz@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-libaudit.c | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libaudit.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index d684a292536e..d4f18f4c8d51 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -114,6 +114,7 @@ FEATURE_TESTS = \ libelf-mmap \ libelf-getphdrnum \ libunwind \ + libaudit \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -265,8 +266,7 @@ ifndef 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index d6d9570a038f..8e49fa0c922b 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -12,6 +12,7 @@ FILES= \ test-libelf-mmap \ test-libelf-getphdrnum \ test-libunwind \ + test-libaudit \ test-libnuma CC := $(CC) -MD @@ -61,6 +62,9 @@ test-libnuma: test-libunwind: $(BUILD) -lunwind -lunwind-x86_64 -lelf +test-libaudit: + $(BUILD) -laudit + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libaudit.c b/tools/perf/config/feature-checks/test-libaudit.c new file mode 100644 index 000000000000..854a65d3cc78 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libaudit.c @@ -0,0 +1,7 @@ +#include <libaudit.h> + +int main(void) +{ + printf("error message: %s\n", audit_errno_to_name(0)); + return audit_open(); +} From b9498b508a0d601029f1040a51e9a5a4aecbb926 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 14:57:54 +0200 Subject: [PATCH 020/161] tools/perf/build: Split out feature check: 'libslang' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-FGmpkydfwqlkaw7yy8ewjpza@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-libslang.c | 6 ++++++ 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libslang.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index d4f18f4c8d51..43713c641600 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -115,6 +115,7 @@ FEATURE_TESTS = \ libelf-getphdrnum \ libunwind \ libaudit \ + libslang \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -280,8 +281,7 @@ 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 8e49fa0c922b..c9b15b0a819b 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -13,6 +13,7 @@ FILES= \ test-libelf-getphdrnum \ test-libunwind \ test-libaudit \ + test-libslang \ test-libnuma CC := $(CC) -MD @@ -65,6 +66,9 @@ test-libunwind: test-libaudit: $(BUILD) -laudit +test-libslang: + $(BUILD) -I/usr/include/slang -lslang + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libslang.c b/tools/perf/config/feature-checks/test-libslang.c new file mode 100644 index 000000000000..22ff22ed94d1 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libslang.c @@ -0,0 +1,6 @@ +#include <slang.h> + +int main(void) +{ + return SLsmg_init_smg(); +} From 7ef9e055ce1d8ad93f636bde1bf050eef26c798b Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:01:56 +0200 Subject: [PATCH 021/161] tools/perf/build: Split out feature check: 'gtk2' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-gfwzurn7wywiviLp7Swyyqsy@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-gtk2.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-gtk2.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 43713c641600..b3bf931dd2a0 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -116,6 +116,7 @@ FEATURE_TESTS = \ libunwind \ libaudit \ libslang \ + gtk2 \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -294,7 +295,7 @@ 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index c9b15b0a819b..920958c83ce8 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -14,6 +14,7 @@ FILES= \ test-libunwind \ test-libaudit \ test-libslang \ + test-gtk2 \ test-libnuma CC := $(CC) -MD @@ -69,6 +70,9 @@ test-libaudit: test-libslang: $(BUILD) -I/usr/include/slang -lslang +test-gtk2: + $(BUILD) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-gtk2.c b/tools/perf/config/feature-checks/test-gtk2.c new file mode 100644 index 000000000000..1ac6d8a1fb14 --- /dev/null +++ b/tools/perf/config/feature-checks/test-gtk2.c @@ -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; +} From c7a79e96dc166a1bdadca1367a39c84887e73de3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:08:30 +0200 Subject: [PATCH 022/161] tools/perf/build: Split out feature check: 'gtk2-infobar' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-oumjyVjonjvgH8ts4mftagel@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-gtk2-infobar.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-gtk2-infobar.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index b3bf931dd2a0..3d3d435b41fa 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -117,6 +117,7 @@ FEATURE_TESTS = \ libaudit \ libslang \ gtk2 \ + gtk2-infobar \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -299,7 +300,7 @@ ifndef NO_GTK2 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_SUPPORT),y) + ifeq ($(feature-gtk2-infobar), 1) CFLAGS += -DHAVE_GTK_INFO_BAR_SUPPORT endif CFLAGS += -DHAVE_GTK2_SUPPORT diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 920958c83ce8..017918f809ff 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -15,6 +15,7 @@ FILES= \ test-libaudit \ test-libslang \ test-gtk2 \ + test-gtk2-infobar \ test-libnuma CC := $(CC) -MD @@ -73,6 +74,9 @@ test-libslang: 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) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-gtk2-infobar.c b/tools/perf/config/feature-checks/test-gtk2-infobar.c new file mode 100644 index 000000000000..eebcfbc45120 --- /dev/null +++ b/tools/perf/config/feature-checks/test-gtk2-infobar.c @@ -0,0 +1,10 @@ +#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; +} From 7181a6714efc5039ffb50db7462d5cefe15b5630 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:15:36 +0200 Subject: [PATCH 023/161] tools/perf/build: Split out feature check: 'libperl' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-ggucqbwFwpxyuxde6dm7itHq@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 13 +++++++++++++ tools/perf/config/feature-checks/test-libperl.c | 9 +++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-libperl.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 3d3d435b41fa..8124dd55b05c 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -118,6 +118,7 @@ FEATURE_TESTS = \ libslang \ gtk2 \ gtk2-infobar \ + libperl \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -321,7 +322,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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 017918f809ff..3033c25f00b4 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -16,6 +16,7 @@ FILES= \ test-libslang \ test-gtk2 \ test-gtk2-infobar \ + test-libperl \ test-libnuma CC := $(CC) -MD @@ -77,6 +78,18 @@ test-gtk2: 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) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libperl.c b/tools/perf/config/feature-checks/test-libperl.c new file mode 100644 index 000000000000..8871f6a0fdb4 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libperl.c @@ -0,0 +1,9 @@ +#include <EXTERN.h> +#include <perl.h> + +int main(void) +{ + perl_alloc(); + + return 0; +} From 9734163b6ee1425c6fa4b65d7e6ce34c9079420d Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:18:37 +0200 Subject: [PATCH 024/161] tools/perf/build: Split out feature check: 'libpython' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-9wfutfb8ufFHrddrwlejqrai@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 18 ++++++++++++++++++ .../config/feature-checks/test-libpython.c | 7 +++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-libpython.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 8124dd55b05c..595c0e0dd139 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -119,6 +119,7 @@ FEATURE_TESTS = \ gtk2 \ gtk2-infobar \ libperl \ + libpython \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -367,7 +368,7 @@ 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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 3033c25f00b4..e7ed05aa5710 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -17,6 +17,7 @@ FILES= \ test-gtk2 \ test-gtk2-infobar \ test-libperl \ + test-libpython \ test-libnuma CC := $(CC) -MD @@ -90,6 +91,23 @@ 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) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libpython.c b/tools/perf/config/feature-checks/test-libpython.c new file mode 100644 index 000000000000..72267972fa98 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libpython.c @@ -0,0 +1,7 @@ +#include <Python.h> +# +int main(void) +{ + Py_Initialize(); + return 0; +} From 95d061c8a9f36e8c2cc458f97bc67716571b3fee Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:40:04 +0200 Subject: [PATCH 025/161] tools/perf/build: Split out feature check: 'libpython-version' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-raHmlqlnv0zexsrPau8hhane@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ .../config/feature-checks/test-libpython-version.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-libpython-version.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 595c0e0dd139..63ba069868c9 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -120,6 +120,7 @@ FEATURE_TESTS = \ gtk2-infobar \ libperl \ libpython \ + libpython-version \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -372,7 +373,7 @@ else $(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) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index e7ed05aa5710..d15074d77243 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -18,6 +18,7 @@ FILES= \ test-gtk2-infobar \ test-libperl \ test-libpython \ + test-libpython-version \ test-libnuma CC := $(CC) -MD @@ -108,6 +109,9 @@ FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) test-libpython: $(BUILD) $(FLAGS_PYTHON_EMBED) +test-libpython-version: + $(BUILD) $(FLAGS_PYTHON_EMBED) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libpython-version.c b/tools/perf/config/feature-checks/test-libpython-version.c new file mode 100644 index 000000000000..facea122d812 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libpython-version.c @@ -0,0 +1,10 @@ +#include <Python.h> + +#if PY_VERSION_HEX >= 0x03000000 + #error +#endif + +int main(void) +{ + return 0; +} From 3b7646e45d110f53d4c0fa0a63158c3d2a763e60 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 15:53:31 +0200 Subject: [PATCH 026/161] tools/perf/build: Split out feature check: 'libbfd' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-cdxdfv7Corpfvjg9Skezhvjn@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-libbfd.c | 7 +++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-libbfd.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 63ba069868c9..7e139694afc2 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -121,6 +121,7 @@ FEATURE_TESTS = \ libperl \ libpython \ libpython-version \ + libbfd \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -404,8 +405,7 @@ else 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) + ifeq ($(feature-libbfd), 1) EXTLIBS += -lbfd else FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index d15074d77243..af65aaa93e16 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -19,6 +19,7 @@ FILES= \ test-libperl \ test-libpython \ test-libpython-version \ + test-libbfd \ test-libnuma CC := $(CC) -MD @@ -112,6 +113,9 @@ test-libpython: test-libpython-version: $(BUILD) $(FLAGS_PYTHON_EMBED) +test-libbfd: + $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-libbfd.c b/tools/perf/config/feature-checks/test-libbfd.c new file mode 100644 index 000000000000..d03339c995d7 --- /dev/null +++ b/tools/perf/config/feature-checks/test-libbfd.c @@ -0,0 +1,7 @@ +#include <bfd.h> + +int main(void) +{ + bfd_demangle(0, 0, 0); + return 0; +} From d0707c9172e5d286fc119dcef5ea1621ef3bfade Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Tue, 8 Oct 2013 10:10:45 +0200 Subject: [PATCH 027/161] tools/perf/build: Split out feature check: 'strlcpy' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-ektO8cgvupthhyqqczSok2sr@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-strlcpy.c | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-strlcpy.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 7e139694afc2..c8ac4df05db1 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -121,6 +121,7 @@ FEATURE_TESTS = \ libperl \ libpython \ libpython-version \ + strlcpy \ libbfd \ libnuma @@ -434,7 +435,7 @@ else endif ifndef NO_STRLCPY - ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY_SUPPORT),y) + ifeq ($(feature-strlcpy), 1) CFLAGS += -DHAVE_STRLCPY_SUPPORT endif endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index af65aaa93e16..d348aa0ec181 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -19,6 +19,7 @@ FILES= \ test-libperl \ test-libpython \ test-libpython-version \ + test-strlcpy \ test-libbfd \ test-libnuma @@ -113,6 +114,9 @@ test-libpython: test-libpython-version: $(BUILD) $(FLAGS_PYTHON_EMBED) +test-strlcpy: + $(BUILD) + test-libbfd: $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl diff --git a/tools/perf/config/feature-checks/test-strlcpy.c b/tools/perf/config/feature-checks/test-strlcpy.c new file mode 100644 index 000000000000..4a6b6ff06f74 --- /dev/null +++ b/tools/perf/config/feature-checks/test-strlcpy.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +extern size_t strlcpy(char *dest, const char *src, size_t size); + +int main(void) +{ + strlcpy(NULL, NULL, 0); + return 0; +} From 34ef21622f9028efafe7950504a9ce90d9cc15a0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 16:46:49 +0200 Subject: [PATCH 028/161] tools/perf/build: Split out feature check: 'on-exit' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-gmywXandzfxnlcbzlX6bkpw1@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-on-exit.c | 6 ++++++ 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-on-exit.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index c8ac4df05db1..44affb5477c5 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -123,6 +123,7 @@ FEATURE_TESTS = \ libpython-version \ strlcpy \ libbfd \ + on-exit \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -441,7 +442,7 @@ ifndef NO_STRLCPY endif ifndef NO_ON_EXIT - ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT_SUPPORT),y) + ifeq ($(feature-on-exit), 1) CFLAGS += -DHAVE_ON_EXIT_SUPPORT endif endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index d348aa0ec181..20f1b8c0f865 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -21,6 +21,7 @@ FILES= \ test-libpython-version \ test-strlcpy \ test-libbfd \ + test-on-exit \ test-libnuma CC := $(CC) -MD @@ -120,6 +121,9 @@ test-strlcpy: test-libbfd: $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl +test-on-exit: + $(BUILD) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-on-exit.c b/tools/perf/config/feature-checks/test-on-exit.c new file mode 100644 index 000000000000..473f1dea5316 --- /dev/null +++ b/tools/perf/config/feature-checks/test-on-exit.c @@ -0,0 +1,6 @@ +#include <stdio.h> + +int main(void) +{ + return on_exit(NULL, NULL); +} From 4cc9117a35b2810fb84454514a9136e5f2945751 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 30 Sep 2013 16:49:38 +0200 Subject: [PATCH 029/161] tools/perf/build: Split out feature check: 'backtrace' Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-ihnwe6cvglVkudyvcavP1wql@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 ++- tools/perf/config/feature-checks/Makefile | 4 ++++ tools/perf/config/feature-checks/test-backtrace.c | 10 ++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tools/perf/config/feature-checks/test-backtrace.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 44affb5477c5..c0c83440de97 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -124,6 +124,7 @@ FEATURE_TESTS = \ strlcpy \ libbfd \ on-exit \ + backtrace \ libnuma $(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) @@ -448,7 +449,7 @@ ifndef NO_ON_EXIT endif ifndef NO_BACKTRACE - ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DHAVE_BACKTRACE_SUPPORT),y) + ifeq ($(feature-backtrace), 1) CFLAGS += -DHAVE_BACKTRACE_SUPPORT endif endif diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 20f1b8c0f865..0e4dbc2d5c8a 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -22,6 +22,7 @@ FILES= \ test-strlcpy \ test-libbfd \ test-on-exit \ + test-backtrace \ test-libnuma CC := $(CC) -MD @@ -124,6 +125,9 @@ test-libbfd: test-on-exit: $(BUILD) +test-backtrace: + $(BUILD) + -include *.d */*.d ############################### diff --git a/tools/perf/config/feature-checks/test-backtrace.c b/tools/perf/config/feature-checks/test-backtrace.c new file mode 100644 index 000000000000..5b79468bea2a --- /dev/null +++ b/tools/perf/config/feature-checks/test-backtrace.c @@ -0,0 +1,10 @@ +#include <execinfo.h> +#include <stdio.h> + +int main(void) +{ + backtrace(NULL, 0); + backtrace_symbols(NULL, 0); + + return 0; +} From 7a10822a30060eceddda16c051086c00acb449c9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 11:26:18 +0200 Subject: [PATCH 030/161] tools/perf: Clean up util/include/linux/compiler.h Use the standard CPP style we use in the kernel: #ifndef foo # define foo bar #endif Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-iqyVrrHqpn0eiwenvgwrh8lf@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/util/include/linux/compiler.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h index 96b919dae11c..bef4d3ddc493 100644 --- a/tools/perf/util/include/linux/compiler.h +++ b/tools/perf/util/include/linux/compiler.h @@ -2,20 +2,25 @@ #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 #endif From fb1c9185e36cf9c616ac15f54e54a01f052672bd Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Tue, 1 Oct 2013 13:26:13 +0200 Subject: [PATCH 031/161] tools/perf: Turn strlcpy() into a __weak function The strlcpy() feature check slows every build unnecessarily - so make it a __weak function so it does not have to be auto-detected. If the libc (or any other library) has an strlcpy() implementation it will be used - otherwise our fallback is active. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-zjbrcupapu08ePsyYhhhxiwk@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 7 ------- tools/perf/config/feature-checks/Makefile | 4 ---- tools/perf/config/feature-checks/test-strlcpy.c | 8 -------- tools/perf/util/cache.h | 3 +-- tools/perf/util/include/linux/compiler.h | 4 ++++ tools/perf/util/path.c | 10 +++++++--- 6 files changed, 12 insertions(+), 24 deletions(-) delete mode 100644 tools/perf/config/feature-checks/test-strlcpy.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index c0c83440de97..3207c25b15f0 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -121,7 +121,6 @@ FEATURE_TESTS = \ libperl \ libpython \ libpython-version \ - strlcpy \ libbfd \ on-exit \ backtrace \ @@ -436,12 +435,6 @@ else endif endif -ifndef NO_STRLCPY - ifeq ($(feature-strlcpy), 1) - CFLAGS += -DHAVE_STRLCPY_SUPPORT - endif -endif - ifndef NO_ON_EXIT ifeq ($(feature-on-exit), 1) CFLAGS += -DHAVE_ON_EXIT_SUPPORT diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 0e4dbc2d5c8a..c65bdac0ebe2 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -19,7 +19,6 @@ FILES= \ test-libperl \ test-libpython \ test-libpython-version \ - test-strlcpy \ test-libbfd \ test-on-exit \ test-backtrace \ @@ -116,9 +115,6 @@ test-libpython: test-libpython-version: $(BUILD) $(FLAGS_PYTHON_EMBED) -test-strlcpy: - $(BUILD) - test-libbfd: $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl diff --git a/tools/perf/config/feature-checks/test-strlcpy.c b/tools/perf/config/feature-checks/test-strlcpy.c deleted file mode 100644 index 4a6b6ff06f74..000000000000 --- a/tools/perf/config/feature-checks/test-strlcpy.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <stdlib.h> -extern size_t strlcpy(char *dest, const char *src, size_t size); - -int main(void) -{ - strlcpy(NULL, NULL, 0); - return 0; -} diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 442953c1ce85..7b176dd02e1a 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.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_SUPPORT +/* 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 */ diff --git a/tools/perf/util/include/linux/compiler.h b/tools/perf/util/include/linux/compiler.h index bef4d3ddc493..b003ad7200b2 100644 --- a/tools/perf/util/include/linux/compiler.h +++ b/tools/perf/util/include/linux/compiler.h @@ -23,4 +23,8 @@ # define __force #endif +#ifndef __weak +# define __weak __attribute__((weak)) +#endif + #endif diff --git a/tools/perf/util/path.c b/tools/perf/util/path.c index f3958743b743..5d13cb45b317 100644 --- a/tools/perf/util/path.c +++ b/tools/perf/util/path.c @@ -22,19 +22,23 @@ static const char *get_perf_dir(void) return "."; } -#ifndef HAVE_STRLCPY_SUPPORT -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) { From baa9c30e1e250abf3e53b98e5bcf415dccdc7ba2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Tue, 1 Oct 2013 14:14:31 +0200 Subject: [PATCH 032/161] tools/perf/build: Speed up auto-detection of features by adding a 'test-all' target Concatenate all feature checks into test-all.c. This can be built and checked faster than all the individual tests. If test-all fails then we still check all the individual features, so this is a pure speedup, it should have no effects on functionality. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-5hlcb2qorzwfwrWTjiygjjih@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 45 ++++- tools/perf/config/feature-checks/Makefile | 3 + tools/perf/config/feature-checks/test-all.c | 196 ++++++++++++++++++++ 3 files changed, 238 insertions(+), 6 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-all.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 3207c25b15f0..cbd7cdca3e56 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -89,17 +89,21 @@ CFLAGS += -std=gnu99 EXTLIBS = -lelf -lpthread -lrt -lm -ldl -feature_check = $(eval $(feature_check_code)); $(info CHK: config/feature-checks/test-$(1)) +feature_check = $(eval $(feature_check_code)) define feature_check_code - feature-$(2) := $(shell make -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) + feature-$(1) := $(shell $(MAKE) -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: # -$(info Testing features:) -$(shell make -i -j -C config/feature-checks >/dev/null 2>&1) -$(info done) +$(info ) +$(info Auto-detecting system features:) FEATURE_TESTS = \ hello \ @@ -126,7 +130,36 @@ FEATURE_TESTS = \ backtrace \ libnuma -$(foreach test,$(FEATURE_TESTS),$(call feature_check,$(test),$(test))) +# +# Special fast-path for the 'all features are available' case: +# +$(call feature_check,all) + +ifeq ($(feature-all), 1) + $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat))) +else + $(shell $(MAKE) -i -j -C config/feature-checks >/dev/null 2>&1) + $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) +endif + +feature_print = $(eval $(feature_print_code)) + +# +# Print the result of the feature test: +# +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 + $(info $(MSG)) +endef + +$(foreach feat,$(FEATURE_TESTS) DUMMY,$(call feature_print,$(feat))) + +# newline at the end of the feature printouts: +$(info ) ifeq ($(feature-stackprotector-all), 1) CFLAGS += -fstack-protector-all diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index c65bdac0ebe2..4b855e0ccd0b 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -32,6 +32,9 @@ BUILD = $(CC) -o $(OUTPUT)$@ $@.c ############################### +test-all: + $(BUILD) -Werror -fstack-protector -fstack-protector-all -Wvolatile-register-var -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' -DPACKAGE=perf -lbfd -ldl + test-hello: $(BUILD) diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/perf/config/feature-checks/test-all.c new file mode 100644 index 000000000000..9f7c4b165305 --- /dev/null +++ b/tools/perf/config/feature-checks/test-all.c @@ -0,0 +1,196 @@ + +#pragma GCC diagnostic ignored "-Wstrict-prototypes" + +#include <Python.h> + +#include <EXTERN.h> +#include <perl.h> + +#include <stdio.h> +#include <libelf.h> +#include <gnu/libc-version.h> +#include <dwarf.h> +#include <elfutils/libdw.h> +#include <elfutils/version.h> +#include <libelf.h> +#include <libunwind.h> +#include <stdlib.h> +#include <libaudit.h> +#include <slang.h> +#include <gtk/gtk.h> +#include <bfd.h> +#include <stdio.h> +#include <execinfo.h> +#include <stdio.h> +#include <numa.h> +#include <numaif.h> + +#pragma GCC diagnostic error "-Wstrict-prototypes" + +int main1(void) +{ + return puts("hi"); +} + +int main2(void) +{ + return puts("hi"); +} + +int main3(void) +{ + return puts("hi"); +} + +int main4(void) +{ + Elf *elf = elf_begin(0, ELF_C_READ, 0); + return (long)elf; +} +# +int main5(void) +{ + Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0); + return (long)elf; +} + +int main6(void) +{ + const char *version = gnu_get_libc_version(); + return (long)version; +} + +int main7(void) +{ + Dwarf *dbg = dwarf_begin(0, DWARF_C_READ); + return (long)dbg; +} + +int main8(void) +{ + size_t dst; + return elf_getphdrnum(0, &dst); +} + +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 main9(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; +} + +int main10(void) +{ + printf("error message: %s\n", audit_errno_to_name(0)); + return audit_open(); +} + +int main11(void) +{ + return SLsmg_init_smg(); +} + +int main12(int argc, char *argv[]) +{ + gtk_init(&argc, &argv); + + return 0; +} + +int main13(void) +{ + gtk_info_bar_new(); + + return 0; +} + +int main14(void) +{ + perl_alloc(); + + return 0; +} + +int main15(void) +{ + Py_Initialize(); + return 0; +} + +#if PY_VERSION_HEX >= 0x03000000 + #error +#endif + +int main16(void) +{ + return 0; +} + +int main17(void) +{ + bfd_demangle(0, 0, 0); + return 0; +} + +void exit_function(int x, void *y) +{ +} + +int main18(void) +{ + return on_exit(exit_function, NULL); +} + +int main19(void) +{ + void *backtrace_fns[1]; + size_t entries; + + entries = backtrace(backtrace_fns, 1); + backtrace_symbols(backtrace_fns, entries); + + return 0; +} + +int main20(void) +{ + numa_available(); + return 0; +} + +int main(int argc, char *argv[]) +{ + main1(); + main2(); + main3(); + main4(); + main5(); + main6(); + main7(); + main8(); + main9(); + main10(); + main11(); + main12(argc, argv); + main13(); + main14(); + main15(); + main16(); + main17(); + main18(); + main19(); + main20(); + + return 0; +} From c72e3f04b45fb2e50cdd81a50c3778c6a57251d8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Tue, 1 Oct 2013 16:28:09 +0200 Subject: [PATCH 033/161] tools/perf/build: Speed up git-version test on re-make util/PERF-VERSION-GEN is currently executed on every build attempt, and this script can take a lot of time on trees that are at a significant git-distance from Linus's tree: $ time util/PERF-VERSION-GEN real 0m4.343s user 0m4.176s sys 0m0.140s It also takes a lot of time if the Git repository is network attached, etc., because the commands it uses: TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null ) has to count commits from the nearest tag and thus has to access (and decompress) every git commit blob on the relevant version path. Even on Linus's tree it takes 0.28 seconds on a fast box to count all the commits and get the git version string: $ time util/PERF-VERSION-GEN real 0m0.279s user 0m0.247s sys 0m0.025s But the version string only has to be regenerated if the git repository's head commit changes. So add a dependency of ../../.git/HEAD and touch the file every time it's regenerated, so that Make's build rules can pick it up and cache the result: make: `PERF-VERSION-FILE' is up to date. real 0m0.184s user 0m0.117s sys 0m0.026s Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-wvmlrurufuk6mo1ovtNigguT@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 64c043b7a438..6b5452a120af 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -70,8 +70,9 @@ ifneq ($(OUTPUT),) #$(info Determined 'OUTPUT' to be $(OUTPUT)) endif -$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE +$(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 @@ -814,6 +815,16 @@ clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean $(RM) $(OUTPUT)util/*-flex* $(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 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 +.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS From c9404c6650d8f58ce8cf98d4c5581fc5c9e37faf Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Tue, 1 Oct 2013 17:17:22 +0200 Subject: [PATCH 034/161] tools/perf/build: Speed up the final link libtraceevent.a and liblk.a rules have always-missed dependencies, which causes python.so to be relinked at every build attempt - even if none of the affected code changes. This slows down re-builds unnecessarily, by adding more than a second to the build time: comet:~/tip/tools/perf> time make ... SUBDIR /fast/mingo/tip/tools/lib/lk/ make[1]: `liblk.a' is up to date. SUBDIR /fast/mingo/tip/tools/lib/traceevent/ LINK perf GEN python/perf.so real 0m1.701s user 0m1.338s sys 0m0.301s Add the (trivial) dependencies to not force a re-link. This speeds up an empty re-build enormously: comet:~/tip/tools/perf> time make ... real 0m0.207s user 0m0.134s sys 0m0.028s [ This adds some coupling between the build dependencies of libtraceevent and liblk - but until those stay relatively simple this should not be an issue. ] Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-wvmlrurufuk6mo1ovtNigguT@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 6b5452a120af..df76198d45d4 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -669,15 +669,19 @@ $(LIB_FILE): $(LIB_OBJS) $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) # libtraceevent.a -$(LIBTRACEEVENT): +TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch]) + +$(LIBTRACEEVENT): $(TE_SOURCES) $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a $(LIBTRACEEVENT)-clean: $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean +LIBLK_SOURCES = $(wildcard $(LK_PATH)*.[ch]) + # if subdir is set, we've been called from above so target has been built # already -$(LIBLK): +$(LIBLK): $(LIBLK_SOURCES) ifeq ($(subdir),) $(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) liblk.a endif @@ -825,6 +829,6 @@ else GIT-HEAD-PHONY = endif -.PHONY: all install clean strip $(LIBTRACEEVENT) $(LIBLK) +.PHONY: all install clean strip .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS From 31f6be65e08d2cbb876b3b5fc9ae9281b7417c85 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 06:51:27 +0200 Subject: [PATCH 035/161] tools/perf: Fix double/triple-build of the feature detection logic during 'make install' et al Linus reported the following perf build system bug: 'Another annoyance during that make was that "make install" seems to want to re-make the thing I just built. That's absolutely horrible, [...]' The thing that got re-built were 'only' the (numerous) feature checks, not the whole project - but still it was mighty annoying as the feature checks took 9+ seconds even on reasonably fast boxes. Even with the autodep patches where feature detection is much faster it wastes resources, wastes screen real estate and confuses users if we execute feature detection twice. There were two sources for these unnecessary re-builds of the feature checks: - Unnecessary nested invocations of $(MAKE), apparently to be able to do conditional compilation dependent on documentation tools presence. Use straight dependencies instead, with no nesting. - A direct invocation of $(MAKE) to rebuild the PERF-VERSION-FILE. This is apparently done to be able to include it into the Makefile: -include $(OUTPUT)PERF-VERSION-FILE but that's entirely pointless for two reasons: 1) the version file gets regenerated by the initial build pass anyway, 2) including it is futile, given its contents: #define PERF_VERSION "3.12.rc3.g8510c7" 'make' will interpret that as a comment line... So just remove this part of the doc-generation logic. With these things fixed a 'make install' now rebuilds only what is needed. A repeated 'make install' on an already built tree is super fast now, it finishes in under 0.3 seconds: # # After the patch: # $ time make install ... real 0m0.280s user 0m0.162s sys 0m0.054s Prior all the autodep changes and prior this fix, a repeat 'make install' took 24.1 seconds (!) on the same system: # # Before the patches: # $ time make install ... real 0m24.109s user 0m21.171s sys 0m2.449s Which almost entirely was caused by fixable build system fat. We are now literally ~86 times faster. A fresh rebuild and install now takes just 11.4 seconds: # # After the patch: # $ make clean $ time make -j16 install ... real 0m11.457s user 1m43.411s sys 0m7.610s Without the patches it took 27.8 seconds: # # Before the patches: # $ make clean $ time make -j16 install ... real 0m27.801s user 1m59.242s sys 0m9.749s So even in the complete rebuild case we are now ~2.5 times faster. Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-x4qjnxjGrgxpribq8sdakfTp@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Documentation/Makefile | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index 5a37a7c84e69..eaa477f00673 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -192,13 +192,14 @@ do-install-man: man 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) @@ -216,14 +217,6 @@ install-pdf: pdf #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. @@ -342,5 +335,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 From de0f03fb8dc268de63d366e735cc576a22df201b Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 09:43:23 +0200 Subject: [PATCH 036/161] tools/perf/build: Invoke feature-checks 'clean' target from the main Makefile config/Makefile is not included for the 'clean' target, so invoke the config/feature-checks/Makefile 'clean' target from Makefile.perf. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-sh2cGvmsjbrazarlqre7pVwt@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index df76198d45d4..6b7779b3760b 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -809,7 +809,14 @@ $(INSTALL_DOC_TARGETS): ### Cleaning rules -clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean +# +# This is here, not in config/Makefile, because config/Makefile does +# not get included for the clean target: +# +config-clean: + @$(MAKE) -C config/feature-checks clean + +clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-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* @@ -829,6 +836,6 @@ else GIT-HEAD-PHONY = endif -.PHONY: all install clean strip +.PHONY: all install clean config-clean strip .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell .PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS From f1138ec66e839ce90c58af0c264db33271d73466 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 09:54:43 +0200 Subject: [PATCH 037/161] tools/perf/build: Speed up auto-detection The detection of certain rarely detected features can be delayed to when they are actually needed. So speed up the common case of auto-detection by pre-building only a core set of features and populating only their feature-flags. [ Features not listed in CORE_FEATURES need to built explicitly via the feature_check() function. ] (Also order the feature names alphabetically, while at it.) Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-xQkuveknd0gqla1dfxrqKpkl@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 51 +++++++++++++---------- tools/perf/config/feature-checks/Makefile | 31 +++++++------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index cbd7cdca3e56..581a94211fea 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -105,30 +105,36 @@ endef $(info ) $(info Auto-detecting system features:) -FEATURE_TESTS = \ - hello \ - stackprotector-all \ - stackprotector \ - volatile-register-var \ - fortify-source \ - bionic \ - libelf \ - glibc \ +# +# 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 \ - libelf-mmap \ - libelf-getphdrnum \ - libunwind \ - libaudit \ - libslang \ + fortify-source \ + glibc \ gtk2 \ gtk2-infobar \ + libaudit \ + libbfd \ + libelf \ + libelf-getphdrnum \ + libelf-mmap \ + libnuma \ libperl \ libpython \ libpython-version \ - libbfd \ + libslang \ + libunwind \ on-exit \ - backtrace \ - libnuma + stackprotector \ + stackprotector-all \ + volatile-register-var # # Special fast-path for the 'all features are available' case: @@ -136,10 +142,13 @@ FEATURE_TESTS = \ $(call feature_check,all) ifeq ($(feature-all), 1) - $(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat))) + # + # 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) -i -j -C config/feature-checks >/dev/null 2>&1) - $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat))) + $(shell $(MAKE) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) + $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) endif feature_print = $(eval $(feature_print_code)) @@ -156,7 +165,7 @@ define feature_print_code $(info $(MSG)) endef -$(foreach feat,$(FEATURE_TESTS) DUMMY,$(call feature_print,$(feat))) +$(foreach feat,$(CORE_FEATURE_TESTS) DUMMY,$(call feature_print,$(feat))) # newline at the end of the feature printouts: $(info ) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 4b855e0ccd0b..d4c55acc82bb 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -1,28 +1,29 @@ FILES= \ - test-hello \ - test-stackprotector-all \ - test-stackprotector \ - test-volatile-register-var \ - test-fortify-source \ + test-all \ + test-backtrace \ test-bionic \ - test-libelf \ - test-glibc \ test-dwarf \ - test-libelf-mmap \ - test-libelf-getphdrnum \ - test-libunwind \ - test-libaudit \ - test-libslang \ + test-fortify-source \ + test-glibc \ test-gtk2 \ test-gtk2-infobar \ + test-hello \ + test-libaudit \ + test-libbfd \ + test-libelf \ + test-libelf-getphdrnum \ + test-libelf-mmap \ + test-libnuma \ test-libperl \ test-libpython \ test-libpython-version \ - test-libbfd \ + test-libslang \ + test-libunwind \ test-on-exit \ - test-backtrace \ - test-libnuma + test-stackprotector-all \ + test-stackprotector \ + test-volatile-register-var CC := $(CC) -MD From b3b64a12239e758573316df19cbbaf0126887440 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 10:01:42 +0200 Subject: [PATCH 038/161] tools/perf/build: Improve printout-of auto-detected features Change the print-out of auto-detected features by making sure that repeat invocations of 'make' when all features are successfully detected do not produce the (rather lengthy) autodetection printout. ( When one or more features are missing then we still print out the feature detection table, to make sure people are aware of the resulting limitations. ) Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-qd8sMsshcjomxqx9bQcufmaa@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 42 ++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 581a94211fea..fb6ec069f541 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -102,8 +102,6 @@ endef # # Build the feature check binaries in parallel, ignore errors, ignore return value and suppress output: # -$(info ) -$(info Auto-detecting system features:) # # Note that this is not a complete list of all feature tests, just @@ -136,10 +134,34 @@ CORE_FEATURE_TESTS = \ stackprotector-all \ volatile-register-var +# +# 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 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) +$(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) # @@ -151,11 +173,10 @@ else $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) endif -feature_print = $(eval $(feature_print_code)) - # # Print the result of the feature test: # +feature_print = $(eval $(feature_print_code)) define feature_print_code ifeq ($(feature-$(1)), 1) MSG := $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1)) @@ -165,10 +186,13 @@ define feature_print_code $(info $(MSG)) endef -$(foreach feat,$(CORE_FEATURE_TESTS) DUMMY,$(call feature_print,$(feat))) - -# newline at the end of the feature printouts: -$(info ) +# +# 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) DUMMY,$(call feature_print,$(feat))) + $(info ) +endif ifeq ($(feature-stackprotector-all), 1) CFLAGS += -fstack-protector-all From 2cfbe880f0a8eed7beabade3e06fd53f999b3e32 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 11:18:28 +0200 Subject: [PATCH 039/161] tools/perf/build: Automatically build in parallel, based on number of CPUs in the system Implement automatic parallel builds when building in tools/perf: $ time make # [ perf build: Doing 'make -j12' parallel build. ] Auto-detecting system features: ... real 0m9.265s user 0m59.888s sys 0m6.082s On GNU make achieving this is not particularly easy, it requires a separate makefile, which then invokes the main Makefile. ( Note: this patch adds Makefile.parallel to show the concept - the two makefiles will be flipped in the next patch to avoid having to specify -f to get parallelism in the default build. ) Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-dvBjwqiTyzrufzkz8oanhpf9@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile.parallel | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tools/perf/Makefile.parallel diff --git a/tools/perf/Makefile.parallel b/tools/perf/Makefile.parallel new file mode 100644 index 000000000000..ec5e08b577ab --- /dev/null +++ b/tools/perf/Makefile.parallel @@ -0,0 +1,26 @@ +# +# 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 + +export JOBS + +$(info $(shell printf '# [ perf build: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build. ]\n')) + +# +# Needed if no target specified: +# +all: + @$(MAKE) --no-print-directory -j$(JOBS) $@ + +%: + @$(MAKE) --no-print-directory -j$(JOBS) $@ + From bd69cc286d817a4ce55b8969b0975e42168fe7c0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 11:49:08 +0200 Subject: [PATCH 040/161] tools/perf/build: Flip Makefile.parallel and Makefile.perf To make it more apparent that there is not change in functionality we introduced Makefile.parallel separately and now flip it with the main Makefile, which moves into Makefile.perf. The renames are: Makefile.parallel => Makefile Makefile => Makefile.perf Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-igRfuw9ugbnnpixLd6wpptzl@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 844 +---------------------------------- tools/perf/Makefile.parallel | 26 -- tools/perf/Makefile.perf | 842 ++++++++++++++++++++++++++++++++++ 3 files changed, 856 insertions(+), 856 deletions(-) delete mode 100644 tools/perf/Makefile.parallel create mode 100644 tools/perf/Makefile.perf diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 6b7779b3760b..ce7874b73dd9 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -1,841 +1,25 @@ -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. +# 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. # -# Define ARCH as name of target architecture if you want cross-builds. +# (To override it, run 'make JOBS=1' and similar.) # -# 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 -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: -# - -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)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 +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 -endif +export JOBS -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 $@ - -$(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 -TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch]) - -$(LIBTRACEEVENT): $(TE_SOURCES) - $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a - -$(LIBTRACEEVENT)-clean: - $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean - -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),) - $(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 +$(info $(shell printf '# [ perf build: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build. ]\n')) # -# This is here, not in config/Makefile, because config/Makefile does -# not get included for the clean target: +# Needed if no target specified: # -config-clean: - @$(MAKE) -C config/feature-checks clean +all: + @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) $@ -clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-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) - -# -# 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 -.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell -.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS +%: + @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) $@ diff --git a/tools/perf/Makefile.parallel b/tools/perf/Makefile.parallel deleted file mode 100644 index ec5e08b577ab..000000000000 --- a/tools/perf/Makefile.parallel +++ /dev/null @@ -1,26 +0,0 @@ -# -# 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 - -export JOBS - -$(info $(shell printf '# [ perf build: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build. ]\n')) - -# -# Needed if no target specified: -# -all: - @$(MAKE) --no-print-directory -j$(JOBS) $@ - -%: - @$(MAKE) --no-print-directory -j$(JOBS) $@ - diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf new file mode 100644 index 000000000000..178a1c87db13 --- /dev/null +++ b/tools/perf/Makefile.perf @@ -0,0 +1,842 @@ +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 +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: +# + +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)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 + 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 $@ + +$(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 +TE_SOURCES = $(wildcard $(TRACE_EVENT_DIR)*.[ch]) + +$(LIBTRACEEVENT): $(TE_SOURCES) + $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a + +$(LIBTRACEEVENT)-clean: + $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean + +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),) + $(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 + +# +# This is here, not in config/Makefile, because config/Makefile does +# not get included for the clean target: +# +config-clean: + @$(MAKE) -C config/feature-checks clean + +clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-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) + +# +# 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 +.PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell +.PHONY: $(GIT-HEAD-PHONY) TAGS tags cscope .FORCE-PERF-CFLAGS + From 73a725f0008702600f7d987e262f963c0fa64bc6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 11:58:30 +0200 Subject: [PATCH 041/161] tools/perf/build: Standardize the various messages output by parallel make Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-mky0rtpwxi3ivxsvdjoOEmhr@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 23 ++++++++++++++++++++--- tools/perf/config/Makefile | 4 ++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index ce7874b73dd9..3b925ad0d5f5 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -13,13 +13,30 @@ endif export JOBS -$(info $(shell printf '# [ perf build: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build. ]\n')) +define print_msg + @printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n' +endef + +define make + @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) $@ +endef # # Needed if no target specified: # all: - @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) $@ + $(print_msg) + $(make) +# +# The clean target is not really parallel, don't print the jobs info: +# +clean: + $(make) + +# +# All other targets get passed through: +# %: - @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) $@ + $(print_msg) + $(make) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index fb6ec069f541..62d02cd03f29 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -179,9 +179,9 @@ endif feature_print = $(eval $(feature_print_code)) define feature_print_code ifeq ($(feature-$(1)), 1) - MSG := $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1)) + MSG = $(shell printf '...%30s: [ \033[32mon\033[m ]' $(1)) else - MSG := $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1)) + MSG = $(shell printf '...%30s: [ \033[31mOFF\033[m ]' $(1)) endif $(info $(MSG)) endef From 1c47661a93fe6f729c80ed18a1f9ab1c7fb0cac2 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 15:15:09 +0200 Subject: [PATCH 042/161] tools/perf/build: Split out feature checks: 'liberty', 'liberty-z', 'cplus-demangle' Note that these are rarely executed tests, so we call feature_check() explicitly and don't have them in CORE_FEATURE_CHECKS. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-pvumlx6mbtfxffgrlwO2mRcx@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 16 ++++++---------- tools/perf/config/feature-checks/Makefile | 12 ++++++++++++ .../config/feature-checks/test-cplus-demangle.c | 10 ++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 tools/perf/config/feature-checks/test-cplus-demangle.c diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 62d02cd03f29..89b2d47d2e4b 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -472,23 +472,19 @@ else EXTLIBS += -liberty CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT else - FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd ifeq ($(feature-libbfd), 1) 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) + $(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_SUPPORT else diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index d4c55acc82bb..e21bceb80bf2 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -11,6 +11,9 @@ FILES= \ test-hello \ test-libaudit \ test-libbfd \ + test-liberty \ + test-liberty-z \ + test-cplus-demangle \ test-libelf \ test-libelf-getphdrnum \ test-libelf-mmap \ @@ -122,6 +125,15 @@ test-libpython-version: test-libbfd: $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl +test-liberty: + $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl -liberty + +test-liberty-z: + $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl -liberty -lz + +test-cplus-demangle: + $(BUILD) -liberty + test-on-exit: $(BUILD) diff --git a/tools/perf/config/feature-checks/test-cplus-demangle.c b/tools/perf/config/feature-checks/test-cplus-demangle.c new file mode 100644 index 000000000000..5202f5038ad8 --- /dev/null +++ b/tools/perf/config/feature-checks/test-cplus-demangle.c @@ -0,0 +1,10 @@ + +extern char *cplus_demangle(const char *, int); + +int main(void) +{ + cplus_demangle(0, 0); + + return 0; +} + From 0648f839ff754e2825fee2cb7080df5874316b3f Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 15:30:35 +0200 Subject: [PATCH 043/161] tools/perf/build: Remove unused config/feature-tests.mak Also remove try-cc et al. These got obsoleted by the split-out feature checks in config/feature-checks/. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-Y6ailbiranadqlrl8Dfivjbi@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 3 +- tools/perf/config/feature-tests.mak | 244 ---------------------------- tools/perf/config/utilities.mak | 14 -- 3 files changed, 1 insertion(+), 260 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 89b2d47d2e4b..e80ffe8262b0 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -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)),) @@ -274,7 +273,7 @@ else msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); NO_DWARF := 1 endif # Dwarf support - endif # SOURCE_LIBELF + endif # libelf support endif # NO_LIBELF ifndef NO_LIBELF diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index f79305739ecc..139597f9cb07 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -1,246 +1,2 @@ -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 diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index 94d2d4f9c35d..4d985e0f03f5 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak @@ -178,17 +178,3 @@ endef _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) _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 -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"') From 1e3f30fae797660a014ac159d93fff9952ec1bf0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 15:48:49 +0200 Subject: [PATCH 044/161] tools/perf/build: Clean up various testcases Prepare to include them into test-all.c directly, by making sure that they build cleanly and without warnings. Also make sure they make a certain amount of sense and don't crash when executed. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-Mn9gsdutzopoowk3xurqpsxE@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/feature-checks/test-backtrace.c | 8 ++++++-- .../perf/config/feature-checks/test-cplus-demangle.c | 9 +++++++-- tools/perf/config/feature-checks/test-gtk2-infobar.c | 3 ++- tools/perf/config/feature-checks/test-gtk2.c | 2 +- tools/perf/config/feature-checks/test-libaudit.c | 2 ++ tools/perf/config/feature-checks/test-libbfd.c | 11 ++++++++++- tools/perf/config/feature-checks/test-libunwind.c | 9 ++++++++- tools/perf/config/feature-checks/test-on-exit.c | 11 ++++++++++- 8 files changed, 46 insertions(+), 9 deletions(-) diff --git a/tools/perf/config/feature-checks/test-backtrace.c b/tools/perf/config/feature-checks/test-backtrace.c index 5b79468bea2a..5b33bcf12c27 100644 --- a/tools/perf/config/feature-checks/test-backtrace.c +++ b/tools/perf/config/feature-checks/test-backtrace.c @@ -3,8 +3,12 @@ int main(void) { - backtrace(NULL, 0); - backtrace_symbols(NULL, 0); + void *backtrace_fns[10]; + size_t entries; + + entries = backtrace(backtrace_fns, 10); + backtrace_symbols_fd(backtrace_fns, entries, 1); return 0; } + diff --git a/tools/perf/config/feature-checks/test-cplus-demangle.c b/tools/perf/config/feature-checks/test-cplus-demangle.c index 5202f5038ad8..ab29f80570af 100644 --- a/tools/perf/config/feature-checks/test-cplus-demangle.c +++ b/tools/perf/config/feature-checks/test-cplus-demangle.c @@ -1,9 +1,14 @@ - +extern int printf(const char *format, ...); extern char *cplus_demangle(const char *, int); int main(void) { - cplus_demangle(0, 0); + char symbol[4096] = "FieldName__9ClassNameFd"; + char *tmp; + + tmp = cplus_demangle(symbol, 0); + + printf("demangled symbol: {%s}\n", tmp); return 0; } diff --git a/tools/perf/config/feature-checks/test-gtk2-infobar.c b/tools/perf/config/feature-checks/test-gtk2-infobar.c index eebcfbc45120..397b4646d066 100644 --- a/tools/perf/config/feature-checks/test-gtk2-infobar.c +++ b/tools/perf/config/feature-checks/test-gtk2-infobar.c @@ -2,8 +2,9 @@ #include <gtk/gtk.h> #pragma GCC diagnostic error "-Wstrict-prototypes" -int main(void) +int main(int argc, char *argv[]) { + gtk_init(&argc, &argv); gtk_info_bar_new(); return 0; diff --git a/tools/perf/config/feature-checks/test-gtk2.c b/tools/perf/config/feature-checks/test-gtk2.c index 1ac6d8a1fb14..6bd80e509439 100644 --- a/tools/perf/config/feature-checks/test-gtk2.c +++ b/tools/perf/config/feature-checks/test-gtk2.c @@ -4,7 +4,7 @@ int main(int argc, char *argv[]) { - gtk_init(&argc, &argv); + gtk_init(&argc, &argv); return 0; } diff --git a/tools/perf/config/feature-checks/test-libaudit.c b/tools/perf/config/feature-checks/test-libaudit.c index 854a65d3cc78..f7e791efa6d1 100644 --- a/tools/perf/config/feature-checks/test-libaudit.c +++ b/tools/perf/config/feature-checks/test-libaudit.c @@ -1,5 +1,7 @@ #include <libaudit.h> +extern int printf(const char *format, ...); + int main(void) { printf("error message: %s\n", audit_errno_to_name(0)); diff --git a/tools/perf/config/feature-checks/test-libbfd.c b/tools/perf/config/feature-checks/test-libbfd.c index d03339c995d7..1886c78c30e7 100644 --- a/tools/perf/config/feature-checks/test-libbfd.c +++ b/tools/perf/config/feature-checks/test-libbfd.c @@ -1,7 +1,16 @@ #include <bfd.h> +extern int printf(const char *format, ...); + int main(void) { - bfd_demangle(0, 0, 0); + char symbol[4096] = "FieldName__9ClassNameFd"; + char *tmp; + + tmp = bfd_demangle(0, symbol, 0); + + printf("demangled symbol: {%s}\n", tmp); + return 0; } + diff --git a/tools/perf/config/feature-checks/test-libunwind.c b/tools/perf/config/feature-checks/test-libunwind.c index 562274695c76..43b9369bcab7 100644 --- a/tools/perf/config/feature-checks/test-libunwind.c +++ b/tools/perf/config/feature-checks/test-libunwind.c @@ -10,11 +10,18 @@ extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as, #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(NULL, 0); + + 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; } diff --git a/tools/perf/config/feature-checks/test-on-exit.c b/tools/perf/config/feature-checks/test-on-exit.c index 473f1dea5316..8f64ed3a58d9 100644 --- a/tools/perf/config/feature-checks/test-on-exit.c +++ b/tools/perf/config/feature-checks/test-on-exit.c @@ -1,6 +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) { - return on_exit(NULL, NULL); + on_exit(exit_fn, &data); + + return 321; } From 3ca576a481f8c12fe606fb75232d52637c666ed0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 2 Oct 2013 16:21:37 +0200 Subject: [PATCH 045/161] tools/perf/build: Collapse the test-all.c testcase Simplify test-all.c by including it all the testcases via #include. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-pcZlwqq5ou7Ebvkekvhtzfbm@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/feature-checks/test-all.c | 254 +++++++------------- 1 file changed, 82 insertions(+), 172 deletions(-) diff --git a/tools/perf/config/feature-checks/test-all.c b/tools/perf/config/feature-checks/test-all.c index 9f7c4b165305..50d431892a0c 100644 --- a/tools/perf/config/feature-checks/test-all.c +++ b/tools/perf/config/feature-checks/test-all.c @@ -1,196 +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. + */ -#pragma GCC diagnostic ignored "-Wstrict-prototypes" +/* + * 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 -#include <Python.h> +#define main main_test_libpython_version +# include "test-libpython-version.c" +#undef main -#include <EXTERN.h> -#include <perl.h> +#define main main_test_libperl +# include "test-libperl.c" +#undef main -#include <stdio.h> -#include <libelf.h> -#include <gnu/libc-version.h> -#include <dwarf.h> -#include <elfutils/libdw.h> -#include <elfutils/version.h> -#include <libelf.h> -#include <libunwind.h> -#include <stdlib.h> -#include <libaudit.h> -#include <slang.h> -#include <gtk/gtk.h> -#include <bfd.h> -#include <stdio.h> -#include <execinfo.h> -#include <stdio.h> -#include <numa.h> -#include <numaif.h> +#define main main_test_hello +# include "test-hello.c" +#undef main -#pragma GCC diagnostic error "-Wstrict-prototypes" +#define main main_test_libelf +# include "test-libelf.c" +#undef main -int main1(void) -{ - return puts("hi"); -} +#define main main_test_libelf_mmap +# include "test-libelf-mmap.c" +#undef main -int main2(void) -{ - return puts("hi"); -} +#define main main_test_glibc +# include "test-glibc.c" +#undef main -int main3(void) -{ - return puts("hi"); -} +#define main main_test_dwarf +# include "test-dwarf.c" +#undef main -int main4(void) -{ - Elf *elf = elf_begin(0, ELF_C_READ, 0); - return (long)elf; -} -# -int main5(void) -{ - Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0); - return (long)elf; -} +#define main main_test_libelf_getphdrnum +# include "test-libelf-getphdrnum.c" +#undef main -int main6(void) -{ - const char *version = gnu_get_libc_version(); - return (long)version; -} +#define main main_test_libunwind +# include "test-libunwind.c" +#undef main -int main7(void) -{ - Dwarf *dbg = dwarf_begin(0, DWARF_C_READ); - return (long)dbg; -} +#define main main_test_libaudit +# include "test-libaudit.c" +#undef main -int main8(void) -{ - size_t dst; - return elf_getphdrnum(0, &dst); -} +#define main main_test_libslang +# include "test-libslang.c" +#undef main -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 main main_test_gtk2 +# include "test-gtk2.c" +#undef main +#define main main_test_gtk2_infobar +# include "test-gtk2-infobar.c" +#undef main -#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table) +#define main main_test_libbfd +# include "test-libbfd.c" +#undef main -int main9(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; -} +#define main main_test_on_exit +# include "test-on-exit.c" +#undef main -int main10(void) -{ - printf("error message: %s\n", audit_errno_to_name(0)); - return audit_open(); -} +#define main main_test_backtrace +# include "test-backtrace.c" +#undef main -int main11(void) -{ - return SLsmg_init_smg(); -} - -int main12(int argc, char *argv[]) -{ - gtk_init(&argc, &argv); - - return 0; -} - -int main13(void) -{ - gtk_info_bar_new(); - - return 0; -} - -int main14(void) -{ - perl_alloc(); - - return 0; -} - -int main15(void) -{ - Py_Initialize(); - return 0; -} - -#if PY_VERSION_HEX >= 0x03000000 - #error -#endif - -int main16(void) -{ - return 0; -} - -int main17(void) -{ - bfd_demangle(0, 0, 0); - return 0; -} - -void exit_function(int x, void *y) -{ -} - -int main18(void) -{ - return on_exit(exit_function, NULL); -} - -int main19(void) -{ - void *backtrace_fns[1]; - size_t entries; - - entries = backtrace(backtrace_fns, 1); - backtrace_symbols(backtrace_fns, entries); - - return 0; -} - -int main20(void) -{ - numa_available(); - return 0; -} +#define main main_test_libnuma +# include "test-libnuma.c" +#undef main int main(int argc, char *argv[]) { - main1(); - main2(); - main3(); - main4(); - main5(); - main6(); - main7(); - main8(); - main9(); - main10(); - main11(); - main12(argc, argv); - main13(); - main14(); - main15(); - main16(); - main17(); - main18(); - main19(); - main20(); + 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; } From b016a0dd08999218a05a4b176bc08a9ff68ccc5e Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 3 Oct 2013 14:32:10 +0200 Subject: [PATCH 046/161] tools/perf/build: Pass through all targets to Makefile.perf Jiri reported that 'make .o' stopped working: > [jolsa@krava perf]$ make -f Makefile perf.o > cc -c -o perf.o perf.c > In file included from builtin.h:4:0, > from perf.c:9: > util/util.h:74:24: fatal error: lk/debugfs.h: No such file or directory > compilation terminated. > make: *** [perf.o] Error 1 This is due to GNU make having built-in rules for popular targets such as *.o. Clear them out so that all targets as passed through to Makefile.perf. Reported-by: Jiri Olsa <jolsa@redhat.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Link: http://lkml.kernel.org/n/tip-5wkuvmlaaxtfgepKcvRij8sh@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 3b925ad0d5f5..6f6f13a13bb6 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -1,3 +1,10 @@ + +# +# 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: + # # 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. From 1c2d1d8cf4dbef33b8c6af6888bed2f4e659220e Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 3 Oct 2013 15:05:56 +0200 Subject: [PATCH 047/161] tools/perf/build: Make sure autodep feature binaries honor the O= setting Arnaldo noticed that the feature-check binaries are generated in the config/check-features/ directory even if O= is specified. Implement $(OUTPUT) logic for config/check-features/Makefile. Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-NLwlnv5prsubuey0vfocebym@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index e80ffe8262b0..3d656e3e6284 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -88,9 +88,14 @@ CFLAGS += -std=gnu99 EXTLIBS = -lelf -lpthread -lrt -lm -ldl +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) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) + feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) endef feature_set = $(eval $(feature_set_code)) @@ -138,7 +143,7 @@ CORE_FEATURE_TESTS = \ # to skip the print-out of the long features list if the file # existed before and after it was built: # -ifeq ($(wildcard config/feature-checks/test-all),) +ifeq ($(wildcard $(OUTPUT)config/feature-checks/test-all),) test-all-failed := 1 else test-all-failed := 0 @@ -168,7 +173,7 @@ ifeq ($(feature-all), 1) # $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) else - $(shell $(MAKE) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) + $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat))) endif From 684f434cc05a122938b75e055d7d799f1dd58d55 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Fri, 4 Oct 2013 11:11:32 +0200 Subject: [PATCH 048/161] tools/perf/build: Exclude MAKEFLAGS from nested invocation In case the user specifies MAKEFLAGS as an environment variable, or uses 'make -jN' explicitly, the options can conflict and result in: BUILD: Doing 'make -j8' parallel build make[1]: warning: -jN forced in submake: disabling jobserver mode. GEN common-cmds.h make[1]: *** write jobserver: Bad file descriptor. Stop. Make sure we invoke the main makefile in a pristine state. Users who want to do something non-standard can use the: make -f Makefile.perf method to invoke the makefile. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-uen6hzTvkqqngqwjma9yoEgw@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 6f6f13a13bb6..74f52d8f9631 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -1,3 +1,10 @@ +# +# This is a simple wrapper Makefile that calls the main Makefile.perf +# with a -j option to do parallel builds +# +# 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. +# # # Clear out the built-in rules GNU make defines by default (such as .o targets), @@ -5,6 +12,11 @@ # .SUFFIXES: +# +# We don't want to pass along options like -j: +# +unexport MAKEFLAGS + # # 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. @@ -18,14 +30,12 @@ ifeq ($(JOBS),) endif endif -export JOBS - define print_msg @printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n' endef define make - @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) $@ + @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(O) $@ endef # From b102420b500da97e0fc18d94f0600bddeced1b99 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Fri, 4 Oct 2013 12:08:05 +0200 Subject: [PATCH 049/161] tools/perf/build: Fix non-canonical directory names in O= This was a long-standing bug, relative pathnames like O=dir did not fully work in the build system: $ make O=localdir clean SUBDIR Documentation ../../scripts/Makefile.include:3: *** O=localdir does not exist. Stop. make[1]: *** [clean] Error 2 make: *** [clean] Error 2 Fix this by canonizing the directory before passing it to Makefile.perf. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-hchMp1hozn9tqgswWcooxcru@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 74f52d8f9631..9580ebe260e0 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -30,12 +30,19 @@ ifeq ($(JOBS),) endif endif +# +# Only pass canonical directory names as the output directory: +# +ifneq ($(O),) + FULL_O := $(shell readlink -f $(O)) +endif + define print_msg @printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n' endef define make - @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(O) $@ + @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $@ endef # From 1f7c645ab4b8326fef5afcd842795e071ecce9df Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Fri, 4 Oct 2013 12:14:59 +0200 Subject: [PATCH 050/161] tools/perf/build: Fix O=/some/dir perf.o type of targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If someone specifies a single target, mixed with O=, the following way: hubble:~/tip/tools/perf> make O=/tmp/perf util/stat.o BUILD: Doing 'make -j8' parallel build gcc -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k [...] The build might even fail, if a target depends on other targets: hubble:~/tip/tools/perf> make O=/tmp/perf perf.o ... perf.c: In function ‘handle_options’: perf.c:155:21: error: ‘PERF_HTML_PATH’ undeclared (first use in this function) The correct way to invoke such targets is: hubble:~/tip/tools/perf> make O=/tmp/perf /tmp/perf/perf.o BUILD: Doing 'make -j8' parallel build GEN /tmp/perf/common-cmds.h CC /tmp/perf/perf.o But that's unnecessary typing and it's also easy to mistakenly build into the source directory. To fix this remove the generic suffix rules and add redirection to $(OUTPUT) for the most popular .o targets. Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-mk0oiukmhgSbrll6chrPkkqr@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/Makefile.perf | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 178a1c87db13..a24f6c280b95 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -576,7 +576,21 @@ $(OUTPUT)perf.o perf.spec \ : $(OUTPUT)PERF-VERSION-FILE .SUFFIXES: -.SUFFIXES: .o .c .S .s + +# +# 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)util/$@" +bench/%.o: $(OUTPUT)bench/%.o + @echo " # Redirected target $@ => $(OUTPUT)bench/$@" +tests/%.o: $(OUTPUT)tests/%.o + @echo " # Redirected target $@ => $(OUTPUT)tests/$@" +endif # These two need to be here so that when O= is not used they take precedence # over the general rule for .o From 20c99e82173bed9e4e0013ec45c0b2b3b80b65d5 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 13:27:23 +0200 Subject: [PATCH 051/161] tools/perf/build: Harmonize the style of the feature testcases The various testcases used different styles, which was not really visible as long as they hid in feature-tests.mak. Now that they are out in the open make them prettier. ( Also delete the leftover, empty feature-tests.mak file. ) Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/n/tip-drDWk8xltndjdsespzjbhu6w@git.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/feature-checks/test-backtrace.c | 1 - tools/perf/config/feature-checks/test-cplus-demangle.c | 1 - tools/perf/config/feature-checks/test-dwarf.c | 1 + tools/perf/config/feature-checks/test-glibc.c | 2 +- tools/perf/config/feature-checks/test-libaudit.c | 1 + tools/perf/config/feature-checks/test-libbfd.c | 1 - tools/perf/config/feature-checks/test-libelf-getphdrnum.c | 3 ++- tools/perf/config/feature-checks/test-libelf-mmap.c | 3 ++- tools/perf/config/feature-checks/test-libelf.c | 1 + tools/perf/config/feature-checks/test-libnuma.c | 1 + tools/perf/config/feature-checks/test-libpython.c | 3 ++- tools/perf/config/feature-tests.mak | 2 -- 12 files changed, 11 insertions(+), 9 deletions(-) delete mode 100644 tools/perf/config/feature-tests.mak diff --git a/tools/perf/config/feature-checks/test-backtrace.c b/tools/perf/config/feature-checks/test-backtrace.c index 5b33bcf12c27..7124aa1dc8fb 100644 --- a/tools/perf/config/feature-checks/test-backtrace.c +++ b/tools/perf/config/feature-checks/test-backtrace.c @@ -11,4 +11,3 @@ int main(void) return 0; } - diff --git a/tools/perf/config/feature-checks/test-cplus-demangle.c b/tools/perf/config/feature-checks/test-cplus-demangle.c index ab29f80570af..610c686e0009 100644 --- a/tools/perf/config/feature-checks/test-cplus-demangle.c +++ b/tools/perf/config/feature-checks/test-cplus-demangle.c @@ -12,4 +12,3 @@ int main(void) return 0; } - diff --git a/tools/perf/config/feature-checks/test-dwarf.c b/tools/perf/config/feature-checks/test-dwarf.c index 783dfcd9a5c4..3fc1801ce4a9 100644 --- a/tools/perf/config/feature-checks/test-dwarf.c +++ b/tools/perf/config/feature-checks/test-dwarf.c @@ -5,5 +5,6 @@ int main(void) { Dwarf *dbg = dwarf_begin(0, DWARF_C_READ); + return (long)dbg; } diff --git a/tools/perf/config/feature-checks/test-glibc.c b/tools/perf/config/feature-checks/test-glibc.c index 13c66a58f2ec..b0820345cd98 100644 --- a/tools/perf/config/feature-checks/test-glibc.c +++ b/tools/perf/config/feature-checks/test-glibc.c @@ -3,6 +3,6 @@ int main(void) { const char *version = gnu_get_libc_version(); + return (long)version; } - diff --git a/tools/perf/config/feature-checks/test-libaudit.c b/tools/perf/config/feature-checks/test-libaudit.c index f7e791efa6d1..afc019f08641 100644 --- a/tools/perf/config/feature-checks/test-libaudit.c +++ b/tools/perf/config/feature-checks/test-libaudit.c @@ -5,5 +5,6 @@ extern int printf(const char *format, ...); int main(void) { printf("error message: %s\n", audit_errno_to_name(0)); + return audit_open(); } diff --git a/tools/perf/config/feature-checks/test-libbfd.c b/tools/perf/config/feature-checks/test-libbfd.c index 1886c78c30e7..24059907e990 100644 --- a/tools/perf/config/feature-checks/test-libbfd.c +++ b/tools/perf/config/feature-checks/test-libbfd.c @@ -13,4 +13,3 @@ int main(void) return 0; } - diff --git a/tools/perf/config/feature-checks/test-libelf-getphdrnum.c b/tools/perf/config/feature-checks/test-libelf-getphdrnum.c index 58eca5332520..d710459306c3 100644 --- a/tools/perf/config/feature-checks/test-libelf-getphdrnum.c +++ b/tools/perf/config/feature-checks/test-libelf-getphdrnum.c @@ -1,7 +1,8 @@ #include <libelf.h> -# + int main(void) { size_t dst; + return elf_getphdrnum(0, &dst); } diff --git a/tools/perf/config/feature-checks/test-libelf-mmap.c b/tools/perf/config/feature-checks/test-libelf-mmap.c index 1c648159c705..564427d7ef18 100644 --- a/tools/perf/config/feature-checks/test-libelf-mmap.c +++ b/tools/perf/config/feature-checks/test-libelf-mmap.c @@ -1,7 +1,8 @@ #include <libelf.h> -# + int main(void) { Elf *elf = elf_begin(0, ELF_C_READ_MMAP, 0); + return (long)elf; } diff --git a/tools/perf/config/feature-checks/test-libelf.c b/tools/perf/config/feature-checks/test-libelf.c index 1a08f9717344..08db322d8957 100644 --- a/tools/perf/config/feature-checks/test-libelf.c +++ b/tools/perf/config/feature-checks/test-libelf.c @@ -3,5 +3,6 @@ int main(void) { Elf *elf = elf_begin(0, ELF_C_READ, 0); + return (long)elf; } diff --git a/tools/perf/config/feature-checks/test-libnuma.c b/tools/perf/config/feature-checks/test-libnuma.c index 70510a923e5a..4763d9cd587d 100644 --- a/tools/perf/config/feature-checks/test-libnuma.c +++ b/tools/perf/config/feature-checks/test-libnuma.c @@ -4,5 +4,6 @@ int main(void) { numa_available(); + return 0; } diff --git a/tools/perf/config/feature-checks/test-libpython.c b/tools/perf/config/feature-checks/test-libpython.c index 72267972fa98..b24b28ad6324 100644 --- a/tools/perf/config/feature-checks/test-libpython.c +++ b/tools/perf/config/feature-checks/test-libpython.c @@ -1,7 +1,8 @@ #include <Python.h> -# + int main(void) { Py_Initialize(); + return 0; } diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak deleted file mode 100644 index 139597f9cb07..000000000000 --- a/tools/perf/config/feature-tests.mak +++ /dev/null @@ -1,2 +0,0 @@ - - From aa4acf6cf102f639a2023b389ca8be8b8d9cad52 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 7 Oct 2013 17:51:29 +0200 Subject: [PATCH 052/161] tools/perf/build: Pass through LDFLAGS to feature tests David Ahern reported that when passing in LDFLAGS=-static then the feature checks still succeed - causing build failures down the line because the static libraries are missing. Solve this by passing through LDFLAGS to the feature-check Makefile. Reported-by: David Ahern <dsahern@gmail.com> Tested-by: David Ahern <dsahern@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/r/20131007155129.GA1066@gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 4 ++-- tools/perf/config/feature-checks/Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 3d656e3e6284..78f3b3eff12a 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -95,7 +95,7 @@ endif feature_check = $(eval $(feature_check_code)) define feature_check_code - feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) -C config/feature-checks test-$1 >/dev/null 2>/dev/null && echo 1 || echo 0) + 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)) @@ -173,7 +173,7 @@ ifeq ($(feature-all), 1) # $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat))) else - $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) -i -j -C config/feature-checks $(CORE_FEATURE_TESTS) >/dev/null 2>&1) + $(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 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index e21bceb80bf2..8ecac1908d5e 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -32,7 +32,7 @@ CC := $(CC) -MD all: $(FILES) -BUILD = $(CC) -o $(OUTPUT)$@ $@.c +BUILD = $(CC) $(LDFLAGS) -o $(OUTPUT)$@ $@.c ############################### From 165108a92fc554d51e73b143b69b77e7c278da78 Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Tue, 8 Oct 2013 17:51:10 +0200 Subject: [PATCH 053/161] tools/perf/build: Clean up feature_print_code() Remove DUMMY by making sure 'feature_print' is evaluated and thus all messages are printed. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Link: http://lkml.kernel.org/r/20131008155110.GA15558@krava.redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/perf/config/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 78f3b3eff12a..f5d661f5637d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -180,21 +180,21 @@ endif # # Print the result of the feature test: # -feature_print = $(eval $(feature_print_code)) +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 - $(info $(MSG)) 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) DUMMY,$(call feature_print,$(feat))) + $(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_print,$(feat))) $(info ) endif From 01533e9720c8527faf0bc6e476c4c911a488e268 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 3 Sep 2013 12:20:12 -0300 Subject: [PATCH 054/161] perf trace: Put syscall formatter parms into struct So that we can add more state to formatters without having to modify all of them. Example is to pass a table to a generic string formatter, like for setitimer 'which' arg. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-zyi2esmas5wfrxznh0x0fkiz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 96 +++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 71aa3e35406b..939426c7dbde 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -33,22 +33,24 @@ # define MADV_UNMERGEABLE 13 #endif +struct syscall_arg { + unsigned long val; + u8 idx; + u8 mask; +}; + static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, - unsigned long arg, - u8 arg_idx __maybe_unused, - u8 *arg_mask __maybe_unused) + struct syscall_arg *arg) { - return scnprintf(bf, size, "%#lx", arg); + return scnprintf(bf, size, "%#lx", arg->val); } #define SCA_HEX syscall_arg__scnprintf_hex static size_t syscall_arg__scnprintf_whence(char *bf, size_t size, - unsigned long arg, - u8 arg_idx __maybe_unused, - u8 *arg_mask __maybe_unused) + struct syscall_arg *arg) { - int whence = arg; + int whence = arg->val; switch (whence) { #define P_WHENCE(n) case SEEK_##n: return scnprintf(bf, size, #n) @@ -71,11 +73,9 @@ static size_t syscall_arg__scnprintf_whence(char *bf, size_t size, #define SCA_WHENCE syscall_arg__scnprintf_whence static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, - unsigned long arg, - u8 arg_idx __maybe_unused, - u8 *arg_mask __maybe_unused) + struct syscall_arg *arg) { - int printed = 0, prot = arg; + int printed = 0, prot = arg->val; if (prot == PROT_NONE) return scnprintf(bf, size, "NONE"); @@ -104,10 +104,9 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, #define SCA_MMAP_PROT syscall_arg__scnprintf_mmap_prot static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, - unsigned long arg, u8 arg_idx __maybe_unused, - u8 *arg_mask __maybe_unused) + struct syscall_arg *arg) { - int printed = 0, flags = arg; + int printed = 0, flags = arg->val; #define P_MMAP_FLAG(n) \ if (flags & MAP_##n) { \ @@ -148,10 +147,9 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, - unsigned long arg, u8 arg_idx __maybe_unused, - u8 *arg_mask __maybe_unused) + struct syscall_arg *arg) { - int behavior = arg; + int behavior = arg->val; switch (behavior) { #define P_MADV_BHV(n) case MADV_##n: return scnprintf(bf, size, #n) @@ -190,8 +188,7 @@ static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, #define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior -static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned long arg, - u8 arg_idx __maybe_unused, u8 *arg_mask) +static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg) { enum syscall_futex_args { SCF_UADDR = (1 << 0), @@ -201,24 +198,24 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned lo SCF_UADDR2 = (1 << 4), SCF_VAL3 = (1 << 5), }; - int op = arg; + int op = arg->val; int cmd = op & FUTEX_CMD_MASK; size_t printed = 0; switch (cmd) { #define P_FUTEX_OP(n) case FUTEX_##n: printed = scnprintf(bf, size, #n); - P_FUTEX_OP(WAIT); *arg_mask |= SCF_VAL3|SCF_UADDR2; break; - P_FUTEX_OP(WAKE); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; - P_FUTEX_OP(FD); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; - P_FUTEX_OP(REQUEUE); *arg_mask |= SCF_VAL3|SCF_TIMEOUT; break; - P_FUTEX_OP(CMP_REQUEUE); *arg_mask |= SCF_TIMEOUT; break; - P_FUTEX_OP(CMP_REQUEUE_PI); *arg_mask |= SCF_TIMEOUT; break; + P_FUTEX_OP(WAIT); arg->mask |= SCF_VAL3|SCF_UADDR2; break; + P_FUTEX_OP(WAKE); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; + P_FUTEX_OP(FD); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; + P_FUTEX_OP(REQUEUE); arg->mask |= SCF_VAL3|SCF_TIMEOUT; break; + P_FUTEX_OP(CMP_REQUEUE); arg->mask |= SCF_TIMEOUT; break; + P_FUTEX_OP(CMP_REQUEUE_PI); arg->mask |= SCF_TIMEOUT; break; P_FUTEX_OP(WAKE_OP); break; - P_FUTEX_OP(LOCK_PI); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; - P_FUTEX_OP(UNLOCK_PI); *arg_mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; - P_FUTEX_OP(TRYLOCK_PI); *arg_mask |= SCF_VAL3|SCF_UADDR2; break; - P_FUTEX_OP(WAIT_BITSET); *arg_mask |= SCF_UADDR2; break; - P_FUTEX_OP(WAKE_BITSET); *arg_mask |= SCF_UADDR2; break; + P_FUTEX_OP(LOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; + P_FUTEX_OP(UNLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2|SCF_TIMEOUT; break; + P_FUTEX_OP(TRYLOCK_PI); arg->mask |= SCF_VAL3|SCF_UADDR2; break; + P_FUTEX_OP(WAIT_BITSET); arg->mask |= SCF_UADDR2; break; + P_FUTEX_OP(WAKE_BITSET); arg->mask |= SCF_UADDR2; break; P_FUTEX_OP(WAIT_REQUEUE_PI); break; default: printed = scnprintf(bf, size, "%#x", cmd); break; } @@ -235,13 +232,12 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, unsigned lo #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, - unsigned long arg, - u8 arg_idx, u8 *arg_mask) + struct syscall_arg *arg) { - int printed = 0, flags = arg; + int printed = 0, flags = arg->val; if (!(flags & O_CREAT)) - *arg_mask |= 1 << (arg_idx + 1); /* Mask the mode parm */ + arg->mask |= 1 << (arg->idx + 1); /* Mask the mode parm */ if (flags == 0) return scnprintf(bf, size, "RDONLY"); @@ -294,7 +290,7 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, static struct syscall_fmt { const char *name; const char *alias; - size_t (*arg_scnprintf[6])(char *bf, size_t size, unsigned long arg, u8 arg_idx, u8 *arg_mask); + size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); bool errmsg; bool timeout; bool hexret; @@ -364,8 +360,7 @@ struct syscall { const char *name; bool filtered; struct syscall_fmt *fmt; - size_t (**arg_scnprintf)(char *bf, size_t size, - unsigned long arg, u8 arg_idx, u8 *args_mask); + size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); }; static size_t fprintf_duration(unsigned long t, FILE *fp) @@ -605,30 +600,35 @@ static int trace__read_syscall_info(struct trace *trace, int id) static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, unsigned long *args) { - int i = 0; size_t printed = 0; if (sc->tp_format != NULL) { struct format_field *field; - u8 mask = 0, bit = 1; + u8 bit = 1; + struct syscall_arg arg = { + .idx = 0, + .mask = 0, + }; for (field = sc->tp_format->format.fields->next; field; - field = field->next, ++i, bit <<= 1) { - if (mask & bit) + field = field->next, ++arg.idx, bit <<= 1) { + if (arg.mask & bit) continue; printed += scnprintf(bf + printed, size - printed, "%s%s: ", printed ? ", " : "", field->name); - - if (sc->arg_scnprintf && sc->arg_scnprintf[i]) { - printed += sc->arg_scnprintf[i](bf + printed, size - printed, - args[i], i, &mask); + if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { + arg.val = args[arg.idx]; + printed += sc->arg_scnprintf[arg.idx](bf + printed, + size - printed, &arg); } else { printed += scnprintf(bf + printed, size - printed, - "%ld", args[i]); + "%ld", args[arg.idx]); } } } else { + int i = 0; + while (i < 6) { printed += scnprintf(bf + printed, size - printed, "%sarg%d: %ld", From 1f115cb72e44391fac3ab1c562a77b421469ac2d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 3 Sep 2013 15:50:28 -0300 Subject: [PATCH 055/161] perf trace: Allow passing parms to arg formatters So that we can have generic formatters that act upon specific parameters. Start using them with a simple string table that assumes entries will be indexes to a string table, like with the 'which' parm for the set and getitimer syscalls Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-r0dqhapr8j6150v1wctgg340@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 939426c7dbde..386ca2058ee7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -35,10 +35,35 @@ struct syscall_arg { unsigned long val; + void *parm; u8 idx; u8 mask; }; +struct strarray { + int nr_entries; + const char **entries; +}; + +#define DEFINE_STRARRAY(array) struct strarray strarray__##array = { \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + +static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, + struct syscall_arg *arg) +{ + int idx = arg->val; + struct strarray *sa = arg->parm; + + if (idx < 0 || idx >= sa->nr_entries) + return scnprintf(bf, size, "%d", idx); + + return scnprintf(bf, size, "%s", sa->entries[idx]); +} + +#define SCA_STRARRAY syscall_arg__scnprintf_strarray + static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg) { @@ -229,6 +254,9 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc return printed; } +static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", }; +static DEFINE_STRARRAY(itimers); + #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, @@ -291,6 +319,7 @@ static struct syscall_fmt { const char *name; const char *alias; size_t (*arg_scnprintf[6])(char *bf, size_t size, struct syscall_arg *arg); + void *arg_parm[6]; bool errmsg; bool timeout; bool hexret; @@ -305,6 +334,9 @@ static struct syscall_fmt { { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, { .name = "futex", .errmsg = true, .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, + { .name = "getitimer", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, + .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, { .name = "ioctl", .errmsg = true, .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, { .name = "lseek", .errmsg = true, @@ -338,6 +370,9 @@ static struct syscall_fmt { { .name = "read", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, }, { .name = "select", .errmsg = true, .timeout = true, }, + { .name = "setitimer", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, + .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, { .name = "socket", .errmsg = true, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, { .name = "uname", .errmsg = true, .alias = "newuname", }, @@ -361,6 +396,7 @@ struct syscall { bool filtered; struct syscall_fmt *fmt; size_t (**arg_scnprintf)(char *bf, size_t size, struct syscall_arg *arg); + void **arg_parm; }; static size_t fprintf_duration(unsigned long t, FILE *fp) @@ -528,6 +564,9 @@ static int syscall__set_arg_fmts(struct syscall *sc) if (sc->arg_scnprintf == NULL) return -1; + if (sc->fmt) + sc->arg_parm = sc->fmt->arg_parm; + for (field = sc->tp_format->format.fields->next; field; field = field->next) { if (sc->fmt && sc->fmt->arg_scnprintf[idx]) sc->arg_scnprintf[idx] = sc->fmt->arg_scnprintf[idx]; @@ -619,6 +658,8 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, "%s%s: ", printed ? ", " : "", field->name); if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { arg.val = args[arg.idx]; + if (sc->arg_parm) + arg.parm = sc->arg_parm[arg.idx]; printed += sc->arg_scnprintf[arg.idx](bf + printed, size - printed, &arg); } else { From efe6b882cda2a9967a629fa14b6106b6a9a558a2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 3 Sep 2013 16:15:12 -0300 Subject: [PATCH 056/161] perf trace: Use strarray for ltrace's whence arg Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-5f9jhbq8my4ojarhtlygveox@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 40 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 386ca2058ee7..7cb60526a6f1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -72,31 +72,6 @@ static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, #define SCA_HEX syscall_arg__scnprintf_hex -static size_t syscall_arg__scnprintf_whence(char *bf, size_t size, - struct syscall_arg *arg) -{ - int whence = arg->val; - - switch (whence) { -#define P_WHENCE(n) case SEEK_##n: return scnprintf(bf, size, #n) - P_WHENCE(SET); - P_WHENCE(CUR); - P_WHENCE(END); -#ifdef SEEK_DATA - P_WHENCE(DATA); -#endif -#ifdef SEEK_HOLE - P_WHENCE(HOLE); -#endif -#undef P_WHENCE - default: break; - } - - return scnprintf(bf, size, "%#x", whence); -} - -#define SCA_WHENCE syscall_arg__scnprintf_whence - static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, struct syscall_arg *arg) { @@ -254,10 +229,20 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc return printed; } +#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op + static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", }; static DEFINE_STRARRAY(itimers); -#define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op +static const char *whences[] = { "SET", "CUR", "END", +#ifdef SEEK_DATA +"DATA", +#endif +#ifdef SEEK_HOLE +"HOLE", +#endif +}; +static DEFINE_STRARRAY(whences); static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) @@ -340,7 +325,8 @@ static struct syscall_fmt { { .name = "ioctl", .errmsg = true, .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, { .name = "lseek", .errmsg = true, - .arg_scnprintf = { [2] = SCA_WHENCE, /* whence */ }, }, + .arg_scnprintf = { [2] = SCA_STRARRAY, /* whence */ }, + .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, { .name = "lstat", .errmsg = true, .alias = "newlstat", }, { .name = "madvise", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* start */ From 80f587d5f9424ebdf93abbe79ab87e7fb7d4699d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 3 Sep 2013 16:28:58 -0300 Subject: [PATCH 057/161] perf trace: Beautify fcntl 'cmd' arg This is just for the low hanging fruit 'cmd' arg, a proper beautifier will as well use arg->mask to ignore the third arg for some of the cmds. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-phhvcyi9vdnxw9l11tbquvru@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7cb60526a6f1..8455a0af852c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -244,6 +244,14 @@ static const char *whences[] = { "SET", "CUR", "END", }; static DEFINE_STRARRAY(whences); +static const char *fcntl_cmds[] = { + "DUPFD", "GETFD", "SETFD", "GETFL", "SETFL", "GETLK", "SETLK", + "SETLKW", "SETOWN", "GETOWN", "SETSIG", "GETSIG", "F_GETLK64", + "F_SETLK64", "F_SETLKW64", "F_SETOWN_EX", "F_GETOWN_EX", + "F_GETOWNER_UIDS", +}; +static DEFINE_STRARRAY(fcntl_cmds); + static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -315,6 +323,9 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, { .name = "mmap", .hexret = true, }, { .name = "connect", .errmsg = true, }, + { .name = "fcntl", .errmsg = true, + .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, + .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, { .name = "fstat", .errmsg = true, .alias = "newfstat", }, { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, { .name = "futex", .errmsg = true, From eb5b1b1475d5ce6ebe84fd4c641545a41839d5f9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 3 Sep 2013 16:37:46 -0300 Subject: [PATCH 058/161] perf trace: Beautify rt_sigprocmask 'how' arg Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-e2epkc38e3x0uqmi1xie4tgc@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8455a0af852c..ecc83ce99bfe 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -252,6 +252,9 @@ static const char *fcntl_cmds[] = { }; static DEFINE_STRARRAY(fcntl_cmds); +static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", }; +static DEFINE_STRARRAY(sighow); + static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -366,6 +369,9 @@ static struct syscall_fmt { { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, { .name = "read", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, }, + { .name = "rt_sigprocmask", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* how */ }, + .arg_parm = { [0] = &strarray__sighow, /* how */ }, }, { .name = "select", .errmsg = true, .timeout = true, }, { .name = "setitimer", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, From 8bad5b0abfdbd0866c2b0445fdee8a8c2c38865b Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 3 Sep 2013 17:17:15 -0300 Subject: [PATCH 059/161] perf trace: Beautify signal number arg in several syscalls Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-ek8w714ramabyl5jqqvjlbyb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ecc83ce99bfe..eb0bbff52b42 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -311,6 +311,51 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags +static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg) +{ + int sig = arg->val; + + switch (sig) { +#define P_SIGNUM(n) case SIG##n: return scnprintf(bf, size, #n) + P_SIGNUM(HUP); + P_SIGNUM(INT); + P_SIGNUM(QUIT); + P_SIGNUM(ILL); + P_SIGNUM(TRAP); + P_SIGNUM(ABRT); + P_SIGNUM(BUS); + P_SIGNUM(FPE); + P_SIGNUM(KILL); + P_SIGNUM(USR1); + P_SIGNUM(SEGV); + P_SIGNUM(USR2); + P_SIGNUM(PIPE); + P_SIGNUM(ALRM); + P_SIGNUM(TERM); + P_SIGNUM(STKFLT); + P_SIGNUM(CHLD); + P_SIGNUM(CONT); + P_SIGNUM(STOP); + P_SIGNUM(TSTP); + P_SIGNUM(TTIN); + P_SIGNUM(TTOU); + P_SIGNUM(URG); + P_SIGNUM(XCPU); + P_SIGNUM(XFSZ); + P_SIGNUM(VTALRM); + P_SIGNUM(PROF); + P_SIGNUM(WINCH); + P_SIGNUM(IO); + P_SIGNUM(PWR); + P_SIGNUM(SYS); + default: break; + } + + return scnprintf(bf, size, "%#x", sig); +} + +#define SCA_SIGNUM syscall_arg__scnprintf_signum + static struct syscall_fmt { const char *name; const char *alias; @@ -338,6 +383,8 @@ static struct syscall_fmt { .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, { .name = "ioctl", .errmsg = true, .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, + { .name = "kill", .errmsg = true, + .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, { .name = "lseek", .errmsg = true, .arg_scnprintf = { [2] = SCA_STRARRAY, /* whence */ }, .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, @@ -369,15 +416,25 @@ static struct syscall_fmt { { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, { .name = "read", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, }, + { .name = "rt_sigaction", .errmsg = true, + .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, { .name = "rt_sigprocmask", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* how */ }, .arg_parm = { [0] = &strarray__sighow, /* how */ }, }, + { .name = "rt_sigqueueinfo", .errmsg = true, + .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, + { .name = "rt_tgsigqueueinfo", .errmsg = true, + .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, { .name = "select", .errmsg = true, .timeout = true, }, { .name = "setitimer", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, { .name = "socket", .errmsg = true, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, + { .name = "tgkill", .errmsg = true, + .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, + { .name = "tkill", .errmsg = true, + .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, { .name = "uname", .errmsg = true, .alias = "newuname", }, }; From e10bce815d5c0e7eb793231e4334839b2cd0d81f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Wed, 4 Sep 2013 10:27:41 -0300 Subject: [PATCH 060/161] perf trace: Beautify socket 'family' arg Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-8xuaupgmy82v7sha3l09oaux@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index eb0bbff52b42..62801663bd46 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -255,6 +255,16 @@ static DEFINE_STRARRAY(fcntl_cmds); static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", }; static DEFINE_STRARRAY(sighow); +static const char *socket_families[] = { + "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM", + "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI", + "SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC", + "RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC", + "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF", + "ALG", "NFC", "VSOCK", +}; +static DEFINE_STRARRAY(socket_families); + static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -429,7 +439,9 @@ static struct syscall_fmt { { .name = "setitimer", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, - { .name = "socket", .errmsg = true, }, + { .name = "socket", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ }, + .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, { .name = "tgkill", .errmsg = true, .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, From a28b24b27869d7a2fc0e6a0cae714641c83791a2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Wed, 4 Sep 2013 11:00:44 -0300 Subject: [PATCH 061/161] perf trace: Beautify socket 'type' arg Taking into account the fact that the SOCK_ types can be overriden for ABI reasons on MIPS and also masking and interpreting the socket flags (NONBLOCK and CLOEXEC), printing whatever is left in the flags bits as an hex number, or'ed. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-cbn57082gq9v0sbsd67edwjq@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 50 +++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 62801663bd46..2b19aef7d3b5 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -265,6 +265,53 @@ static const char *socket_families[] = { }; static DEFINE_STRARRAY(socket_families); +#ifndef SOCK_TYPE_MASK +#define SOCK_TYPE_MASK 0xf +#endif + +static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, + struct syscall_arg *arg) +{ + size_t printed; + int type = arg->val, + flags = type & ~SOCK_TYPE_MASK; + + type &= SOCK_TYPE_MASK; + /* + * Can't use a strarray, MIPS may override for ABI reasons. + */ + switch (type) { +#define P_SK_TYPE(n) case SOCK_##n: printed = scnprintf(bf, size, #n); break; + P_SK_TYPE(STREAM); + P_SK_TYPE(DGRAM); + P_SK_TYPE(RAW); + P_SK_TYPE(RDM); + P_SK_TYPE(SEQPACKET); + P_SK_TYPE(DCCP); + P_SK_TYPE(PACKET); +#undef P_SK_TYPE + default: + printed = scnprintf(bf, size, "%#x", type); + } + +#define P_SK_FLAG(n) \ + if (flags & SOCK_##n) { \ + printed += scnprintf(bf + printed, size - printed, "|%s", #n); \ + flags &= ~SOCK_##n; \ + } + + P_SK_FLAG(CLOEXEC); + P_SK_FLAG(NONBLOCK); +#undef P_SK_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "|%#x", flags); + + return printed; +} + +#define SCA_SK_TYPE syscall_arg__scnprintf_socket_type + static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -440,7 +487,8 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, { .name = "socket", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ }, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ + [1] = SCA_SK_TYPE, /* type */ }, .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, { .name = "tgkill", .errmsg = true, From 511089994e33c9dbfe2c6e1fb2fb00b5e53866e8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Wed, 4 Sep 2013 11:42:27 -0300 Subject: [PATCH 062/161] perf trace: Beautify access 'mode' arg Removing the _OK suffix and using RWX when all three bits are set, for instance. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-ypaz9k43lyqy94679feqnv8x@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2b19aef7d3b5..7aa6bcacd51f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -312,6 +312,33 @@ static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, #define SCA_SK_TYPE syscall_arg__scnprintf_socket_type +static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size, + struct syscall_arg *arg) +{ + size_t printed = 0; + int mode = arg->val; + + if (mode == F_OK) /* 0 */ + return scnprintf(bf, size, "F"); +#define P_MODE(n) \ + if (mode & n##_OK) { \ + printed += scnprintf(bf + printed, size - printed, "%s", #n); \ + mode &= ~n##_OK; \ + } + + P_MODE(R); + P_MODE(W); + P_MODE(X); +#undef P_MODE + + if (mode) + printed += scnprintf(bf + printed, size - printed, "|%#x", mode); + + return printed; +} + +#define SCA_ACCMODE syscall_arg__scnprintf_access_mode + static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, struct syscall_arg *arg) { @@ -422,7 +449,8 @@ static struct syscall_fmt { bool timeout; bool hexret; } syscall_fmts[] = { - { .name = "access", .errmsg = true, }, + { .name = "access", .errmsg = true, + .arg_scnprintf = { [1] = SCA_ACCMODE, /* mode */ }, }, { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, From c045bf02e47664af67f8970a6a67065ff51acf62 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Wed, 4 Sep 2013 11:52:33 -0300 Subject: [PATCH 063/161] perf trace: Beautify rlmimit resources On the getrlimit, setrlimit and prlimit64 syscalls. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-pups75313afhn7p96qwhzs9v@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7aa6bcacd51f..7ce036ee863b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -252,6 +252,13 @@ static const char *fcntl_cmds[] = { }; static DEFINE_STRARRAY(fcntl_cmds); +static const char *rlimit_resources[] = { + "CPU", "FSIZE", "DATA", "STACK", "CORE", "RSS", "NPROC", "NOFILE", + "MEMLOCK", "AS", "LOCKS", "SIGPENDING", "MSGQUEUE", "NICE", "RTPRIO", + "RTTIME", +}; +static DEFINE_STRARRAY(rlimit_resources); + static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", }; static DEFINE_STRARRAY(sighow); @@ -466,6 +473,9 @@ static struct syscall_fmt { { .name = "getitimer", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, + { .name = "getrlimit", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* resource */ }, + .arg_parm = { [0] = &strarray__rlimit_resources, /* resource */ }, }, { .name = "ioctl", .errmsg = true, .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, { .name = "kill", .errmsg = true, @@ -498,6 +508,9 @@ static struct syscall_fmt { { .name = "poll", .errmsg = true, .timeout = true, }, { .name = "ppoll", .errmsg = true, .timeout = true, }, { .name = "pread", .errmsg = true, .alias = "pread64", }, + { .name = "prlimit64", .errmsg = true, + .arg_scnprintf = { [1] = SCA_STRARRAY, /* resource */ }, + .arg_parm = { [1] = &strarray__rlimit_resources, /* resource */ }, }, { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, { .name = "read", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, }, @@ -514,6 +527,9 @@ static struct syscall_fmt { { .name = "setitimer", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, + { .name = "setrlimit", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* resource */ }, + .arg_parm = { [0] = &strarray__rlimit_resources, /* resource */ }, }, { .name = "socket", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ [1] = SCA_SK_TYPE, /* type */ }, From 4bb09192d38ef08f0619667527cabb26354fff89 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Wed, 4 Sep 2013 12:37:43 -0600 Subject: [PATCH 064/161] perf trace: Add option to show full timestamp Current timestamp shown for output is time relative to firt sample. This patch adds an option to show the absolute perf_clock timestamp which is useful when comparing output across commands (e.g., perf-trace to perf-script). Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1378319865-55695-1-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-trace.txt | 4 ++++ tools/perf/builtin-trace.c | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index daccd2c0a48f..a93e91aad583 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -78,6 +78,10 @@ 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. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script[1] diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7ce036ee863b..bc21140ac782 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -624,6 +624,7 @@ struct trace { struct perf_record_opts opts; struct machine host; u64 base_time; + bool full_time; FILE *output; unsigned long nr_events; struct strlist *ev_qualifier; @@ -1066,7 +1067,7 @@ static int trace__process_sample(struct perf_tool *tool, if (skip_sample(trace, sample)) return 0; - if (trace->base_time == 0) + if (!trace->full_time && trace->base_time == 0) trace->base_time = sample->time; if (handler) @@ -1195,7 +1196,7 @@ again: continue; } - if (trace->base_time == 0) + if (!trace->full_time && trace->base_time == 0) trace->base_time = sample.time; if (type != PERF_RECORD_SAMPLE) { @@ -1433,6 +1434,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) trace__set_duration), OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), OPT_INCR('v', "verbose", &verbose, "be more verbose"), + OPT_BOOLEAN('T', "time", &trace.full_time, + "Show full timestamp, not time relative to first start"), OPT_END() }; int err; From 770480592084d2c114adedfbe6740e345aaf2279 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Wed, 4 Sep 2013 12:37:44 -0600 Subject: [PATCH 065/161] perf trace: Remove duplicate mmap entry in syscall_fmts array Entries in syscall_fmts need to be in alphabetical order, and the duplicate entry breaks bsearch on new entries around this duplicate entry. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1378319865-55695-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bc21140ac782..903416c573af 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -461,7 +461,6 @@ static struct syscall_fmt { { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, - { .name = "mmap", .hexret = true, }, { .name = "connect", .errmsg = true, }, { .name = "fcntl", .errmsg = true, .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, From 22ae5cf1c9b4e27a3efe96d8fa6d038560a2cf23 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Thu, 12 Sep 2013 11:27:34 -0300 Subject: [PATCH 066/161] perf trace: Don't print zeroed args This way we make the output more compact. If somebody complain (and provide a sane reason why we would like to see zeroes) we can make it an optional, ~/.perfconfig configurable knob. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-myqozw43hk8z2r5hsupzdk82@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 903416c573af..516f6b39b4b6 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -818,6 +818,9 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, if (arg.mask & bit) continue; + if (args[arg.idx] == 0) + continue; + printed += scnprintf(bf + printed, size - printed, "%s%s: ", printed ? ", " : "", field->name); if (sc->arg_scnprintf && sc->arg_scnprintf[arg.idx]) { From b2cc99fdaad20b6e787f0864a1ac7b14391f9fe6 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Thu, 12 Sep 2013 11:54:48 -0300 Subject: [PATCH 067/161] perf trace: Beautify send/recv syscall 'flags' arg [root@sandy ~]# perf trace -a -e recvmmsg,recvmsg,recvfrom,sendto,sendmsg,sendmmsg 6.901 (0.002 ms): 589 recvmsg(fd: 51, msg: 0x7fff35673420, flags: CMSG_CLOEXEC) = -1 EAGAIN Resource temporarily unavailable 6.966 (0.008 ms): 589 sendmsg(fd: 50, msg: 0x7fff35673230, flags: NOSIGNAL ) = 961 6.984 (0.004 ms): 979 sendmsg(fd: 3, msg: 0x7fff5b484940, flags: NOSIGNAL ) = 945 Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-h25k5k50nac0ej5cl5iwgvae@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 67 +++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 516f6b39b4b6..c400fbee1fc7 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -319,6 +319,60 @@ static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, #define SCA_SK_TYPE syscall_arg__scnprintf_socket_type +#ifndef MSG_PROBE +#define MSG_PROBE 0x10 +#endif +#ifndef MSG_SENDPAGE_NOTLAST +#define MSG_SENDPAGE_NOTLAST 0x20000 +#endif +#ifndef MSG_FASTOPEN +#define MSG_FASTOPEN 0x20000000 +#endif + +static size_t syscall_arg__scnprintf_msg_flags(char *bf, size_t size, + struct syscall_arg *arg) +{ + int printed = 0, flags = arg->val; + + if (flags == 0) + return scnprintf(bf, size, "NONE"); +#define P_MSG_FLAG(n) \ + if (flags & MSG_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~MSG_##n; \ + } + + P_MSG_FLAG(OOB); + P_MSG_FLAG(PEEK); + P_MSG_FLAG(DONTROUTE); + P_MSG_FLAG(TRYHARD); + P_MSG_FLAG(CTRUNC); + P_MSG_FLAG(PROBE); + P_MSG_FLAG(TRUNC); + P_MSG_FLAG(DONTWAIT); + P_MSG_FLAG(EOR); + P_MSG_FLAG(WAITALL); + P_MSG_FLAG(FIN); + P_MSG_FLAG(SYN); + P_MSG_FLAG(CONFIRM); + P_MSG_FLAG(RST); + P_MSG_FLAG(ERRQUEUE); + P_MSG_FLAG(NOSIGNAL); + P_MSG_FLAG(MORE); + P_MSG_FLAG(WAITFORONE); + P_MSG_FLAG(SENDPAGE_NOTLAST); + P_MSG_FLAG(FASTOPEN); + P_MSG_FLAG(CMSG_CLOEXEC); +#undef P_MSG_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags); + + return printed; +} + +#define SCA_MSG_FLAGS syscall_arg__scnprintf_msg_flags + static size_t syscall_arg__scnprintf_access_mode(char *bf, size_t size, struct syscall_arg *arg) { @@ -512,7 +566,12 @@ static struct syscall_fmt { .arg_parm = { [1] = &strarray__rlimit_resources, /* resource */ }, }, { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, { .name = "read", .errmsg = true, }, - { .name = "recvfrom", .errmsg = true, }, + { .name = "recvfrom", .errmsg = true, + .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, + { .name = "recvmmsg", .errmsg = true, + .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, + { .name = "recvmsg", .errmsg = true, + .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "rt_sigaction", .errmsg = true, .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, { .name = "rt_sigprocmask", .errmsg = true, @@ -523,6 +582,12 @@ static struct syscall_fmt { { .name = "rt_tgsigqueueinfo", .errmsg = true, .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, { .name = "select", .errmsg = true, .timeout = true, }, + { .name = "sendmmsg", .errmsg = true, + .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, + { .name = "sendmsg", .errmsg = true, + .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, + { .name = "sendto", .errmsg = true, + .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "setitimer", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, From 49af9e93adfa11d50435aa079299a765843532fc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Thu, 12 Sep 2013 12:18:56 -0300 Subject: [PATCH 068/161] perf trace: Beautify eventfd2 'flags' arg 61.168 ( 0.004 ms): 24267 eventfd2(flags: CLOEXEC|NONBLOCK) = 9 Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-3hg8eajdzil077501c8f5jkw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c400fbee1fc7..8a09ba3dcd97 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -13,6 +13,7 @@ #include <libaudit.h> #include <stdlib.h> +#include <sys/eventfd.h> #include <sys/mman.h> #include <linux/futex.h> @@ -456,6 +457,32 @@ static size_t syscall_arg__scnprintf_open_flags(char *bf, size_t size, #define SCA_OPEN_FLAGS syscall_arg__scnprintf_open_flags +static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size, + struct syscall_arg *arg) +{ + int printed = 0, flags = arg->val; + + if (flags == 0) + return scnprintf(bf, size, "NONE"); +#define P_FLAG(n) \ + if (flags & EFD_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~EFD_##n; \ + } + + P_FLAG(SEMAPHORE); + P_FLAG(CLOEXEC); + P_FLAG(NONBLOCK); +#undef P_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags); + + return printed; +} + +#define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags + static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg) { int sig = arg->val; @@ -516,6 +543,8 @@ static struct syscall_fmt { { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, { .name = "connect", .errmsg = true, }, + { .name = "eventfd2", .errmsg = true, + .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, { .name = "fcntl", .errmsg = true, .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, From 50c95cbd70808aa2e5ba8d79e503456f1da37aeb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Thu, 12 Sep 2013 12:35:21 -0300 Subject: [PATCH 069/161] perf trace: Add option to show process COMM Enabled by default, disable with --no-comm, e.g.: 181.821 (0.001 ms): deja-dup-monit/10784 recvmsg(fd: 8, msg: 0x7fff4342baf0, flags: PEEK|TRUNC|CMSG_CLOEXEC ) = 20 181.824 (0.001 ms): deja-dup-monit/10784 geteuid( ) = 1000 181.825 (0.001 ms): deja-dup-monit/10784 getegid( ) = 1000 181.834 (0.002 ms): deja-dup-monit/10784 recvmsg(fd: 8, msg: 0x7fff4342baf0, flags: CMSG_CLOEXEC ) = 20 181.836 (0.001 ms): deja-dup-monit/10784 geteuid( ) = 1000 181.838 (0.001 ms): deja-dup-monit/10784 getegid( ) = 1000 181.705 (0.003 ms): evolution-addr/10924 recvmsg(fd: 10, msg: 0x7fff17dc6990, flags: PEEK|TRUNC|CMSG_CLOEXEC) = 1256 181.710 (0.002 ms): evolution-addr/10924 geteuid( ) = 1000 181.712 (0.001 ms): evolution-addr/10924 getegid( ) = 1000 181.727 (0.003 ms): evolution-addr/10924 recvmsg(fd: 10, msg: 0x7fff17dc6990, flags: CMSG_CLOEXEC ) = 1256 181.731 (0.001 ms): evolution-addr/10924 geteuid( ) = 1000 181.734 (0.001 ms): evolution-addr/10924 getegid( ) = 1000 181.908 (0.002 ms): evolution-addr/10924 recvmsg(fd: 10, msg: 0x7fff17dc6990, flags: PEEK|TRUNC|CMSG_CLOEXEC) = 20 181.913 (0.001 ms): evolution-addr/10924 geteuid( ) = 1000 181.915 (0.001 ms): evolution-addr/10924 getegid( ) = 1000 181.930 (0.003 ms): evolution-addr/10924 recvmsg(fd: 10, msg: 0x7fff17dc6990, flags: CMSG_CLOEXEC ) = 20 181.934 (0.001 ms): evolution-addr/10924 geteuid( ) = 1000 181.937 (0.001 ms): evolution-addr/10924 getegid( ) = 1000 220.718 (0.010 ms): at-spi2-regist/10715 sendmsg(fd: 3, msg: 0x7fffdb8756c0, flags: NOSIGNAL ) = 200 220.741 (0.000 ms): dbus-daemon/10711 ... [continued]: epoll_wait()) = 1 220.759 (0.004 ms): dbus-daemon/10711 recvmsg(fd: 11, msg: 0x7ffff94594d0, flags: CMSG_CLOEXEC ) = 200 220.780 (0.002 ms): dbus-daemon/10711 recvmsg(fd: 11, msg: 0x7ffff94594d0, flags: CMSG_CLOEXEC ) = 200 220.788 (0.001 ms): dbus-daemon/10711 recvmsg(fd: 11, msg: 0x7ffff94594d0, flags: CMSG_CLOEXEC ) = -1 EAGAIN Resource temporarily unavailable 220.760 (0.004 ms): at-spi2-regist/10715 sendmsg(fd: 3, msg: 0x7fffdb8756c0, flags: NOSIGNAL ) = 200 220.771 (0.023 ms): perf/26347 open(filename: 0xf2e780, mode: 15918976 ) = 19 220.850 (0.002 ms): perf/26347 close(fd: 19 ) = 0 Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-6be5jvnkdzjptdrebfn5263n@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-trace.txt | 3 +++ tools/perf/builtin-trace.c | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index a93e91aad583..37773854d5c4 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -82,6 +82,9 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. --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. + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script[1] diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8a09ba3dcd97..be658433d3bb 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -726,6 +726,7 @@ struct trace { struct intlist *pid_list; bool sched; bool multiple_threads; + bool show_comm; double duration_filter; double runtime_ms; }; @@ -755,8 +756,11 @@ static size_t trace__fprintf_entry_head(struct trace *trace, struct thread *thre size_t printed = trace__fprintf_tstamp(trace, tstamp, fp); printed += fprintf_duration(duration, fp); - if (trace->multiple_threads) + if (trace->multiple_threads) { + if (trace->show_comm) + printed += fprintf(fp, "%.14s/", thread->comm); printed += fprintf(fp, "%d ", thread->tid); + } return printed; } @@ -1503,10 +1507,13 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) .mmap_pages = 1024, }, .output = stdout, + .show_comm = true, }; const char *output_name = NULL; const char *ev_qualifier_str = NULL; const struct option trace_options[] = { + OPT_BOOLEAN(0, "comm", &trace.show_comm, + "show the thread COMM next to its id"), OPT_STRING('e', "expr", &ev_qualifier_str, "expr", "list of events to trace"), OPT_STRING('o', "output", &output_name, "file", "output file name"), From 1ba6e01782fd2a94481e18b91b363636f8171565 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 4 Jul 2013 18:11:25 +0530 Subject: [PATCH 070/161] perf completion: Don't dictate perf install location The statement have perf limits the locations in which to look for the perf program. Moreover, it depends on the bash-completion package to be installed. Replace it with a call to `type perf`. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1372941691-14684-2-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bash_completion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion index 56e6a12aab59..50540cfe3d18 100644 --- a/tools/perf/bash_completion +++ b/tools/perf/bash_completion @@ -19,7 +19,7 @@ __ltrim_colon_completions() fi } -have perf && +type perf &>/dev/null && _perf() { local cur prev cmd From 30079d1d5ebcb8d706c6e05cacebb7facc60cd95 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 4 Jul 2013 18:11:26 +0530 Subject: [PATCH 071/161] perf completion: Update __ltrim_colon_completions The function is taken from the bash-completion package; update it to use the latest version where colon_word doesn't miss quoting. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1372941691-14684-3-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bash_completion | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion index 50540cfe3d18..b0cdd12bd5e4 100644 --- a/tools/perf/bash_completion +++ b/tools/perf/bash_completion @@ -11,7 +11,7 @@ __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"} From 7b6c48e16e5d312b0ebae78acfb3ff4f9c8c083c Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 4 Jul 2013 18:11:27 +0530 Subject: [PATCH 072/161] perf completion: Strip dependency on _filedir _filedir is defined in the bash-completion package, but there is no need to depend on it. Instead, call complete with multiple -o arguments before the -F argument like in git.git's completion script. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1372941691-14684-4-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bash_completion | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion index b0cdd12bd5e4..d2598be517fb 100644 --- a/tools/perf/bash_completion +++ b/tools/perf/bash_completion @@ -54,9 +54,8 @@ _perf() subcmd=${COMP_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 From 4685a6cfaeac6d2fe8ed10a9aa0cbff5026529cb Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 4 Jul 2013 18:11:29 +0530 Subject: [PATCH 073/161] perf completion: Strip function_exists () Use "type" to check existence consistently. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1372941691-14684-6-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bash_completion | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion index d2598be517fb..35fdda1540d8 100644 --- a/tools/perf/bash_completion +++ b/tools/perf/bash_completion @@ -1,12 +1,6 @@ # perf completion -function_exists() -{ - declare -F $1 > /dev/null - return $? -} - -function_exists __ltrim_colon_completions || +type __ltrim_colon_completions &>/dev/null || __ltrim_colon_completions() { if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then From c3fb6717e90049b93d0f5f5714a4d878799d89c2 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 4 Jul 2013 18:11:30 +0530 Subject: [PATCH 074/161] perf completion: Strip dependency on bash-completion The bash-completion package defines the _get_comp_words_by_ref function. There is no need to depend on it, as we can reimplement it like git.git has. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Link: http://lkml.kernel.org/r/1372941691-14684-7-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bash_completion | 83 +++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion index 35fdda1540d8..ee9c6d85f2c9 100644 --- a/tools/perf/bash_completion +++ b/tools/perf/bash_completion @@ -1,5 +1,81 @@ # perf completion +# Taken from git.git's completion script. +__my_reassemble_comp_words_by_ref() +{ + 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 +} + +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() { @@ -19,12 +95,7 @@ _perf() local cur 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 prev cmd=${COMP_WORDS[0]} From 6e0dc374a2c912a8a967ea8a4f9696dd4b0a6d3e Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 4 Jul 2013 18:11:31 +0530 Subject: [PATCH 075/161] perf completion: Use more comp words The completion words $words and $cword are available, so we might as well use them instead of directly accessing COMP_WORDS. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Link: http://lkml.kernel.org/r/1372941691-14684-8-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bash_completion | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/perf/bash_completion b/tools/perf/bash_completion index ee9c6d85f2c9..62e157db2e2b 100644 --- a/tools/perf/bash_completion +++ b/tools/perf/bash_completion @@ -92,15 +92,15 @@ __ltrim_colon_completions() type perf &>/dev/null && _perf() { - local cur prev cmd + local cur words cword prev cmd COMPREPLY=() - _get_comp_words_by_ref -n : cur prev + _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 \ @@ -110,13 +110,13 @@ _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" ) ) fi From 9cd00941f8c274e6ca03ed238d96ddb0be474b86 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> Date: Wed, 18 Sep 2013 15:56:14 +0200 Subject: [PATCH 076/161] perf symbols: Support for Openembedded/Yocto -dbg packages On OpenEmbedded the symbol files are located under a .debug folder on the same folder as the binary file. This patch adds support for such files. Without this patch on perf top you can see: no symbols found in /usr/lib/gstreamer-1.0/libtheoraenc.so.1.1.2, maybe install a debug package? 84.56% libtheoraenc.so.1.1.2 [.] 0x000000000000b346 With this patch symbols are shown: 19.06% libtheoraenc.so.1.1.2 [.] oc_int_frag_satd_thresh_mmxext 9.76% libtheoraenc.so.1.1.2 [.] oc_analyze_mb_mode_luma 5.58% libtheoraenc.so.1.1.2 [.] oc_qii_state_advance 4.84% libtheoraenc.so.1.1.2 [.] oc_enc_tokenize_ac ... Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Waiman Long <Waiman.Long@hp.com> Link: http://lkml.kernel.org/r/1379512574-25912-1-git-send-email-ricardo.ribalda@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/dso.c | 49 +++++++++++++++++++++++++++++----------- tools/perf/util/dso.h | 1 + tools/perf/util/symbol.c | 1 + 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index e3c1ff8512c8..6bfc8aacaf7c 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -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; diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index b793053335d6..dbd9241ea290 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -23,6 +23,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, }; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 7eb0362f4ffd..cd1dcc45049b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -51,6 +51,7 @@ static enum dso_binary_type binary_type_symtab[] = { DSO_BINARY_TYPE__SYSTEM_PATH_DSO, DSO_BINARY_TYPE__GUEST_KMODULE, DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE, + DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO, DSO_BINARY_TYPE__NOT_FOUND, }; From 5283ec23a02e8afdc984c7f5f07e2a2662d4934a Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Thu, 12 Sep 2013 18:39:34 +0200 Subject: [PATCH 077/161] perf tools: Remove unused trace-event-* code Removing unused trace-event-* code. Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1379003976-5839-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/trace-event-parse.c | 36 ----------------------------- tools/perf/util/trace-event.h | 9 -------- 2 files changed, 45 deletions(-) diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index e9e1c03f927d..6681f71f2f95 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c @@ -120,42 +120,6 @@ raw_field_value(struct event_format *event, const char *name, void *data) return val; } -void *raw_field_ptr(struct event_format *event, const char *name, void *data) -{ - struct format_field *field; - - field = pevent_find_any_field(event, name); - if (!field) - return NULL; - - if (field->flags & FIELD_IS_DYNAMIC) { - int offset; - - offset = *(int *)(data + field->offset); - offset &= 0xffff; - - return data + offset; - } - - return data + field->offset; -} - -int trace_parse_common_type(struct pevent *pevent, void *data) -{ - struct pevent_record record; - - record.data = data; - return pevent_data_type(pevent, &record); -} - -int trace_parse_common_pid(struct pevent *pevent, void *data) -{ - struct pevent_record record; - - record.data = data; - return pevent_data_pid(pevent, &record); -} - unsigned long long read_size(struct event_format *event, void *ptr, int size) { return pevent_read_number(event->pevent, ptr, size); diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index fafe1a40444a..04df63114109 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -11,8 +11,6 @@ union perf_event; struct perf_tool; struct thread; -extern struct pevent *perf_pevent; - int bigendian(void); struct pevent *read_trace_init(int file_bigendian, int host_bigendian); @@ -23,26 +21,19 @@ int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size); int parse_event_file(struct pevent *pevent, char *buf, unsigned long size, char *sys); -struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu); - unsigned long long raw_field_value(struct event_format *event, const char *name, void *data); -void *raw_field_ptr(struct event_format *event, const char *name, void *data); void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size); ssize_t trace_report(int fd, struct pevent **pevent, bool repipe); -int trace_parse_common_type(struct pevent *pevent, void *data); -int trace_parse_common_pid(struct pevent *pevent, void *data); - struct event_format *trace_find_next_event(struct pevent *pevent, struct event_format *event); unsigned long long read_size(struct event_format *event, void *ptr, int size); unsigned long long eval_flag(const char *flag); -struct pevent_record *trace_read_data(struct pevent *pevent, int cpu); int read_tracing_data(int fd, struct list_head *pattrs); struct tracing_data { From 918512b435e15fefe609d236e0ecd62cb8f389c9 Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Thu, 12 Sep 2013 18:39:35 +0200 Subject: [PATCH 078/161] perf tools: Unify page_size usage Making page_size global from the util object. Removing the not needed one. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1379003976-5839-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-record.c | 5 +---- tools/perf/perf.c | 1 + tools/perf/util/python.c | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index cf36ba2a1591..0aacd6295fe6 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -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; @@ -360,8 +359,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); diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 245020cc6180..626577830264 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -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]); diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 71b5412bbbb9..a24ce0a6a941 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -1036,6 +1036,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); From 02ad0702e54f9b82b697718e7e8662eb3f2266ee Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <davidlohr@hp.com> Date: Sun, 8 Sep 2013 19:19:13 -0700 Subject: [PATCH 079/161] perf lock: Remove dead code No need for break statements after goto jumps. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1378693159-8747-2-git-send-email-davidlohr@hp.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-lock.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index ee33ba2f05dd..148f7e28ade7 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -446,7 +446,6 @@ broken: list_del(&seq->list); free(seq); goto end; - break; default: BUG_ON("Unknown state of lock sequence found!\n"); break; @@ -508,8 +507,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; @@ -564,7 +561,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; @@ -606,7 +602,6 @@ static int report_lock_release_event(struct perf_evsel *evsel, switch (seq->state) { case SEQ_STATE_UNINITIALIZED: goto end; - break; case SEQ_STATE_ACQUIRED: break; case SEQ_STATE_READ_ACQUIRED: @@ -624,7 +619,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; From b33492ade49a223a666e582d0c63566609e7014b Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <davidlohr@hp.com> Date: Sun, 8 Sep 2013 19:19:14 -0700 Subject: [PATCH 080/161] perf lock: Return proper code in report_lock_*_event The report_lock_*_event() functions return -1 when lock_stat_findnew(), thread_stat_findnew() or get_seq() return NULL. These functions only return this value when failing to allocate memory, this return -ENOMEM instead. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1378693159-8747-3-git-send-email-davidlohr@hp.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-lock.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 148f7e28ade7..d3188629cbaf 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -400,17 +400,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: @@ -472,17 +472,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: @@ -533,17 +533,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: @@ -587,17 +587,17 @@ 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: From 0a98c7febf55325ebac4f28289a9433f4b66ed0e Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <davidlohr@hp.com> Date: Sun, 8 Sep 2013 19:19:15 -0700 Subject: [PATCH 081/161] perf lock: Plug some memleaks Address some trivial leaks. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1378693159-8747-4-git-send-email-davidlohr@hp.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-lock.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index d3188629cbaf..77843478a27a 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -321,10 +321,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); @@ -875,7 +877,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++) { @@ -892,7 +894,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++) @@ -908,7 +910,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) From 375eb2be5584b8182a917124ca217b74e43d2dc4 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <davidlohr@hp.com> Date: Sun, 8 Sep 2013 19:19:16 -0700 Subject: [PATCH 082/161] perf lock: Redo __cmd_report This function should be straightforward, and we can remove some trivial logic by moving the functionality of read_events() into __cmd_report() - thus allowing a new session to be properly deleted. Since the 'info' subcommand also needs to process the recorded events, add a 'display_info' flag to differentiate between report and info commands. Furthermore, this patch also calls perf_session__has_traces(), making sure that we don't compare apples and oranges, fixing a segfault when using an perf.data file generated by a different subcommand. ie: ./perf mem record sleep 1 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.017 MB perf.data (~724 samples) ] ./perf lock report Segmentation fault (core dumped) Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1378693159-8747-5-git-send-email-davidlohr@hp.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-lock.c | 90 ++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 77843478a27a..780484fb59a0 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -818,34 +818,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; @@ -858,18 +830,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) @@ -970,7 +978,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); @@ -983,11 +991,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); } From 60a25cbc4a167fc0129296c3c640d8506a57acc5 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <davidlohr@hp.com> Date: Sun, 8 Sep 2013 19:19:18 -0700 Subject: [PATCH 083/161] perf lock: Limit bad rate precision Two decimal precision should be enough for this. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1378693159-8747-7-git-send-email-davidlohr@hp.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 780484fb59a0..972310cbeb63 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -686,7 +686,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]); From f37376cd721a539ac398cbb7718b72fce83cd49b Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso <davidlohr@hp.com> Date: Sun, 8 Sep 2013 19:19:19 -0700 Subject: [PATCH 084/161] perf lock: Account for lock average wait time While perf-lock currently reports both the total wait time and the number of contentions, it doesn't explicitly show the average wait time. Having this value immediately in the report can be quite useful when looking into performance issues. Furthermore, allowing report to sort by averages is another handy feature to have - and thus do not only print the value, but add it to the lock_stat structure. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Aswin Chandramouleeswaran <aswin@hp.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1378693159-8747-8-git-send-email-davidlohr@hp.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-lock.txt | 2 +- tools/perf/builtin-lock.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/Documentation/perf-lock.txt b/tools/perf/Documentation/perf-lock.txt index c7f5f55634ac..ab25be28c9dc 100644 --- a/tools/perf/Documentation/perf-lock.txt +++ b/tools/perf/Documentation/perf-lock.txt @@ -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 ------------ diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 972310cbeb63..6a9076f165f4 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -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), @@ -516,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; @@ -570,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; @@ -703,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)"); @@ -734,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 ? @@ -940,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() }; From 994a1f78b191df0c9d6caca3f3afb03e247aff26 Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Sun, 1 Sep 2013 12:36:12 +0200 Subject: [PATCH 085/161] perf tools: Check mmap pages value early Move the check of the mmap_pages value to the options parsing time, so we could rely on this value on other parts of code. Related changes come in the next patches. Also changes perf_evlist::mmap_len to proper size_t type. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378031796-17892-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-kvm.c | 5 ++-- tools/perf/builtin-record.c | 9 +++----- tools/perf/builtin-top.c | 5 ++-- tools/perf/builtin-trace.c | 5 ++-- tools/perf/util/evlist.c | 46 +++++++++++++++++++++++++++++-------- tools/perf/util/evlist.h | 6 ++++- 6 files changed, 54 insertions(+), 22 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 935d52216c89..cfa0b7979914 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -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, diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0aacd6295fe6..92ca5419073b 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -233,10 +233,6 @@ try_again: "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; @@ -854,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, diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b3e0229ee38f..e8466956adbe 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1075,8 +1075,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) "file", "vmlinux pathname"), 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, diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index be658433d3bb..f3ddbb008fb4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1528,8 +1528,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) "list of cpus to monitor"), OPT_BOOLEAN(0, "no-inherit", &trace.opts.no_inherit, "child tasks do not inherit counters"), - OPT_UINTEGER('m', "mmap-pages", &trace.opts.mmap_pages, - "number of mmap data pages"), + OPT_CALLBACK('m', "mmap-pages", &trace.opts.mmap_pages, "pages", + "number of mmap data pages", + perf_evlist__parse_mmap_pages), OPT_STRING('u', "uid", &trace.opts.target.uid_str, "user", "user to profile"), OPT_CALLBACK(0, "duration", &trace, "float", diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f9f77bee0b1b..4283f49ca0ab 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -18,6 +18,7 @@ #include <unistd.h> #include "parse-events.h" +#include "parse-options.h" #include <sys/mman.h> @@ -672,6 +673,40 @@ out_unmap: 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, *mmap_pages = opt->value; + size_t size; + 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 +730,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 +737,8 @@ 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); + mask = evlist->mmap_len - page_size - 1; list_for_each_entry(evsel, &evlist->entries, node) { if ((evsel->attr.read_format & PERF_FORMAT_ID) && diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 880d7139d2fb..4edb5008fd36 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -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; @@ -103,6 +103,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); From 27050f530dc4fd88dc93d85c177e000efe970d12 Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Sun, 1 Sep 2013 12:36:13 +0200 Subject: [PATCH 086/161] perf tools: Add possibility to specify mmap size Adding possibility to specify mmap size via -m/--mmap-pages by appending unit size character (B/K/M/G) to the number, like: $ perf record -m 8K ls $ perf record -m 2M ls The size is rounded up appropriately to follow perf mmap restrictions. If no unit is specified the number provides pages as of now, like: $ perf record -m 8 ls Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378031796-17892-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-kvm.txt | 4 ++- tools/perf/Documentation/perf-record.txt | 4 ++- tools/perf/Documentation/perf-top.txt | 4 ++- tools/perf/Documentation/perf-trace.txt | 4 ++- tools/perf/util/evlist.c | 32 +++++++++++++++++++----- tools/perf/util/util.c | 25 ++++++++++++++++++ tools/perf/util/util.h | 14 +++++++++++ 7 files changed, 77 insertions(+), 10 deletions(-) diff --git a/tools/perf/Documentation/perf-kvm.txt b/tools/perf/Documentation/perf-kvm.txt index ac84db2d2334..6a06cefe9642 100644 --- a/tools/perf/Documentation/perf-kvm.txt +++ b/tools/perf/Documentation/perf-kvm.txt @@ -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:: diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index f732eaa6a500..f10ab63576d7 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -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:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 6d70fbfe28a2..f65777c1f723 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -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>:: diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 37773854d5c4..7f70d3640edd 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -59,7 +59,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:: diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4283f49ca0ab..d21ab0812926 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -687,14 +687,33 @@ static size_t perf_evlist__mmap_size(unsigned long pages) int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, int unset __maybe_unused) { - unsigned int pages, *mmap_pages = opt->value; + unsigned int pages, val, *mmap_pages = opt->value; size_t size; - char *eptr; + 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 }, + }; - pages = strtoul(str, &eptr, 10); - if (*eptr != '\0') { - pr_err("failed to parse --mmap_pages/-m value\n"); - return -1; + 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); @@ -738,6 +757,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, evlist->overwrite = overwrite; 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) { diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index ccfdeb62f576..ab71d6216803 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -361,3 +361,28 @@ int parse_nsec_time(const char *str, u64 *ptime) *ptime = time_sec * NSEC_PER_SEC + time_nsec; return 0; } + +unsigned long parse_tag_value(const char *str, struct parse_tag *tags) +{ + struct parse_tag *i = tags; + + while (i->tag) { + char *s; + + s = strchr(str, i->tag); + if (s) { + unsigned long int value; + char *endptr; + + value = strtoul(str, &endptr, 10); + if (s != endptr) + break; + + value *= i->mult; + return value; + } + i++; + } + + return (unsigned long) -1; +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index a53535949043..c29ecaabf461 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -270,6 +270,13 @@ bool is_power_of_2(unsigned long n) return (n != 0 && ((n & (n - 1)) == 0)); } +static inline unsigned next_pow2(unsigned x) +{ + if (!x) + return 1; + return 1ULL << (32 - __builtin_clz(x - 1)); +} + size_t hex_width(u64 v); int hex2u64(const char *ptr, u64 *val); @@ -281,4 +288,11 @@ void dump_stack(void); extern unsigned int page_size; void get_term_dimensions(struct winsize *ws); + +struct parse_tag { + char tag; + int mult; +}; + +unsigned long parse_tag_value(const char *str, struct parse_tag *tags); #endif /* GIT_COMPAT_UTIL_H */ From b22d54b09a5448d3706929c6f0eae36429f4ec5d Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Sun, 1 Sep 2013 12:36:14 +0200 Subject: [PATCH 087/161] perf evlist: Introduce perf_evlist__new_default function Adding new common function to create evlist with default event. It spares some code lines in automated tests. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378031796-17892-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/tests/perf-record.c | 12 +----------- tools/perf/tests/task-exit.c | 14 ++------------ tools/perf/util/evlist.c | 12 ++++++++++++ tools/perf/util/evlist.h | 1 + 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index b8a7056519ac..82ac71550091 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -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 diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 28fe5894b061..b07f8a14e15d 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -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 @@ out_close_evlist: perf_evlist__close(evlist); out_delete_maps: perf_evlist__delete_maps(evlist); -out_free_evlist: perf_evlist__delete(evlist); return err; } diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d21ab0812926..f0d71a9d49f4 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -50,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 diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 4edb5008fd36..871b55ab5dee 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -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); From dd96c46b5c765a779d8c35cc7d1df7515b4c7baf Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Sun, 1 Sep 2013 12:36:15 +0200 Subject: [PATCH 088/161] perf tools: Adding throttle event data struct support Moving 'struct throttle_event' out of python code and making it global as any other event. There's no usage of throttling events in any perf commands so far (besides python support), but we'll need this event data backup for upcoming test. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378031796-17892-5-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/event.h | 7 +++++++ tools/perf/util/python.c | 7 ------- tools/perf/util/session.c | 13 +++++++++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 17d9e167a7b9..9b7d4d333111 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -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 | \ @@ -178,6 +184,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; diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index a24ce0a6a941..06efd027b1db 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c @@ -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) \ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index b97f468af955..d1e449534b33 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -397,6 +397,17 @@ static void perf_event__read_swap(union perf_event *event, bool sample_id_all) swap_sample_id_all(event, &event->read + 1); } +static void perf_event__throttle_swap(union perf_event *event, + bool sample_id_all) +{ + event->throttle.time = bswap_64(event->throttle.time); + event->throttle.id = bswap_64(event->throttle.id); + event->throttle.stream_id = bswap_64(event->throttle.stream_id); + + if (sample_id_all) + swap_sample_id_all(event, &event->throttle + 1); +} + static u8 revbyte(u8 b) { int rev = (b >> 4) | ((b & 0xf) << 4); @@ -482,6 +493,8 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_EXIT] = perf_event__task_swap, [PERF_RECORD_LOST] = perf_event__all64_swap, [PERF_RECORD_READ] = perf_event__read_swap, + [PERF_RECORD_THROTTLE] = perf_event__throttle_swap, + [PERF_RECORD_UNTHROTTLE] = perf_event__throttle_swap, [PERF_RECORD_SAMPLE] = perf_event__all64_swap, [PERF_RECORD_HEADER_ATTR] = perf_event__hdr_attr_swap, [PERF_RECORD_HEADER_EVENT_TYPE] = perf_event__event_type_swap, From fc2be6968e99b5314f20e938a547d44dcb1c40eb Mon Sep 17 00:00:00 2001 From: Willy Tarreau <w@1wt.eu> Date: Sat, 14 Sep 2013 10:32:59 +0200 Subject: [PATCH 089/161] perf symbols: Add new option --ignore-vmlinux for perf top Running "perf top" on a machine with possibly invalid or non-matching vmlinux at the various places results in no symbol resolving despite /proc/kallsyms being present and valid. Add a new option --ignore-vmlinux to explicitly indicate that we do not want to use these kernels and just use what we have (kallsyms). Signed-off-by: Willy Tarreau <w@1wt.eu> Cc: Ingo Molnar <mingo@redhat.com> Link: http://lkml.kernel.org/r/20130914083259.GA3418@1wt.eu Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-top.c | 2 ++ tools/perf/util/symbol.c | 4 ++-- tools/perf/util/symbol.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e8466956adbe..65c49b2f51c1 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1073,6 +1073,8 @@ 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_CALLBACK('m', "mmap-pages", &opts->mmap_pages, "pages", diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index cd1dcc45049b..48c38791d61b 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1215,7 +1215,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map, goto do_kallsyms; } - if (symbol_conf.vmlinux_name != NULL) { + if (!symbol_conf.ignore_vmlinux && symbol_conf.vmlinux_name != NULL) { err = dso__load_vmlinux(dso, map, symbol_conf.vmlinux_name, filter); if (err > 0) { @@ -1227,7 +1227,7 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map, return err; } - if (vmlinux_path != NULL) { + if (!symbol_conf.ignore_vmlinux && vmlinux_path != NULL) { err = dso__load_vmlinux_path(dso, map, filter); if (err > 0) return err; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2a97bb1a8097..9b8b213a62c1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -85,6 +85,7 @@ struct symbol_conf { unsigned short priv_size; unsigned short nr_events; bool try_vmlinux_path, + ignore_vmlinux, show_kernel_path, use_modules, sort_by_name, From fc67297b16da335d610af2fac96233d51146300a Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung@kernel.org> Date: Fri, 13 Sep 2013 15:27:43 +0900 Subject: [PATCH 090/161] perf tools: Separate out GTK codes to libperf-gtk.so Separate out GTK codes to a shared object called libperf-gtk.so. This time only GTK codes are built with -fPIC and libperf remains as is. Now run GTK hist and annotation browser using libdl. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Pekka Enberg <penberg@kernel.org> Cc: Andi Kleen <ak@linux.intel.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1379053663-13706-1-git-send-email-namhyung@kernel.org [ Fix it up wrt Ingo's tools/perf build speedups ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile.perf | 42 +++++++++++++++++------- tools/perf/builtin-annotate.c | 26 +++++++++++++-- tools/perf/builtin-report.c | 16 +++++++-- tools/perf/config/Makefile | 12 +++++-- tools/perf/ui/gtk/annotate.c | 13 ++++++-- tools/perf/ui/gtk/gtk.h | 16 +++++++++ tools/perf/ui/setup.c | 61 +++++++++++++++++++++++++++++++++-- tools/perf/ui/ui.h | 12 +------ tools/perf/util/annotate.h | 24 -------------- tools/perf/util/hist.h | 15 --------- tools/perf/util/util.h | 2 ++ 11 files changed, 165 insertions(+), 74 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index a24f6c280b95..40c39c39ce80 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -114,6 +114,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ BUILTIN_OBJS = LIB_H = LIB_OBJS = +GTK_OBJS = PYRF_OBJS = SCRIPT_SH = @@ -490,13 +491,19 @@ ifndef NO_SLANG 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 + 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 + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)' + $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' endif ifndef NO_LIBPERL @@ -550,6 +557,12 @@ $(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)"' \ @@ -632,6 +645,9 @@ $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS $(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 $< @@ -673,7 +689,8 @@ $(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 = $(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))): @@ -786,7 +803,9 @@ check: $(OUTPUT)common-cmds.h ### Installation rules -install-bin: all +install-gtk: + +install-bin: all install-gtk $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' @@ -831,7 +850,8 @@ config-clean: @$(MAKE) -C config/feature-checks clean clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean - $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) + $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(GTK_OBJS) + $(RM) $(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 @@ -850,7 +870,7 @@ else GIT-HEAD-PHONY = endif -.PHONY: all install clean config-clean strip +.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 diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 0393d9800516..94f9a8e78117 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -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 @@ find_next: 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: /* diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 06e1abe351dd..21b5c2f54c2a 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -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); diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index f5d661f5637d..d9bba8d57c40 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -377,11 +377,11 @@ ifndef NO_GTK2 NO_GTK2 := 1 else ifeq ($(feature-gtk2-infobar), 1) - CFLAGS += -DHAVE_GTK_INFO_BAR_SUPPORT + GTK_CFLAGS := -DHAVE_GTK_INFO_BAR_SUPPORT endif CFLAGS += -DHAVE_GTK2_SUPPORT - CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null) - EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null) + GTK_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null) + GTK_LIBS := $(shell pkg-config --libs gtk+-2.0 2>/dev/null) endif endif @@ -554,7 +554,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)) @@ -567,6 +572,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) diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c index f538794615db..9c7ff8d31b27 100644 --- a/tools/perf/ui/gtk/annotate.c +++ b/tools/perf/ui/gtk/annotate.c @@ -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; diff --git a/tools/perf/ui/gtk/gtk.h b/tools/perf/ui/gtk/gtk.h index a72acbc565e0..8576cf194872 100644 --- a/tools/perf/ui/gtk/gtk.h +++ b/tools/perf/ui/gtk/gtk.h @@ -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) @@ -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_ */ diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c index 47d9a571f261..5df5140a9f29 100644 --- a/tools/perf/ui/setup.c +++ b/tools/perf/ui/setup.c @@ -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: diff --git a/tools/perf/ui/ui.h b/tools/perf/ui/ui.h index 1349d142a005..ab88383f8be8 100644 --- a/tools/perf/ui/ui.h +++ b/tools/perf/ui/ui.h @@ -6,6 +6,7 @@ #include <linux/compiler.h> extern pthread_mutex_t ui__lock; +extern void *perf_gtk_handle; extern int use_browser; @@ -23,17 +24,6 @@ static inline int ui__init(void) static inline void ui__exit(bool wait_for_ok __maybe_unused) {} #endif -#ifdef HAVE_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_ */ diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index f0699e9bcc6f..834b7b57b788 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -165,30 +165,6 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, } #endif -#ifdef HAVE_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 */ diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ed4f90ebe0d5..20b175808cd3 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -228,20 +228,5 @@ static inline int script_browse(const char *script_opt __maybe_unused) #define K_SWITCH_INPUT_DATA -3000 #endif -#ifdef HAVE_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 */ diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index c29ecaabf461..7fd840bf6b62 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -128,6 +128,8 @@ void put_tracing_file(char *file); #endif #endif +#define PERF_GTK_DSO "libperf-gtk.so" + /* General helper functions */ extern void usage(const char *err) NORETURN; extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); From 963ba5fd5d04f36d6a5c9a94562484a4f270c1de Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:25 +0900 Subject: [PATCH 091/161] perf sort: Fix a memory leak on srcline In the hist_entry__srcline_snprintf(), path and self->srcline are pointing the same memory region, but they are doubly allocated. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/sort.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index b4ecc0e4c908..97cf3ef4417c 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -269,10 +269,7 @@ static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, if (!fp) goto out_ip; - if (getline(&path, &line_len, fp) < 0 || !line_len) - goto out_ip; - self->srcline = strdup(path); - if (self->srcline == NULL) + if (getline(&self->srcline, &line_len, fp) < 0 || !line_len) goto out_ip; nl = strchr(self->srcline, '\n'); From 89da393c171926d3372f573d752be5ced98038eb Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:26 +0900 Subject: [PATCH 092/161] perf annotate: Reuse path from the result of addr2line In the symbol__get_source_line(), path and src_line->path will have same value, but they were allocated separately, and leaks one. Just share path to src_line->path. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/annotate.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7eae5488ecea..c6fd1870f278 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1143,11 +1143,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, 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 = path; insert_source_line(&tmp_root, src_line); next_close: From 909b143162de7af310d2a9351220030260ebe728 Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:27 +0900 Subject: [PATCH 093/161] perf hists: Free srcline when freeing hist_entry We've been leaked srcline of hist_entry, it should be freed also. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/hist.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index f3278a388e9a..e6fc38a86e2c 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -535,6 +535,7 @@ void hist_entry__free(struct hist_entry *he) { free(he->branch_info); free(he->mem_info); + free(he->srcline); free(he); } From f048d548f803b57ee1dbf66702f398ba69657450 Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:28 +0900 Subject: [PATCH 094/161] perf annotate: Factor out get/free_srcline() Currently external addr2line tool is used for srcline sort key and annotate with srcline info. Separate the common code to prepare upcoming enhancements. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile.perf | 1 + tools/perf/util/annotate.c | 20 ++------- tools/perf/util/hist.c | 2 +- tools/perf/util/sort.c | 17 ++------ tools/perf/util/srcline.c | 83 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 5 +++ 6 files changed, 96 insertions(+), 32 deletions(-) create mode 100644 tools/perf/util/srcline.c diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 40c39c39ce80..1f1361531f92 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -363,6 +363,7 @@ 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 diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index c6fd1870f278..d48297d77e19 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1070,7 +1070,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; } @@ -1087,7 +1087,6 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, 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 +1114,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,19 +1131,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 = path; + src_line->path = get_srcline(filename, offset); insert_source_line(&tmp_root, src_line); - next_close: - pclose(fp); next: src_line = (void *)src_line + sizeof_src_line; } @@ -1188,7 +1174,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); } diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index e6fc38a86e2c..cca03831f41a 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -535,7 +535,7 @@ void hist_entry__free(struct hist_entry *he) { free(he->branch_info); free(he->mem_info); - free(he->srcline); + free_srcline(he->srcline); free(he); } diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 97cf3ef4417c..b7e0ef0445de 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -251,8 +251,7 @@ static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, unsigned int width __maybe_unused) { FILE *fp = NULL; - char cmd[PATH_MAX + 2], *path = self->srcline, *nl; - size_t line_len; + char *path = self->srcline; if (path != NULL) goto out_path; @@ -263,19 +262,9 @@ static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, if (!strncmp(self->ms.map->dso->long_name, "/tmp/perf-", 10)) goto out_ip; - snprintf(cmd, sizeof(cmd), "addr2line -e %s %016" PRIx64, - self->ms.map->dso->long_name, self->ip); - fp = popen(cmd, "r"); - if (!fp) - goto out_ip; + path = get_srcline(self->ms.map->dso->long_name, self->ip); + self->srcline = path; - if (getline(&self->srcline, &line_len, fp) < 0 || !line_len) - goto out_ip; - - nl = strchr(self->srcline, '\n'); - if (nl != NULL) - *nl = '\0'; - path = self->srcline; out_path: if (fp) pclose(fp); diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c new file mode 100644 index 000000000000..7e92cca6f502 --- /dev/null +++ b/tools/perf/util/srcline.c @@ -0,0 +1,83 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <linux/kernel.h> + +#include "util/util.h" +#include "util/debug.h" + +static int addr2line(const char *dso_name, unsigned long addr, + char **file, unsigned int *line_nr) +{ + FILE *fp; + char cmd[PATH_MAX]; + char *filename = NULL; + size_t len; + char *sep; + int ret = 0; + + scnprintf(cmd, sizeof(cmd), "addr2line -e %s %016"PRIx64, + dso_name, addr); + + fp = popen(cmd, "r"); + if (fp == NULL) { + pr_warning("popen failed for %s\n", dso_name); + return 0; + } + + if (getline(&filename, &len, fp) < 0 || !len) { + pr_warning("addr2line has no output for %s\n", dso_name); + goto out; + } + + sep = strchr(filename, '\n'); + if (sep) + *sep = '\0'; + + if (!strcmp(filename, "??:0")) { + pr_debug("no debugging info in %s\n", dso_name); + free(filename); + goto out; + } + + sep = strchr(filename, ':'); + if (sep) { + *sep++ = '\0'; + *file = filename; + *line_nr = strtoul(sep, NULL, 0); + ret = 1; + } +out: + pclose(fp); + return ret; +} + +char *get_srcline(const char *dso_name, unsigned long addr) +{ + char *file; + unsigned line; + char *srcline; + size_t size; + + if (!addr2line(dso_name, addr, &file, &line)) + return SRCLINE_UNKNOWN; + + /* just calculate actual length */ + size = snprintf(NULL, 0, "%s:%u", file, line) + 1; + + srcline = malloc(size); + if (srcline) + snprintf(srcline, size, "%s:%u", file, line); + else + srcline = SRCLINE_UNKNOWN; + + free(file); + return srcline; +} + +void free_srcline(char *srcline) +{ + if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) + free(srcline); +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 7fd840bf6b62..7c8b43fa8898 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -297,4 +297,9 @@ struct parse_tag { }; unsigned long parse_tag_value(const char *str, struct parse_tag *tags); + +#define SRCLINE_UNKNOWN ((char *) "??:0") + +char *get_srcline(const char *dso_name, unsigned long addr); +void free_srcline(char *srcline); #endif /* GIT_COMPAT_UTIL_H */ From 58d91a0068694a5ba3efc99e88ce6b4b0dd0d085 Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:29 +0900 Subject: [PATCH 095/161] perf tools: Do not try to call addr2line on non-binary files No need to call addr2line since they don't have such information. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-6-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/sort.c | 3 --- tools/perf/util/srcline.c | 11 +++++++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index b7e0ef0445de..d4435939c774 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -259,9 +259,6 @@ static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, if (!self->ms.map) goto out_ip; - if (!strncmp(self->ms.map->dso->long_name, "/tmp/perf-", 10)) - goto out_ip; - path = get_srcline(self->ms.map->dso->long_name, self->ip); self->srcline = path; diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 7e92cca6f502..777f91880cdb 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -57,11 +57,17 @@ char *get_srcline(const char *dso_name, unsigned long addr) { char *file; unsigned line; - char *srcline; + char *srcline = SRCLINE_UNKNOWN; size_t size; + if (dso_name[0] == '[') + goto out; + + if (!strncmp(dso_name, "/tmp/perf-", 10)) + goto out; + if (!addr2line(dso_name, addr, &file, &line)) - return SRCLINE_UNKNOWN; + goto out; /* just calculate actual length */ size = snprintf(NULL, 0, "%s:%u", file, line) + 1; @@ -73,6 +79,7 @@ char *get_srcline(const char *dso_name, unsigned long addr) srcline = SRCLINE_UNKNOWN; free(file); +out: return srcline; } From 86c98cab5a3137376ea7df5ffa5bd52e545fee95 Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:30 +0900 Subject: [PATCH 096/161] perf annotate: Pass dso instead of dso_name to get_srcline() This is a preparation of next change. No functional changes are intended. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-7-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/annotate.c | 11 ++++------- tools/perf/util/dso.h | 1 + tools/perf/util/sort.c | 2 +- tools/perf/util/srcline.c | 4 +++- tools/perf/util/util.h | 4 +++- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index d48297d77e19..d73e8008aada 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1081,8 +1081,7 @@ 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; @@ -1131,7 +1130,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, goto next; offset = start + i; - src_line->path = get_srcline(filename, offset); + src_line->path = get_srcline(map->dso, offset); insert_source_line(&tmp_root, src_line); next: @@ -1338,7 +1337,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; @@ -1348,9 +1346,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, diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index dbd9241ea290..72eedd65fc2d 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -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, diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index d4435939c774..f732120e8bc6 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -259,7 +259,7 @@ static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, if (!self->ms.map) goto out_ip; - path = get_srcline(self->ms.map->dso->long_name, self->ip); + path = get_srcline(self->ms.map->dso, self->ip); self->srcline = path; out_path: diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 777f91880cdb..c736d9428cf2 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -4,6 +4,7 @@ #include <linux/kernel.h> +#include "util/dso.h" #include "util/util.h" #include "util/debug.h" @@ -53,11 +54,12 @@ out: return ret; } -char *get_srcline(const char *dso_name, unsigned long addr) +char *get_srcline(struct dso *dso, unsigned long addr) { char *file; unsigned line; char *srcline = SRCLINE_UNKNOWN; + char *dso_name = dso->long_name; size_t size; if (dso_name[0] == '[') diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 7c8b43fa8898..1f06ba44cd53 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -300,6 +300,8 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags); #define SRCLINE_UNKNOWN ((char *) "??:0") -char *get_srcline(const char *dso_name, unsigned long addr); +struct dso; + +char *get_srcline(struct dso *dso, unsigned long addr); void free_srcline(char *srcline); #endif /* GIT_COMPAT_UTIL_H */ From 2cc9d0ef577975abb3ebce7d5978559ec1c73633 Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:31 +0900 Subject: [PATCH 097/161] perf tools: Save failed result of get_srcline() Some dso's lack srcline info, so there's no point to keep trying on them. Just save failture status and skip them. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-8-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/dso.c | 1 + tools/perf/util/dso.h | 1 + tools/perf/util/srcline.c | 10 ++++++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 6bfc8aacaf7c..af4c687cc49b 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -450,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); diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index 72eedd65fc2d..9ac666abbe7e 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -83,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; diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index c736d9428cf2..dcff10bed7da 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -58,10 +58,13 @@ char *get_srcline(struct dso *dso, unsigned long addr) { char *file; unsigned line; - char *srcline = SRCLINE_UNKNOWN; + char *srcline; char *dso_name = dso->long_name; size_t size; + if (!dso->has_srcline) + return SRCLINE_UNKNOWN; + if (dso_name[0] == '[') goto out; @@ -81,8 +84,11 @@ char *get_srcline(struct dso *dso, unsigned long addr) srcline = SRCLINE_UNKNOWN; free(file); -out: return srcline; + +out: + dso->has_srcline = 0; + return SRCLINE_UNKNOWN; } void free_srcline(char *srcline) From 2f48fcd84e9e68392e29c59204a4a434311d49e9 Mon Sep 17 00:00:00 2001 From: Roberto Vitillo <ravitillo@lbl.gov> Date: Wed, 11 Sep 2013 14:09:32 +0900 Subject: [PATCH 098/161] perf tools: Implement addr2line directly using libbfd When the srcline sort key is used , the external addr2line utility needs to be run for each hist entry to get the srcline info. This can consume quite a time if one has a huge perf.data file. So rather than executing the external utility, implement it internally and just call it. We can do it since we've linked with libbfd already. Signed-off-by: Roberto Agostino Vitillo <ravitillo@lbl.gov> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-9-git-send-email-namhyung@kernel.org [ Use a2l_data struct instead of static globals ] Signed-off-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/Makefile | 4 + tools/perf/util/srcline.c | 167 +++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index d9bba8d57c40..cf6ad5db19dc 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -523,6 +523,10 @@ ifndef NO_LIBNUMA endif endif +ifndef ($(filter -lbfd,$(EXTLIBS)),) + CFLAGS += -DHAVE_LIBBFD_SUPPORT +endif + # Among the variables below, these: # perfexecdir # template_dir diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index dcff10bed7da..37353194e0f6 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -8,6 +8,172 @@ #include "util/util.h" #include "util/debug.h" +#ifdef HAVE_LIBBFD_SUPPORT + +/* + * Implement addr2line using libbfd. + */ +#define PACKAGE "perf" +#include <bfd.h> + +struct a2l_data { + const char *input; + unsigned long addr; + + bool found; + const char *filename; + const char *funcname; + unsigned line; + + bfd *abfd; + asymbol **syms; +}; + +static int bfd_error(const char *string) +{ + const char *errmsg; + + errmsg = bfd_errmsg(bfd_get_error()); + fflush(stdout); + + if (string) + pr_debug("%s: %s\n", string, errmsg); + else + pr_debug("%s\n", errmsg); + + return -1; +} + +static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) +{ + long storage; + long symcount; + asymbol **syms; + bfd_boolean dynamic = FALSE; + + if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) + return bfd_error(bfd_get_filename(abfd)); + + storage = bfd_get_symtab_upper_bound(abfd); + if (storage == 0L) { + storage = bfd_get_dynamic_symtab_upper_bound(abfd); + dynamic = TRUE; + } + if (storage < 0L) + return bfd_error(bfd_get_filename(abfd)); + + syms = malloc(storage); + if (dynamic) + symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); + else + symcount = bfd_canonicalize_symtab(abfd, syms); + + if (symcount < 0) { + free(syms); + return bfd_error(bfd_get_filename(abfd)); + } + + a2l->syms = syms; + return 0; +} + +static void find_address_in_section(bfd *abfd, asection *section, void *data) +{ + bfd_vma pc, vma; + bfd_size_type size; + struct a2l_data *a2l = data; + + if (a2l->found) + return; + + if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) + return; + + pc = a2l->addr; + vma = bfd_get_section_vma(abfd, section); + size = bfd_get_section_size(section); + + if (pc < vma || pc >= vma + size) + return; + + a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, + &a2l->filename, &a2l->funcname, + &a2l->line); +} + +static struct a2l_data *addr2line_init(const char *path) +{ + bfd *abfd; + struct a2l_data *a2l = NULL; + + abfd = bfd_openr(path, NULL); + if (abfd == NULL) + return NULL; + + if (!bfd_check_format(abfd, bfd_object)) + goto out; + + a2l = zalloc(sizeof(*a2l)); + if (a2l == NULL) + goto out; + + a2l->abfd = abfd; + a2l->input = strdup(path); + if (a2l->input == NULL) + goto out; + + if (slurp_symtab(abfd, a2l)) + goto out; + + return a2l; + +out: + if (a2l) { + free((void *)a2l->input); + free(a2l); + } + bfd_close(abfd); + return NULL; +} + +static void addr2line_cleanup(struct a2l_data *a2l) +{ + if (a2l->abfd) + bfd_close(a2l->abfd); + free((void *)a2l->input); + free(a2l->syms); + free(a2l); +} + +static int addr2line(const char *dso_name, unsigned long addr, + char **file, unsigned int *line) +{ + int ret = 0; + struct a2l_data *a2l; + + a2l = addr2line_init(dso_name); + if (a2l == NULL) { + pr_warning("addr2line_init failed for %s\n", dso_name); + return 0; + } + + a2l->addr = addr; + bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); + + if (a2l->found && a2l->filename) { + *file = strdup(a2l->filename); + *line = a2l->line; + + if (*file) + ret = 1; + } + + addr2line_cleanup(a2l); + return ret; +} + +#else /* HAVE_LIBBFD_SUPPORT */ + static int addr2line(const char *dso_name, unsigned long addr, char **file, unsigned int *line_nr) { @@ -53,6 +219,7 @@ out: pclose(fp); return ret; } +#endif /* HAVE_LIBBFD_SUPPORT */ char *get_srcline(struct dso *dso, unsigned long addr) { From 4adcc43003024354b45edadfad4ea2fa205f135f Mon Sep 17 00:00:00 2001 From: Namhyung Kim <namhyung.kim@lge.com> Date: Wed, 11 Sep 2013 14:09:33 +0900 Subject: [PATCH 099/161] perf tools: Fix srcline sort key behavior Currently the srcline sort key compares ip rather than srcline info. I guess this was due to a performance reason to run external addr2line utility. Now we have implemented the functionality inside, use the srcline info when comparing hist entries. Also constantly print "??:0" string for unknown srcline rather than printing ip. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1378876173-13363-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/sort.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index f732120e8bc6..32c56377e008 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -243,33 +243,32 @@ struct sort_entry sort_sym = { static int64_t sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) { - return (int64_t)(right->ip - left->ip); + if (!left->srcline) { + if (!left->ms.map) + left->srcline = SRCLINE_UNKNOWN; + else { + struct map *map = left->ms.map; + left->srcline = get_srcline(map->dso, + map__rip_2objdump(map, left->ip)); + } + } + if (!right->srcline) { + if (!right->ms.map) + right->srcline = SRCLINE_UNKNOWN; + else { + struct map *map = right->ms.map; + right->srcline = get_srcline(map->dso, + map__rip_2objdump(map, right->ip)); + } + } + return strcmp(left->srcline, right->srcline); } static int hist_entry__srcline_snprintf(struct hist_entry *self, char *bf, size_t size, unsigned int width __maybe_unused) { - FILE *fp = NULL; - char *path = self->srcline; - - if (path != NULL) - goto out_path; - - if (!self->ms.map) - goto out_ip; - - path = get_srcline(self->ms.map->dso, self->ip); - self->srcline = path; - -out_path: - if (fp) - pclose(fp); - return repsep_snprintf(bf, size, "%s", path); -out_ip: - if (fp) - pclose(fp); - return repsep_snprintf(bf, size, "%-#*llx", BITS_PER_LONG / 4, self->ip); + return repsep_snprintf(bf, size, "%s", self->srcline); } struct sort_entry sort_srcline = { From eac032c54be48e899a7be2b8db4b746be1b51748 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Fri, 20 Sep 2013 11:27:32 -0300 Subject: [PATCH 100/161] perf trace: Beautify epoll_ctl 'op' arg [root@sandy ~]# perf trace -e epoll_ctl 2.490 (0.003 ms): systemd-logind/586 epoll_ctl(epfd: 10, op: ADD, fd: 24, event: 0x7fff22314ef0) = 0 2.621 (0.003 ms): systemd-logind/586 epoll_ctl(epfd: 10, op: DEL, fd: 24 ) = 0 2.833 (0.010 ms): systemd-logind/586 epoll_ctl(epfd: 10, op: ADD, fd: 24, event: 0x7fff22314cd0) = 0 2.953 (0.002 ms): systemd-logind/586 epoll_ctl(epfd: 10, op: DEL, fd: 24 ) = 0 3.118 (0.002 ms): systemd-logind/586 epoll_ctl(epfd: 10, op: ADD, fd: 24, event: 0x7fff22314d20) = 0 4.762 (0.002 ms): systemd-logind/586 epoll_ctl(epfd: 10, op: DEL, fd: 24 ) = 0 ^C[root@sandy ~]# Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-88xz9phc8cbicnxonud6if8h@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index f3ddbb008fb4..807e542da623 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -232,6 +232,9 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op +static const char *epoll_ctl_ops[] = { [1] = "ADD", "DEL", "MOD", }; +static DEFINE_STRARRAY(epoll_ctl_ops); + static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", }; static DEFINE_STRARRAY(itimers); @@ -543,6 +546,9 @@ static struct syscall_fmt { { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, { .name = "connect", .errmsg = true, }, + { .name = "epoll_ctl", .errmsg = true, + .arg_scnprintf = { [1] = SCA_STRARRAY, /* op */ }, + .arg_parm = { [1] = &strarray__epoll_ctl_ops, /* op */ }, }, { .name = "eventfd2", .errmsg = true, .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, { .name = "fcntl", .errmsg = true, From 5cea6ff265e6979226b751f5ebfdda4594322523 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Fri, 20 Sep 2013 11:49:50 -0300 Subject: [PATCH 101/161] perf trace: Beautify flock 'cmd' arg 4735.638 ( 0.003 ms): man/19881 flock(fd: 3, cmd: SH|NB) = 0 4735.832 ( 0.002 ms): man/19881 flock(fd: 3, cmd: UN ) = 0 Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-amh3y88kh1nmclpwezqlarl8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 807e542da623..2007c8c2c52b 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -189,6 +189,37 @@ static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, #define SCA_MADV_BHV syscall_arg__scnprintf_madvise_behavior +static size_t syscall_arg__scnprintf_flock(char *bf, size_t size, + struct syscall_arg *arg) +{ + int printed = 0, op = arg->val; + + if (op == 0) + return scnprintf(bf, size, "NONE"); +#define P_CMD(cmd) \ + if ((op & LOCK_##cmd) == LOCK_##cmd) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #cmd); \ + op &= ~LOCK_##cmd; \ + } + + P_CMD(SH); + P_CMD(EX); + P_CMD(NB); + P_CMD(UN); + P_CMD(MAND); + P_CMD(RW); + P_CMD(READ); + P_CMD(WRITE); +#undef P_OP + + if (op) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", op); + + return printed; +} + +#define SCA_FLOCK syscall_arg__scnprintf_flock + static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct syscall_arg *arg) { enum syscall_futex_args { @@ -554,6 +585,8 @@ static struct syscall_fmt { { .name = "fcntl", .errmsg = true, .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, + { .name = "flock", .errmsg = true, + .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, }, { .name = "fstat", .errmsg = true, .alias = "newfstat", }, { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, { .name = "futex", .errmsg = true, From 453350dd0f0245b91b1e43310f5966fb1c51e7bd Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Fri, 20 Sep 2013 12:13:37 -0300 Subject: [PATCH 102/161] perf trace: Add helper for syscalls with a single strarray arg In such cases just stating the (arg, name, array) is enough, reducing the size of the syscall formatters table. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-3k53p6dv2sh4ydsc5k5otoia@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 40 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 2007c8c2c52b..8855207deae8 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -562,6 +562,10 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscal #define SCA_SIGNUM syscall_arg__scnprintf_signum +#define STRARRAY(arg, name, array) \ + .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ + .arg_parm = { [arg] = &strarray__##array, } + static struct syscall_fmt { const char *name; const char *alias; @@ -577,33 +581,23 @@ static struct syscall_fmt { { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, { .name = "connect", .errmsg = true, }, - { .name = "epoll_ctl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAY, /* op */ }, - .arg_parm = { [1] = &strarray__epoll_ctl_ops, /* op */ }, }, + { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), }, { .name = "eventfd2", .errmsg = true, .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, - { .name = "fcntl", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAY, /* cmd */ }, - .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, + { .name = "fcntl", .errmsg = true, STRARRAY(1, cmd, fcntl_cmds), }, { .name = "flock", .errmsg = true, .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, }, { .name = "fstat", .errmsg = true, .alias = "newfstat", }, { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, { .name = "futex", .errmsg = true, .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, - { .name = "getitimer", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, - .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, - { .name = "getrlimit", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* resource */ }, - .arg_parm = { [0] = &strarray__rlimit_resources, /* resource */ }, }, + { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, + { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, { .name = "ioctl", .errmsg = true, .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, { .name = "kill", .errmsg = true, .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "lseek", .errmsg = true, - .arg_scnprintf = { [2] = SCA_STRARRAY, /* whence */ }, - .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, + { .name = "lseek", .errmsg = true, STRARRAY(2, whence, whences), }, { .name = "lstat", .errmsg = true, .alias = "newlstat", }, { .name = "madvise", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* start */ @@ -629,9 +623,7 @@ static struct syscall_fmt { { .name = "poll", .errmsg = true, .timeout = true, }, { .name = "ppoll", .errmsg = true, .timeout = true, }, { .name = "pread", .errmsg = true, .alias = "pread64", }, - { .name = "prlimit64", .errmsg = true, - .arg_scnprintf = { [1] = SCA_STRARRAY, /* resource */ }, - .arg_parm = { [1] = &strarray__rlimit_resources, /* resource */ }, }, + { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), }, { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, { .name = "read", .errmsg = true, }, { .name = "recvfrom", .errmsg = true, @@ -642,9 +634,7 @@ static struct syscall_fmt { .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "rt_sigaction", .errmsg = true, .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, - { .name = "rt_sigprocmask", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* how */ }, - .arg_parm = { [0] = &strarray__sighow, /* how */ }, }, + { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), }, { .name = "rt_sigqueueinfo", .errmsg = true, .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, { .name = "rt_tgsigqueueinfo", .errmsg = true, @@ -656,12 +646,8 @@ static struct syscall_fmt { .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "sendto", .errmsg = true, .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, - { .name = "setitimer", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* which */ }, - .arg_parm = { [0] = &strarray__itimers, /* which */ }, }, - { .name = "setrlimit", .errmsg = true, - .arg_scnprintf = { [0] = SCA_STRARRAY, /* resource */ }, - .arg_parm = { [0] = &strarray__rlimit_resources, /* resource */ }, }, + { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, + { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, { .name = "socket", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ [1] = SCA_SK_TYPE, /* type */ }, From 4aa5823225c70efba758750029504807cd30b925 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Fri, 20 Sep 2013 12:19:41 -0300 Subject: [PATCH 103/161] perf trace: Don't supress zeroed args when there is an strarray entry for it Case in hand: 9.682 ( 0.001 ms): Xorg/13079 setitimer(which: REAL, value: 0x7fffede42470) = 0 ITIMER_REAL is zero. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-6hnoqsjh99t4hxi3xu2nlwep@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8855207deae8..27b0ec88cb23 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -940,8 +940,15 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, field = field->next, ++arg.idx, bit <<= 1) { if (arg.mask & bit) continue; - - if (args[arg.idx] == 0) + /* + * Suppress this argument if its value is zero and + * and we don't have a string associated in an + * strarray for it. + */ + if (args[arg.idx] == 0 && + !(sc->arg_scnprintf && + sc->arg_scnprintf[arg.idx] == SCA_STRARRAY && + sc->arg_parm[arg.idx])) continue; printed += scnprintf(bf + printed, size - printed, From 07120aa5d5a241895bcca8b6e5b5b8d7b1df1f2f Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Fri, 20 Sep 2013 12:24:20 -0300 Subject: [PATCH 104/161] perf trace: Use socket's beautifiers in socketpair For the address family and socket type. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-3a6cwwskobvan823pau76cm4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 27b0ec88cb23..bf74217be22c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -652,6 +652,10 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ [1] = SCA_SK_TYPE, /* type */ }, .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, + { .name = "socketpair", .errmsg = true, + .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ + [1] = SCA_SK_TYPE, /* type */ }, + .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, { .name = "tgkill", .errmsg = true, .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, From 46cce19ba8cc8231d3c949c128e4bdaf420228a2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Mon, 23 Sep 2013 12:52:04 -0300 Subject: [PATCH 105/161] perf trace: Beautify pipe2 'flags' arg 4.234 (0.005 ms): fetchmail/3224 pipe2(fildes: 0x7fffc72bcee0, flags: CLOEXEC) = 0 Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-9e1jz78i6q6e0xr9fsitqbpe@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index bf74217be22c..76d9427b4b91 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -517,6 +517,29 @@ static size_t syscall_arg__scnprintf_eventfd_flags(char *bf, size_t size, #define SCA_EFD_FLAGS syscall_arg__scnprintf_eventfd_flags +static size_t syscall_arg__scnprintf_pipe_flags(char *bf, size_t size, + struct syscall_arg *arg) +{ + int printed = 0, flags = arg->val; + +#define P_FLAG(n) \ + if (flags & O_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~O_##n; \ + } + + P_FLAG(CLOEXEC); + P_FLAG(NONBLOCK); +#undef P_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags); + + return printed; +} + +#define SCA_PIPE_FLAGS syscall_arg__scnprintf_pipe_flags + static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscall_arg *arg) { int sig = arg->val; @@ -620,6 +643,8 @@ static struct syscall_fmt { .arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, }, { .name = "openat", .errmsg = true, .arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, }, + { .name = "pipe2", .errmsg = true, + .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, }, { .name = "poll", .errmsg = true, .timeout = true, }, { .name = "ppoll", .errmsg = true, .timeout = true, }, { .name = "pread", .errmsg = true, .alias = "pread64", }, From 4f8c1b74c5fdac35ee4480685d42030446724848 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sun, 22 Sep 2013 19:45:00 -0600 Subject: [PATCH 106/161] perf trace: Add beautifier for clock_gettime's clk_id argument Before: 0.030 ( 0.002 ms): 2571 clock_gettime(which_clock: 1, tp: 0x7f3b45729cd0 ) = 0 After: 0.030 ( 0.002 ms): 2571 clock_gettime(which_clock: MONOTONIC, tp: 0x7f3b45729cd0 ) = 0 v2: Update to use the STRARRAY option Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1379900700-5186-6-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 76d9427b4b91..39a947a0d122 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -297,6 +297,12 @@ static DEFINE_STRARRAY(rlimit_resources); static const char *sighow[] = { "BLOCK", "UNBLOCK", "SETMASK", }; static DEFINE_STRARRAY(sighow); +static const char *clockid[] = { + "REALTIME", "MONOTONIC", "PROCESS_CPUTIME_ID", "THREAD_CPUTIME_ID", + "MONOTONIC_RAW", "REALTIME_COARSE", "MONOTONIC_COARSE", +}; +static DEFINE_STRARRAY(clockid); + static const char *socket_families[] = { "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM", "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI", @@ -603,6 +609,7 @@ static struct syscall_fmt { { .name = "arch_prctl", .errmsg = true, .alias = "prctl", }, { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, + { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, { .name = "connect", .errmsg = true, }, { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), }, { .name = "eventfd2", .errmsg = true, From b6e8f8f4674be5a32f78027ec6e432f5ea33921e Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sun, 22 Sep 2013 19:44:56 -0600 Subject: [PATCH 107/161] perf trace: Handle MSG_WAITFORONE not defined Needed for compiles on Fedora 12 for example. Signed-off-by: David Ahern <dsahern@gmail.com> Link: http://lkml.kernel.org/r/1379900700-5186-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 39a947a0d122..3ca6a856ba62 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -363,6 +363,9 @@ static size_t syscall_arg__scnprintf_socket_type(char *bf, size_t size, #ifndef MSG_PROBE #define MSG_PROBE 0x10 #endif +#ifndef MSG_WAITFORONE +#define MSG_WAITFORONE 0x10000 +#endif #ifndef MSG_SENDPAGE_NOTLAST #define MSG_SENDPAGE_NOTLAST 0x20000 #endif From 3d903aa74a98da2836249bce86aaf557781239c9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 24 Sep 2013 00:09:38 -0300 Subject: [PATCH 108/161] perf trace: Beautify mlock & friends 'addr' arg Printing it as an hex number. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-gd68zmnwbbofsv5m6w18intw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 3ca6a856ba62..12a275d02ada 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -635,6 +635,10 @@ static struct syscall_fmt { { .name = "madvise", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* start */ [2] = SCA_MADV_BHV, /* behavior */ }, }, + { .name = "mlock", .errmsg = true, + .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, + { .name = "mlockall", .errmsg = true, + .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, { .name = "mmap", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ [2] = SCA_MMAP_PROT, /* prot */ @@ -645,6 +649,8 @@ static struct syscall_fmt { { .name = "mremap", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ [4] = SCA_HEX, /* new_addr */ }, }, + { .name = "munlock", .errmsg = true, + .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, { .name = "munmap", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, { .name = "open", .errmsg = true, From 75b757ca90469e990e6901f4a9497fe4161f7f5a Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 24 Sep 2013 11:04:32 -0300 Subject: [PATCH 109/161] perf trace: Show path associated with fd in live sessions For live sessions we can just access /proc to map an fd to its path, on a best effort way, i.e. sometimes the fd will have gone away when we try to do the mapping, as it is done in a lazy way, only when a reference to such fd is made then the path will be looked up in /proc. This is disabled when processing perf.data files, where we will have to have a way to get getname events, be it via an on-the-fly 'perf probe' event or after a vfs_getname tracepoint is added to the kernel. A first step will be to synthesize such event for the use cases where the threads in the monitored workload exist already. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-1r1ti33ye1666jezu2d8q1c3@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 253 ++++++++++++++++++++++++++++++++++--- 1 file changed, 237 insertions(+), 16 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 12a275d02ada..fcc157fce6c6 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -36,6 +36,8 @@ struct syscall_arg { unsigned long val; + struct thread *thread; + struct trace *trace; void *parm; u8 idx; u8 mask; @@ -65,6 +67,29 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, #define SCA_STRARRAY syscall_arg__scnprintf_strarray +static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, + struct syscall_arg *arg); + +#define SCA_FD syscall_arg__scnprintf_fd + +static size_t syscall_arg__scnprintf_fd_at(char *bf, size_t size, + struct syscall_arg *arg) +{ + int fd = arg->val; + + if (fd == AT_FDCWD) + return scnprintf(bf, size, "CWD"); + + return syscall_arg__scnprintf_fd(bf, size, arg); +} + +#define SCA_FDAT syscall_arg__scnprintf_fd_at + +static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, + struct syscall_arg *arg); + +#define SCA_CLOSE_FD syscall_arg__scnprintf_close_fd + static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, struct syscall_arg *arg) { @@ -613,28 +638,84 @@ static struct syscall_fmt { { .name = "brk", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* brk */ }, }, { .name = "clock_gettime", .errmsg = true, STRARRAY(0, clk_id, clockid), }, + { .name = "close", .errmsg = true, + .arg_scnprintf = { [0] = SCA_CLOSE_FD, /* fd */ }, }, { .name = "connect", .errmsg = true, }, + { .name = "dup", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "dup2", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "dup3", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "epoll_ctl", .errmsg = true, STRARRAY(1, op, epoll_ctl_ops), }, { .name = "eventfd2", .errmsg = true, .arg_scnprintf = { [1] = SCA_EFD_FLAGS, /* flags */ }, }, - { .name = "fcntl", .errmsg = true, STRARRAY(1, cmd, fcntl_cmds), }, + { .name = "faccessat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, + { .name = "fadvise64", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fallocate", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fchdir", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fchmod", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fchmodat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, + { .name = "fchown", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fchownat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, + { .name = "fcntl", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ + [1] = SCA_STRARRAY, /* cmd */ }, + .arg_parm = { [1] = &strarray__fcntl_cmds, /* cmd */ }, }, + { .name = "fdatasync", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "flock", .errmsg = true, - .arg_scnprintf = { [1] = SCA_FLOCK, /* cmd */ }, }, - { .name = "fstat", .errmsg = true, .alias = "newfstat", }, - { .name = "fstatat", .errmsg = true, .alias = "newfstatat", }, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ + [1] = SCA_FLOCK, /* cmd */ }, }, + { .name = "fsetxattr", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fstat", .errmsg = true, .alias = "newfstat", + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fstatat", .errmsg = true, .alias = "newfstatat", + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, + { .name = "fstatfs", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "fsync", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "ftruncate", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "futex", .errmsg = true, .arg_scnprintf = { [1] = SCA_FUTEX_OP, /* op */ }, }, + { .name = "futimesat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, + { .name = "getdents", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "getdents64", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "getitimer", .errmsg = true, STRARRAY(0, which, itimers), }, { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, { .name = "ioctl", .errmsg = true, - .arg_scnprintf = { [2] = SCA_HEX, /* arg */ }, }, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ + [2] = SCA_HEX, /* arg */ }, }, { .name = "kill", .errmsg = true, .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, - { .name = "lseek", .errmsg = true, STRARRAY(2, whence, whences), }, + { .name = "linkat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, + { .name = "lseek", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ + [2] = SCA_STRARRAY, /* whence */ }, + .arg_parm = { [2] = &strarray__whences, /* whence */ }, }, { .name = "lstat", .errmsg = true, .alias = "newlstat", }, { .name = "madvise", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* start */ [2] = SCA_MADV_BHV, /* behavior */ }, }, + { .name = "mkdirat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, + { .name = "mknodat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* fd */ }, }, { .name = "mlock", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, { .name = "mlockall", .errmsg = true, @@ -653,26 +734,45 @@ static struct syscall_fmt { .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, { .name = "munmap", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, + { .name = "name_to_handle_at", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, + { .name = "newfstatat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, { .name = "open", .errmsg = true, .arg_scnprintf = { [1] = SCA_OPEN_FLAGS, /* flags */ }, }, { .name = "open_by_handle_at", .errmsg = true, - .arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, }, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ + [2] = SCA_OPEN_FLAGS, /* flags */ }, }, { .name = "openat", .errmsg = true, - .arg_scnprintf = { [2] = SCA_OPEN_FLAGS, /* flags */ }, }, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ + [2] = SCA_OPEN_FLAGS, /* flags */ }, }, { .name = "pipe2", .errmsg = true, .arg_scnprintf = { [1] = SCA_PIPE_FLAGS, /* flags */ }, }, { .name = "poll", .errmsg = true, .timeout = true, }, { .name = "ppoll", .errmsg = true, .timeout = true, }, - { .name = "pread", .errmsg = true, .alias = "pread64", }, + { .name = "pread", .errmsg = true, .alias = "pread64", + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "preadv", .errmsg = true, .alias = "pread", + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "prlimit64", .errmsg = true, STRARRAY(1, resource, rlimit_resources), }, - { .name = "pwrite", .errmsg = true, .alias = "pwrite64", }, - { .name = "read", .errmsg = true, }, + { .name = "pwrite", .errmsg = true, .alias = "pwrite64", + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "pwritev", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "read", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "readlinkat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, + { .name = "readv", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "recvfrom", .errmsg = true, .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "recvmmsg", .errmsg = true, .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "recvmsg", .errmsg = true, .arg_scnprintf = { [2] = SCA_MSG_FLAGS, /* flags */ }, }, + { .name = "renameat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, { .name = "rt_sigaction", .errmsg = true, .arg_scnprintf = { [0] = SCA_SIGNUM, /* sig */ }, }, { .name = "rt_sigprocmask", .errmsg = true, STRARRAY(0, how, sighow), }, @@ -689,6 +789,8 @@ static struct syscall_fmt { .arg_scnprintf = { [3] = SCA_MSG_FLAGS, /* flags */ }, }, { .name = "setitimer", .errmsg = true, STRARRAY(0, which, itimers), }, { .name = "setrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, + { .name = "shutdown", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, { .name = "socket", .errmsg = true, .arg_scnprintf = { [0] = SCA_STRARRAY, /* family */ [1] = SCA_SK_TYPE, /* type */ }, @@ -698,11 +800,21 @@ static struct syscall_fmt { [1] = SCA_SK_TYPE, /* type */ }, .arg_parm = { [0] = &strarray__socket_families, /* family */ }, }, { .name = "stat", .errmsg = true, .alias = "newstat", }, + { .name = "symlinkat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, { .name = "tgkill", .errmsg = true, .arg_scnprintf = { [2] = SCA_SIGNUM, /* sig */ }, }, { .name = "tkill", .errmsg = true, .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, { .name = "uname", .errmsg = true, .alias = "newuname", }, + { .name = "unlinkat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dfd */ }, }, + { .name = "utimensat", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FDAT, /* dirfd */ }, }, + { .name = "write", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, + { .name = "writev", .errmsg = true, + .arg_scnprintf = { [0] = SCA_FD, /* fd */ }, }, }; static int syscall_fmt__cmp(const void *name, const void *fmtp) @@ -747,11 +859,20 @@ struct thread_trace { unsigned long nr_events; char *entry_str; double runtime_ms; + struct { + int max; + char **table; + } paths; }; static struct thread_trace *thread_trace__new(void) { - return zalloc(sizeof(struct thread_trace)); + struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); + + if (ttrace) + ttrace->paths.max = -1; + + return ttrace; } static struct thread_trace *thread__trace(struct thread *thread, FILE *fp) @@ -792,6 +913,7 @@ struct trace { unsigned long nr_events; struct strlist *ev_qualifier; bool not_ev_qualifier; + bool live; struct intlist *tid_list; struct intlist *pid_list; bool sched; @@ -801,6 +923,98 @@ struct trace { double runtime_ms; }; +static int thread__read_fd_path(struct thread *thread, int fd) +{ + struct thread_trace *ttrace = thread->priv; + char linkname[PATH_MAX], pathname[PATH_MAX]; + struct stat st; + int ret; + + if (thread->pid_ == thread->tid) { + scnprintf(linkname, sizeof(linkname), + "/proc/%d/fd/%d", thread->pid_, fd); + } else { + scnprintf(linkname, sizeof(linkname), + "/proc/%d/task/%d/fd/%d", thread->pid_, thread->tid, fd); + } + + if (lstat(linkname, &st) < 0 || st.st_size + 1 > (off_t)sizeof(pathname)) + return -1; + + ret = readlink(linkname, pathname, sizeof(pathname)); + + if (ret < 0 || ret > st.st_size) + return -1; + + pathname[ret] = '\0'; + + if (fd > ttrace->paths.max) { + char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); + + if (npath == NULL) + return -1; + + if (ttrace->paths.max != -1) { + memset(npath + ttrace->paths.max + 1, 0, + (fd - ttrace->paths.max) * sizeof(char *)); + } else { + memset(npath, 0, (fd + 1) * sizeof(char *)); + } + + ttrace->paths.table = npath; + ttrace->paths.max = fd; + } + + ttrace->paths.table[fd] = strdup(pathname); + + return ttrace->paths.table[fd] != NULL ? 0 : -1; +} + +static const char *thread__fd_path(struct thread *thread, int fd, bool live) +{ + struct thread_trace *ttrace = thread->priv; + + if (ttrace == NULL) + return NULL; + + if (fd < 0) + return NULL; + + if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL) && + (!live || thread__read_fd_path(thread, fd))) + return NULL; + + return ttrace->paths.table[fd]; +} + +static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, + struct syscall_arg *arg) +{ + int fd = arg->val; + size_t printed = scnprintf(bf, size, "%d", fd); + const char *path = thread__fd_path(arg->thread, fd, arg->trace->live); + + if (path) + printed += scnprintf(bf + printed, size - printed, "<%s>", path); + + return printed; +} + +static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, + struct syscall_arg *arg) +{ + int fd = arg->val; + size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); + struct thread_trace *ttrace = arg->thread->priv; + + if (ttrace && fd >= 0 && fd <= ttrace->paths.max) { + free(ttrace->paths.table[fd]); + ttrace->paths.table[fd] = NULL; + } + + return printed; +} + static bool trace__filter_duration(struct trace *trace, double t) { return t < (trace->duration_filter * NSEC_PER_MSEC); @@ -969,7 +1183,8 @@ static int trace__read_syscall_info(struct trace *trace, int id) } static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, - unsigned long *args) + unsigned long *args, struct trace *trace, + struct thread *thread) { size_t printed = 0; @@ -977,8 +1192,10 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, struct format_field *field; u8 bit = 1; struct syscall_arg arg = { - .idx = 0, - .mask = 0, + .idx = 0, + .mask = 0, + .trace = trace, + .thread = thread, }; for (field = sc->tp_format->format.fields->next; field; @@ -1111,7 +1328,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, msg = ttrace->entry_str; printed += scnprintf(msg + printed, 1024 - printed, "%s(", sc->name); - printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, args); + printed += syscall__scnprintf_args(sc, msg + printed, 1024 - printed, + args, trace, thread); if (!strcmp(sc->name, "exit_group") || !strcmp(sc->name, "exit")) { if (!trace->duration_filter) { @@ -1292,6 +1510,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) unsigned long before; const bool forks = argc > 0; + trace->live = true; + if (evlist == NULL) { fprintf(trace->output, "Not enough memory to run!\n"); goto out; @@ -1423,6 +1643,7 @@ out_delete_maps: out_delete_evlist: perf_evlist__delete(evlist); out: + trace->live = false; return err; } From b52bc23414124b0d37fd9933b5a894d9b4a9720d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 24 Sep 2013 11:56:36 -0300 Subject: [PATCH 110/161] perf trace: Add 'trace' alias to 'perf trace' Make 'perf trace' more accessible by aliasing it to just 'trace': [root@zoo linux]# trace --duration 15 -a -e futex sleep 1 110.092 (16.188 ms): libvirtd/1166 futex(uaddr: 0x185b344, op: WAIT|PRIV, val: 174293 ) = 0 110.101 (15.903 ms): libvirtd/1171 futex(uaddr: 0x185b3dc, op: WAIT|PRIV, val: 139265 ) = 0 111.594 (15.776 ms): libvirtd/1165 futex(uaddr: 0x185b344, op: WAIT|PRIV, val: 174295 ) = 0 111.610 (15.969 ms): libvirtd/1169 futex(uaddr: 0x185b3dc, op: WAIT|PRIV, val: 139267 ) = 0 113.556 (16.216 ms): libvirtd/1168 futex(uaddr: 0x185b3dc, op: WAIT|PRIV, val: 139269 ) = 0 291.265 (199.508 ms): chromium-brows/15830 futex(uaddr: 0x7fff2986bcb4, op: WAIT_BITSET|PRIV|CLKRT, val: 1, utime: 0x7fff2986bab0, val3: 4294967295) = -1 ETIMEDOUT Connection timed out 360.354 (69.053 ms): chromium-brows/15830 futex(uaddr: 0x7fff2986bcb4, op: WAIT_BITSET|PRIV|CLKRT, val: 1, utime: 0x7fff2986bab0, val3: 4294967295) = -1 ETIMEDOUT Connection timed out [root@zoo linux]# I.e. looking for futex calls that take at least 15ms, system wide, during a one second window. Now to get callchains into 'trace' to figure out what are those locks :-) Requested-by: Ingo Molnar <mingo@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-ch4smqz8b5fmgrte7c5e4fuw@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile.perf | 2 ++ tools/perf/perf.c | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 1f1361531f92..2badb08a0037 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -78,6 +78,7 @@ CC = $(CROSS_COMPILE)gcc AR = $(CROSS_COMPILE)ar RM = rm -f +LN = ln -f MKDIR = mkdir FIND = find INSTALL = install @@ -809,6 +810,7 @@ install-gtk: install-bin: all install-gtk $(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' $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' ifndef NO_LIBPERL diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 626577830264..8b38b4e80ec2 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -481,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--; From a9faa0cab619fad380c2669825aa84212943d528 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Mon, 23 Sep 2013 10:17:35 +0200 Subject: [PATCH 111/161] perf bench sched: Add --threaded option Allow the measurement of thread versus process context switch performance. The default stays at 'process' based measurement, like lmbench's lat_ctx benchmark. Sample output: comet:~/tip/tools/perf> taskset 1 ./perf bench sched pipe # Running sched/pipe benchmark... # Executed 1000000 pipe operations between two processes Total time: 4.138 [sec] 4.138729 usecs/op 241620 ops/sec comet:~/tip/tools/perf> taskset 1 ./perf bench sched pipe --threaded # Running sched/pipe benchmark... # Executed 1000000 pipe operations between two threads Total time: 3.667 [sec] 3.667667 usecs/op 272652 ops/sec Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Arnaldo Carvalho de Melo <acme@infradead.org> Link: http://lkml.kernel.org/r/20130917114256.GA31159@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bench/sched-pipe.c | 115 +++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 29 deletions(-) diff --git a/tools/perf/bench/sched-pipe.c b/tools/perf/bench/sched-pipe.c index 69cfba8d4c6c..07a8d7646a15 100644 --- a/tools/perf/bench/sched-pipe.c +++ b/tools/perf/bench/sched-pipe.c @@ -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; From f4be904d2fa7c65e230ed4b1008ebdf5f4053ac3 Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Sun, 22 Sep 2013 13:22:09 +0300 Subject: [PATCH 112/161] perf machine: Use snprintf instead of sprintf To avoid buffer overruns. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1379845338-29637-2-git-send-email-adrian.hunter@intel.com [ Split from aa7fe3b ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/machine.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 6188d2876a71..ddf917b787fa 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -785,10 +785,10 @@ static int machine__create_modules(struct machine *machine) 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; } From e2137086be7bc52893a790292635cfafc475b693 Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Thu, 26 Sep 2013 20:55:54 +0200 Subject: [PATCH 113/161] perf tools: Add missing -ldl for gtk build If we build perf with NO_LIBPYTHON=1 NO_LIBPERL=1 the '-ldl' is not added to libs build fails if we have gtk2 code in, because it depends on it. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Andi Kleen <ak@linux.intel.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1380221754-29865-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index cf6ad5db19dc..29ad7d6c5311 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -382,6 +382,7 @@ ifndef NO_GTK2 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 From 820042233bd3c1b24b5ca4c75a88a4e0de39814a Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Fri, 27 Sep 2013 18:29:58 +0200 Subject: [PATCH 114/161] perf tools: Move start conditions to start of the flex file Moving start conditions to start of the flex file so it's clear what the INITIAL condition rules are. Plus adding default rule for INITIAL condition. This prevents default space to be printed for events like: $ ./perf stat -e "cycles " kill 2>/dev/null $ ^^^^^^^^ Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1380299398-10839-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/parse-events.l | 63 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l index 91346b753960..343299575b30 100644 --- a/tools/perf/util/parse-events.l +++ b/tools/perf/util/parse-events.l @@ -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); } -} +. { } %% From c458fe62ca31496664c1211a7906d261220b18f9 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Mon, 30 Sep 2013 16:43:05 +0530 Subject: [PATCH 115/161] perf stat: Don't print bogus data on -e cycles When only the cycles event is requested: $ perf stat -e cycles dd if=/dev/zero of=/dev/null count=1000000 1000000+0 records in 1000000+0 records out 512000000 bytes (512 MB) copied, 0.26123 s, 2.0 GB/s Performance counter stats for 'dd if=/dev/zero of=/dev/null count=1000000': 911,626,453 cycles # 0.000 GHz 0.262113350 seconds time elapsed The 0.000 GHz comment in the output is totally bogus and misleading. It happens because update_shadow_stats() doesn't touch runtime_nsecs_stats; it is only written when a requested counter matches a SW_TASK_CLOCK. In our case, since we have only requested HW_CPU_CYCLES, runtime_nsecs_stats is unavailable. So, omit printing the comment altogether. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1380539585-23859-3-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-stat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 700b47849101..ce2266c5cd52 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -997,10 +997,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]); From 3e7a081796146f97f166d77a655c0eb585065077 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Tue, 1 Oct 2013 14:06:44 +0530 Subject: [PATCH 116/161] perf stat: Don't print bogus data on -e instructions When only the instructions event is requested: $ perf stat -e instructions git s M builtin-stat.c Performance counter stats for 'git s': 917,453,420 instructions # 0.00 insns per cycle 0.213002926 seconds time elapsed The 0.00 insns per cycle comment in the output is totally bogus and misleading. It happens because update_shadow_stats() doesn't touch runtime_cycles_stats when only the instructions event is requested. So, omit printing the bogus data altogether. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1380616604-4077-1-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-stat.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index ce2266c5cd52..fb02b53b0e3d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -930,11 +930,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])); From f3c236b0c7a84e5d59cc639a1673a20b0a59ecc0 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 3 Oct 2013 14:10:36 +0530 Subject: [PATCH 117/161] perf tools: Ignore 'perf timechart' output file The default output file produced by the 'perf timechart' tool is called output.svg, add it to .gitignore. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Link: http://lkml.kernel.org/r/1380789636-4512-1-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 8f8fbc227a46..782d86e961b9 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -13,6 +13,7 @@ perf*.html common-cmds.h perf.data perf.data.old +output.svg perf-archive tags TAGS From b81a48ea877e1a104dace1392d92f708ff208f97 Mon Sep 17 00:00:00 2001 From: Petr Holasek <pholasek@redhat.com> Date: Thu, 3 Oct 2013 19:28:45 +0200 Subject: [PATCH 118/161] perf bench: Fix failing assertions in numa bench Patch adds more subtle handling of -C and -N parameters in parse_{cpu,node}_setup_list() functions when there isn't enough NUMA nodes or CPUs present. Instead of assertion and terminating benchmark, partial test is skipped with error message and perf will continue to the next one. Fixed problem can be easily reproduced on machine with only one NUMA node: # Running numa/mem benchmark... # Running main, "perf bench numa mem -a" ... # Running RAM-bw-remote, "perf bench numa mem -p 1 -t 1 -P 1024 -C 0 -M 1 -s perf: bench/numa.c:622: parse_setup_node_list: Assertion `!(bind_node_0 < 0 || bind_node_0 >= g->p.nr_nodes)' failed. Aborted Signed-off-by: Petr Holasek <pholasek@redhat.com> Acked-by: Ingo Molnar <mingo@kernel.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Petr Benas <pbenas@redhat.com> Link: http://lkml.kernel.org/r/1380821325-4017-1-git-send-email-pholasek@redhat.com Signed-off-by: Petr Benas <pbenas@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/bench/numa.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index 30d1c3225b46..64fa01cfc34d 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -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 @@ out: 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 @@ out: 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"); From a65cb4b9f8a777a715371c63c0525408048cea3e Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Wed, 2 Oct 2013 15:46:39 +0200 Subject: [PATCH 119/161] perf evlist: Fix perf_evlist__mmap_read event overflow The perf_evlist__mmap_read used 'union perf_event' as a placeholder for event crossing the mmap boundary. This is ok for sample shorter than ~PATH_MAX. However we could grow up to the maximum sample size which is 16 bits max. I hit this overflow issue when using 'perf top -G dwarf' which produces sample with the size around 8192 bytes. We could configure any valid sample size here using: '-G dwarf,size'. Using array with sample max size instead for the event placeholder. Also adding another safe check for the dynamic size of the user stack. TODO: The 'struct perf_mmap' is quite big now, maybe we could use some lazy allocation for event_copy size. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: David Ahern <dsahern@gmail.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1380721599-24285-1-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/event.h | 3 +++ tools/perf/util/evlist.c | 4 ++-- tools/perf/util/evlist.h | 2 +- tools/perf/util/evsel.c | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 9b7d4d333111..752709ccfb00 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -75,6 +75,9 @@ struct throttle_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[]; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index f0d71a9d49f4..cb9523f50a37 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -540,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); @@ -550,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; diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 871b55ab5dee..722618f84c53 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -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 { diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index abe69af58b62..bfebc1ea3c51 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -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; } } From 62d3b617c02785a4f1fbde8d93ca77a0b33d8454 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 14:27:58 -0600 Subject: [PATCH 120/161] perf stat: Fix misleading message when specifying cpu list or system wide The "perf stat" tool displays the command run in its summary output which is misleading when using a cpu list or system wide collection. Before: perf stat -a -- sleep 1 Performance counter stats for 'sleep 1': 16152.670249 task-clock # 16.132 CPUs utilized 417 context-switches # 0.002 M/sec 7 cpu-migrations # 0.030 K/sec ... After: perf stat -a -- sleep 1 Performance counter stats for 'system wide': 16206.931120 task-clock # 16.144 CPUs utilized 395 context-switches # 0.002 M/sec 5 cpu-migrations # 0.030 K/sec ... or perf stat -C1 -- sleep 1 Performance counter stats for 'CPU(s) 1': 1001.669257 task-clock # 1.000 CPUs utilized 4,264 context-switches # 0.004 M/sec 3 cpu-migrations # 0.003 K/sec ... Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380400080-9211-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-stat.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index fb02b53b0e3d..c8a2662eb57a 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1229,7 +1229,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]); From ac3063bd4725689f39d7a23fdfca2e034c73dcac Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Mon, 30 Sep 2013 07:37:37 -0600 Subject: [PATCH 121/161] perf stat: Don't require a workload when using system wide or CPU options The "perf stat" command can do system wide counters or one or more cpus. For these options do not require a workload to be specified. v2: use perf_target__none per Namhyung's comment. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/52497F3C.9070908@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-stat.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index c8a2662eb57a..2178e6636f71 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1659,8 +1659,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) { From 4bbe5a61f29b13437a6a16467328d3bae8fce9e7 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 14:28:00 -0600 Subject: [PATCH 122/161] perf stat: Add units to nanosec-based counters Ingo pointed out that the task-clock counter should have the units explicitly stated since it is not a counter. Before: perf stat -a -- sleep 1 Performance counter stats for 'sleep 1': 16186.874834 task-clock # 16.154 CPUs utilized ... After: perf stat -a -- sleep 1 Performance counter stats for 'system wide': 16146.402138 task-clock (msec) # 16.125 CPUs utilized ... Reported-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380400080-9211-4-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-stat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2178e6636f71..1a9c95d270aa 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -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); From 8fb598e5a3b0ac213012e8461a309843ba0f2e74 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 13:13:00 -0600 Subject: [PATCH 123/161] perf trace: Fix comm resolution when reading events from file Task comm's are getting lost when processing events from a file. The problem is that the trace struct used by the live processing has its host machine and the perf-session used for file based processing has its host machine. Fix by having both references point to the same machine. Before: 0.030 ( 0.001 ms): :27743/27743 brk( ... 0.057 ( 0.004 ms): :27743/27743 mmap(len: 4096, prot: READ|WRITE, flags: ... 0.075 ( 0.006 ms): :27743/27743 access(filename: 0x7f3809fbce00, mode: R ... 0.091 ( 0.005 ms): :27743/27743 open(filename: 0x7f3809fba14c, flags: CLOEXEC ... ... After: 0.030 ( 0.001 ms): make/27743 brk( ... 0.057 ( 0.004 ms): make/27743 mmap(len: 4096, prot: READ|WRITE, flags: ... 0.075 ( 0.006 ms): make/27743 access(filename: 0x7f3809fbce00, mode: R ... 0.091 ( 0.005 ms): make/27743 open(filename: 0x7f3809fba14c, flags: CLOEXEC ... ... Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380395584-9025-4-git-send-email-dsahern@gmail.com [ Moved creation of new host machine to a separate constructor: machine__new_host() ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 25 +++++++++++++------------ tools/perf/util/machine.c | 17 +++++++++++++++++ tools/perf/util/machine.h | 1 + 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index fcc157fce6c6..5776b5f829e1 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -906,7 +906,7 @@ struct trace { struct syscall *table; } syscalls; struct perf_record_opts opts; - struct machine host; + struct machine *host; u64 base_time; bool full_time; FILE *output; @@ -1083,16 +1083,17 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) if (err) return err; - machine__init(&trace->host, "", HOST_KERNEL_ID); - machine__create_kernel_maps(&trace->host); + trace->host = machine__new_host(); + if (trace->host == NULL) + return -ENOMEM; if (perf_target__has_task(&trace->opts.target)) { err = perf_event__synthesize_thread_map(&trace->tool, evlist->threads, trace__tool_process, - &trace->host); + trace->host); } else { err = perf_event__synthesize_threads(&trace->tool, trace__tool_process, - &trace->host); + trace->host); } if (err) @@ -1304,8 +1305,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, if (sc->filtered) return 0; - thread = machine__findnew_thread(&trace->host, sample->pid, - sample->tid); + thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); ttrace = thread__trace(thread, trace->output); if (ttrace == NULL) return -1; @@ -1357,8 +1357,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, if (sc->filtered) return 0; - thread = machine__findnew_thread(&trace->host, sample->pid, - sample->tid); + thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); ttrace = thread__trace(thread, trace->output); if (ttrace == NULL) return -1; @@ -1414,7 +1413,7 @@ static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evs { u64 runtime = perf_evsel__intval(evsel, sample, "runtime"); double runtime_ms = (double)runtime / NSEC_PER_MSEC; - struct thread *thread = machine__findnew_thread(&trace->host, + struct thread *thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); struct thread_trace *ttrace = thread__trace(thread, trace->output); @@ -1597,7 +1596,7 @@ again: trace->base_time = sample.time; if (type != PERF_RECORD_SAMPLE) { - trace__process_event(trace, &trace->host, event); + trace__process_event(trace, trace->host, event); continue; } @@ -1681,6 +1680,8 @@ static int trace__replay(struct trace *trace) if (session == NULL) return -ENOMEM; + trace->host = &session->machines.host; + err = perf_session__set_tracepoints_handlers(session, handlers); if (err) goto out; @@ -1728,7 +1729,7 @@ static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp) size_t printed = trace__fprintf_threads_header(fp); struct rb_node *nd; - for (nd = rb_first(&trace->host.threads); nd; nd = rb_next(nd)) { + for (nd = rb_first(&trace->host->threads); nd; nd = rb_next(nd)) { struct thread *thread = rb_entry(nd, struct thread, rb_node); struct thread_trace *ttrace = thread->priv; const char *color; diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index ddf917b787fa..fc14f9bf82c8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -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; diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 58a6be1fc739..5150d5e1db67 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -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); From 5e2485b1a2813faa6b80007c653f8bbbed9457ee Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 13:13:01 -0600 Subject: [PATCH 124/161] perf trace: Add record option The record option is a convience alias to include the -e raw_syscalls:* argument to perf-record. All other options are passed to perf-record's handler. Resulting data file can be analyzed by perf-trace -i. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380395584-9025-5-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-trace.txt | 12 +++++++--- tools/perf/builtin-trace.c | 32 +++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 7f70d3640edd..1a224862118f 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -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 ------- diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5776b5f829e1..1e2368f56a74 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1501,6 +1501,33 @@ static int parse_target_str(struct trace *trace) return 0; } +static int trace__record(int argc, const char **argv) +{ + unsigned int rec_argc, i, j; + const char **rec_argv; + const char * const record_args[] = { + "record", + "-R", + "-m", "1024", + "-c", "1", + "-e", "raw_syscalls:sys_enter,raw_syscalls:sys_exit", + }; + + rec_argc = ARRAY_SIZE(record_args) + argc; + rec_argv = calloc(rec_argc + 1, sizeof(char *)); + + if (rec_argv == NULL) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(record_args); i++) + rec_argv[i] = record_args[i]; + + for (j = 0; j < (unsigned int)argc; j++, i++) + rec_argv[i] = argv[j]; + + return cmd_record(i, rec_argv, NULL); +} + static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = perf_evlist__new(); @@ -1788,6 +1815,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) const char * const trace_usage[] = { "perf trace [<options>] [<command>]", "perf trace [<options>] -- <command> [<options>]", + "perf trace record [<options>] [<command>]", + "perf trace record [<options>] -- <command> [<options>]", NULL }; struct trace trace = { @@ -1844,6 +1873,9 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) int err; char bf[BUFSIZ]; + if ((argc > 1) && (strcmp(argv[1], "record") == 0)) + return trace__record(argc-2, &argv[2]); + argc = parse_options(argc, argv, trace_options, trace_usage, 0); if (output_name != NULL) { From 35feee19f9fda7447f51073b5be3f6d082b508f5 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 13:12:58 -0600 Subject: [PATCH 125/161] perf machine: Add method to loop over threads and invoke handler Loop over all threads within a machine - including threads moved to the dead threads list -- and invoked a function. This allows commands to run some specific function on each thread (eg., dump statistics) yet hides how the threads are maintained within the machine. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380395584-9025-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/machine.c | 23 +++++++++++++++++++++++ tools/perf/util/machine.h | 4 ++++ 2 files changed, 27 insertions(+) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index fc14f9bf82c8..901397ae82be 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -1393,3 +1393,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; +} diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index 5150d5e1db67..d44c09bdc45e 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -166,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 */ From 896cbb56bfee6ad99e0ee1b8209dc678f1a49f5a Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 13:12:59 -0600 Subject: [PATCH 126/161] perf trace: Use new machine method to loop over threads Use the new machine method that loops over threads to dump summary data. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380395584-9025-3-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 74 ++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 1e2368f56a74..addc3e11f999 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1751,37 +1751,57 @@ static size_t trace__fprintf_threads_header(FILE *fp) return printed; } +/* struct used to pass data to per-thread function */ +struct summary_data { + FILE *fp; + struct trace *trace; + size_t printed; +}; + +static int trace__fprintf_one_thread(struct thread *thread, void *priv) +{ + struct summary_data *data = priv; + FILE *fp = data->fp; + size_t printed = data->printed; + struct trace *trace = data->trace; + struct thread_trace *ttrace = thread->priv; + const char *color; + double ratio; + + if (ttrace == NULL) + return 0; + + ratio = (double)ttrace->nr_events / trace->nr_events * 100.0; + + color = PERF_COLOR_NORMAL; + if (ratio > 50.0) + color = PERF_COLOR_RED; + else if (ratio > 25.0) + color = PERF_COLOR_GREEN; + else if (ratio > 5.0) + color = PERF_COLOR_YELLOW; + + printed += color_fprintf(fp, color, "%20s", thread->comm); + printed += fprintf(fp, " - %-5d :%11lu [", thread->tid, ttrace->nr_events); + printed += color_fprintf(fp, color, "%5.1f%%", ratio); + printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms); + + data->printed += printed; + + return 0; +} + static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp) { - size_t printed = trace__fprintf_threads_header(fp); - struct rb_node *nd; + struct summary_data data = { + .fp = fp, + .trace = trace + }; + data.printed = trace__fprintf_threads_header(fp); - for (nd = rb_first(&trace->host->threads); nd; nd = rb_next(nd)) { - struct thread *thread = rb_entry(nd, struct thread, rb_node); - struct thread_trace *ttrace = thread->priv; - const char *color; - double ratio; + machine__for_each_thread(trace->host, trace__fprintf_one_thread, &data); - if (ttrace == NULL) - continue; - - ratio = (double)ttrace->nr_events / trace->nr_events * 100.0; - - color = PERF_COLOR_NORMAL; - if (ratio > 50.0) - color = PERF_COLOR_RED; - else if (ratio > 25.0) - color = PERF_COLOR_GREEN; - else if (ratio > 5.0) - color = PERF_COLOR_YELLOW; - - printed += color_fprintf(fp, color, "%20s", thread->comm); - printed += fprintf(fp, " - %-5d :%11lu [", thread->tid, ttrace->nr_events); - printed += color_fprintf(fp, color, "%5.1f%%", ratio); - printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms); - } - - return printed; + return data.printed; } static int trace__set_duration(const struct option *opt, const char *str, From 2969b12993ca7a8b9692048431e075a67815002d Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Sat, 28 Sep 2013 13:13:02 -0600 Subject: [PATCH 127/161] perf intlist: Add priv member Allows commands to leverage intlist infrastructure for opaque structures. For example an upcoming perf-trace change will use this as a means of tracking syscalls statistics by task. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1380395584-9025-6-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/intlist.c | 1 + tools/perf/util/intlist.h | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c index 11a8d86f7fea..826d7b38c9a0 100644 --- a/tools/perf/util/intlist.c +++ b/tools/perf/util/intlist.c @@ -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; } diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h index 62351dad848f..0eb00ac39e01 100644 --- a/tools/perf/util/intlist.h +++ b/tools/perf/util/intlist.h @@ -9,6 +9,7 @@ struct int_node { struct rb_node rb_node; int i; + void *priv; }; struct intlist { From 316d70d6dbde540b275289563cbddd9f0c903fc6 Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Tue, 8 Oct 2013 11:45:48 +0300 Subject: [PATCH 128/161] perf symbols: Make a separate function to parse /proc/modules Make a separate function to parse /proc/modules so that it can be reused. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381221956-16699-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/machine.c | 67 +++++++++++---------------------------- tools/perf/util/symbol.c | 58 +++++++++++++++++++++++++++++++++ tools/perf/util/symbol.h | 3 ++ 3 files changed, 79 insertions(+), 49 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 901397ae82be..6b861aefd99a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -793,12 +793,22 @@ 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]; @@ -812,56 +822,15 @@ static int machine__create_modules(struct machine *machine) 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) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 48c38791d61b..5fd95135e838 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -500,6 +500,64 @@ out_failure: return -1; } +int modules__parse(const char *filename, void *arg, + int (*process_module)(void *arg, const char *name, + u64 start)) +{ + char *line = NULL; + size_t n; + FILE *file; + int err = 0; + + file = fopen(filename, "r"); + if (file == NULL) + return -1; + + while (1) { + char name[PATH_MAX]; + u64 start; + char *sep; + ssize_t line_len; + + line_len = getline(&line, &n, file); + if (line_len < 0) { + if (feof(file)) + break; + err = -1; + goto out; + } + + if (!line) { + err = -1; + goto out; + } + + 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'; + + scnprintf(name, sizeof(name), "[%s]", line); + + err = process_module(arg, name, start); + if (err) + break; + } +out: + free(line); + fclose(file); + return err; +} + struct process_kallsyms_args { struct map *map; struct dso *dso; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 9b8b213a62c1..2d3eb43ab9f9 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -223,6 +223,9 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size); int kallsyms__parse(const char *filename, void *arg, int (*process_symbol)(void *arg, const char *name, char type, u64 start)); +int modules__parse(const char *filename, void *arg, + int (*process_module)(void *arg, const char *name, + u64 start)); int filename__read_debuglink(const char *filename, char *debuglink, size_t size); From 03e3adc9f4d8b57dc83475c8c4c6e462a78ff709 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 8 Oct 2013 16:00:21 -0300 Subject: [PATCH 129/161] perf trace: Allow specifying index offset in strarrays So that the index passed doesn't have to start at zero, being decremented from an offset specified when declaring the strarray before being used as the real array index. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-k1ce6uqyt4qar9edrj3mevod@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index addc3e11f999..7424298b87e3 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -44,6 +44,7 @@ struct syscall_arg { }; struct strarray { + int offset; int nr_entries; const char **entries; }; @@ -53,14 +54,20 @@ struct strarray { .entries = array, \ } +#define DEFINE_STRARRAY_OFFSET(array, off) struct strarray strarray__##array = { \ + .offset = off, \ + .nr_entries = ARRAY_SIZE(array), \ + .entries = array, \ +} + static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, struct syscall_arg *arg) { - int idx = arg->val; struct strarray *sa = arg->parm; + int idx = arg->val - sa->offset; if (idx < 0 || idx >= sa->nr_entries) - return scnprintf(bf, size, "%d", idx); + return scnprintf(bf, size, "%d", arg->val); return scnprintf(bf, size, "%s", sa->entries[idx]); } @@ -288,8 +295,8 @@ static size_t syscall_arg__scnprintf_futex_op(char *bf, size_t size, struct sysc #define SCA_FUTEX_OP syscall_arg__scnprintf_futex_op -static const char *epoll_ctl_ops[] = { [1] = "ADD", "DEL", "MOD", }; -static DEFINE_STRARRAY(epoll_ctl_ops); +static const char *epoll_ctl_ops[] = { "ADD", "DEL", "MOD", }; +static DEFINE_STRARRAY_OFFSET(epoll_ctl_ops, 1); static const char *itimers[] = { "REAL", "VIRTUAL", "PROF", }; static DEFINE_STRARRAY(itimers); From 975b7c2f40d431da4fdb46dd8b9d90c129eecc12 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 8 Oct 2013 17:17:43 -0300 Subject: [PATCH 130/161] perf trace: Prepare the strarray scnprintf method for reuse Right now when an index passed to that method has no string associated it'll print the index as a decimal number, prepare it so that we can use it to print it in hex as well, for ioctls, for instance. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-nsvy06sqj64qvnkmzvwxsx2v@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 7424298b87e3..0d4af1d7e55c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -60,18 +60,25 @@ struct strarray { .entries = array, \ } -static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, - struct syscall_arg *arg) +static size_t __syscall_arg__scnprintf_strarray(char *bf, size_t size, + const char *intfmt, + struct syscall_arg *arg) { struct strarray *sa = arg->parm; int idx = arg->val - sa->offset; if (idx < 0 || idx >= sa->nr_entries) - return scnprintf(bf, size, "%d", arg->val); + return scnprintf(bf, size, intfmt, arg->val); return scnprintf(bf, size, "%s", sa->entries[idx]); } +static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, + struct syscall_arg *arg) +{ + return __syscall_arg__scnprintf_strarray(bf, size, "%d", arg); +} + #define SCA_STRARRAY syscall_arg__scnprintf_strarray static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, From 78645cf3ed32860a3e83b8e35aa469f5b844a4ba Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Tue, 8 Oct 2013 17:43:20 -0300 Subject: [PATCH 131/161] perf trace: Initial beautifier for ioctl's 'cmd' arg [root@zoo linux]# trace -e ioctl | grep -v "cmd: 0x" | head -10 0.386 ( 0.001 ms): trace/1602 ioctl(fd: 1<pipe:[127057]>, cmd: TCGETS, arg: 0x7fff59fcb4d0 ) = -1 ENOTTY Inappropriate ioctl for device 1459.368 ( 0.002 ms): inotify_reader/10352 ioctl(fd: 18<anon_inode:inotify>, cmd: FIONREAD, arg: 0x7fb835228bcc ) = 0 1463.586 ( 0.002 ms): inotify_reader/10352 ioctl(fd: 18<anon_inode:inotify>, cmd: FIONREAD, arg: 0x7fb835228bcc ) = 0 1463.611 ( 0.002 ms): inotify_reader/10352 ioctl(fd: 18<anon_inode:inotify>, cmd: FIONREAD, arg: 0x7fb835228bcc ) = 0 3740.526 ( 0.002 ms): awk/1612 ioctl(fd: 1<pipe:[128265]>, cmd: TCGETS, arg: 0x7fff4d166b90 ) = -1 ENOTTY Inappropriate ioctl for device 3740.704 ( 0.001 ms): awk/1612 ioctl(fd: 3</proc/meminfo>, cmd: TCGETS, arg: 0x7fff4d1669a0 ) = -1 ENOTTY Inappropriate ioctl for device 3742.550 ( 0.002 ms): ps/1614 ioctl(fd: 1<pipe:[128266]>, cmd: TIOCGWINSZ, arg: 0x7fff591762b0 ) = -1 ENOTTY Inappropriate ioctl for device 3742.555 ( 0.003 ms): ps/1614 ioctl(fd: 2<socket:[19550]>, cmd: TIOCGWINSZ, arg: 0x7fff591762b0 ) = -1 ENOTTY Inappropriate ioctl for device 3742.558 ( 0.002 ms): ps/1614 ioctl(cmd: TIOCGWINSZ, arg: 0x7fff591762b0 ) = -1 ENOTTY Inappropriate ioctl for device 3742.572 ( 0.002 ms): ps/1614 ioctl(fd: 1<pipe:[128266]>, cmd: TCGETS, arg: 0x7fff59176220 ) = -1 ENOTTY Inappropriate ioctl for device [root@zoo linux]# Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-afajwap3mr60dfl4qpdl1pxn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 0d4af1d7e55c..19ddcabc73d2 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -81,6 +81,14 @@ static size_t syscall_arg__scnprintf_strarray(char *bf, size_t size, #define SCA_STRARRAY syscall_arg__scnprintf_strarray +static size_t syscall_arg__scnprintf_strhexarray(char *bf, size_t size, + struct syscall_arg *arg) +{ + return __syscall_arg__scnprintf_strarray(bf, size, "%#x", arg); +} + +#define SCA_STRHEXARRAY syscall_arg__scnprintf_strhexarray + static size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg); @@ -633,6 +641,28 @@ static size_t syscall_arg__scnprintf_signum(char *bf, size_t size, struct syscal #define SCA_SIGNUM syscall_arg__scnprintf_signum +#define TCGETS 0x5401 + +static const char *tioctls[] = { + "TCGETS", "TCSETS", "TCSETSW", "TCSETSF", "TCGETA", "TCSETA", "TCSETAW", + "TCSETAF", "TCSBRK", "TCXONC", "TCFLSH", "TIOCEXCL", "TIOCNXCL", + "TIOCSCTTY", "TIOCGPGRP", "TIOCSPGRP", "TIOCOUTQ", "TIOCSTI", + "TIOCGWINSZ", "TIOCSWINSZ", "TIOCMGET", "TIOCMBIS", "TIOCMBIC", + "TIOCMSET", "TIOCGSOFTCAR", "TIOCSSOFTCAR", "FIONREAD", "TIOCLINUX", + "TIOCCONS", "TIOCGSERIAL", "TIOCSSERIAL", "TIOCPKT", "FIONBIO", + "TIOCNOTTY", "TIOCSETD", "TIOCGETD", "TCSBRKP", [0x27] = "TIOCSBRK", + "TIOCCBRK", "TIOCGSID", "TCGETS2", "TCSETS2", "TCSETSW2", "TCSETSF2", + "TIOCGRS485", "TIOCSRS485", "TIOCGPTN", "TIOCSPTLCK", + "TIOCGDEV||TCGETX", "TCSETX", "TCSETXF", "TCSETXW", "TIOCSIG", + "TIOCVHANGUP", "TIOCGPKT", "TIOCGPTLCK", "TIOCGEXCL", + [0x50] = "FIONCLEX", "FIOCLEX", "FIOASYNC", "TIOCSERCONFIG", + "TIOCSERGWILD", "TIOCSERSWILD", "TIOCGLCKTRMIOS", "TIOCSLCKTRMIOS", + "TIOCSERGSTRUCT", "TIOCSERGETLSR", "TIOCSERGETMULTI", "TIOCSERSETMULTI", + "TIOCMIWAIT", "TIOCGICOUNT", [0x60] = "FIOQSIZE", +}; + +static DEFINE_STRARRAY_OFFSET(tioctls, 0x5401); + #define STRARRAY(arg, name, array) \ .arg_scnprintf = { [arg] = SCA_STRARRAY, }, \ .arg_parm = { [arg] = &strarray__##array, } @@ -713,7 +743,9 @@ static struct syscall_fmt { { .name = "getrlimit", .errmsg = true, STRARRAY(0, resource, rlimit_resources), }, { .name = "ioctl", .errmsg = true, .arg_scnprintf = { [0] = SCA_FD, /* fd */ - [2] = SCA_HEX, /* arg */ }, }, + [1] = SCA_STRHEXARRAY, /* cmd */ + [2] = SCA_HEX, /* arg */ }, + .arg_parm = { [1] = &strarray__tioctls, /* cmd */ }, }, { .name = "kill", .errmsg = true, .arg_scnprintf = { [1] = SCA_SIGNUM, /* sig */ }, }, { .name = "linkat", .errmsg = true, From cee972c0e6940ec75bab2d02f37e96d06ce143eb Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 07:42:56 +0200 Subject: [PATCH 132/161] perf tools: Fix redirection printouts Fix the duplicate util/util printout Arnaldo reported: $ make V=1 O=/tmp/build/perf -C tools/perf/ util/srcline.o ... # Redirected target util/srcline.o => /tmp/build/perf/util/util/srcline.o Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/20131010054256.GA23716@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile.perf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 2badb08a0037..8bc6d0c4e776 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -600,11 +600,11 @@ ifneq ($(OUTPUT),) %.o: $(OUTPUT)%.o @echo " # Redirected target $@ => $(OUTPUT)$@" util/%.o: $(OUTPUT)util/%.o - @echo " # Redirected target $@ => $(OUTPUT)util/$@" + @echo " # Redirected target $@ => $(OUTPUT)$@" bench/%.o: $(OUTPUT)bench/%.o - @echo " # Redirected target $@ => $(OUTPUT)bench/$@" + @echo " # Redirected target $@ => $(OUTPUT)$@" tests/%.o: $(OUTPUT)tests/%.o - @echo " # Redirected target $@ => $(OUTPUT)tests/$@" + @echo " # Redirected target $@ => $(OUTPUT)$@" endif # These two need to be here so that when O= is not used they take precedence From 8ec19c0eba73d7221e93e993c1c8bd62484354e9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 9 Oct 2013 11:49:26 +0200 Subject: [PATCH 133/161] perf tools: Implement summary output for 'make clean' 'make clean' used to show all the rm lines, which isn't really informative in any way and spams the console. Implement summary output: comet:~/tip/tools/perf> make clean CLEAN libtraceevent CLEAN liblk CLEAN config CLEAN core-objs CLEAN core-progs CLEAN core-gen CLEAN Documentation CLEAN python 'make clean V=1' will still show the old, detailed output. Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1381312169-17354-2-git-send-email-mingo@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/Makefile | 18 ++++++++++-------- tools/perf/Makefile.perf | 24 ++++++++++++------------ tools/perf/config/utilities.mak | 6 ++++++ tools/scripts/Makefile.include | 2 +- 4 files changed, 29 insertions(+), 21 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index eaa477f00673..be5adb1e0290 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -246,15 +246,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) $@+ $@ && \ diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 8bc6d0c4e776..250b276c136f 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -148,7 +148,7 @@ 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-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) @@ -708,7 +708,8 @@ $(LIBTRACEEVENT): $(TE_SOURCES) $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) libtraceevent.a $(LIBTRACEEVENT)-clean: - $(QUIET_SUBDIR0)$(TRACE_EVENT_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean + $(call QUIET_CLEAN, libtraceevent) + @$(MAKE) -C $(TRACE_EVENT_DIR) O=$(OUTPUT) clean >/dev/null LIBLK_SOURCES = $(wildcard $(LK_PATH)*.[ch]) @@ -721,7 +722,8 @@ endif $(LIBLK)-clean: ifeq ($(subdir),) - $(QUIET_SUBDIR0)$(LK_DIR) $(QUIET_SUBDIR1) O=$(OUTPUT) clean + $(call QUIET_CLEAN, liblk) + @$(MAKE) -C $(LK_DIR) O=$(OUTPUT) clean >/dev/null endif help: @@ -850,17 +852,15 @@ $(INSTALL_DOC_TARGETS): # not get included for the clean target: # config-clean: - @$(MAKE) -C config/feature-checks clean + $(call QUIET_CLEAN, config) + @$(MAKE) -C config/feature-checks clean >/dev/null clean: $(LIBTRACEEVENT)-clean $(LIBLK)-clean config-clean - $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(GTK_OBJS) - $(RM) $(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* + $(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) # diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index 4d985e0f03f5..94908a5fbea7 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak @@ -178,3 +178,9 @@ endef _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) _gea_warn = $(warning The path '$(1)' is not executable.) _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) + +ifneq ($(findstring $(MAKEFLAGS),s),s) + ifneq ($(V),1) + QUIET_CLEAN = @printf ' CLEAN %s\n' $(1); + endif +endif diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 0d0506d55c71..1853736c8106 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -66,7 +66,7 @@ ifneq ($(V),1) QUIET_MKDIR = @echo ' ' MKDIR $@; QUIET_GEN = @echo ' ' GEN $@; QUIET_SUBDIR0 = +@subdir= - QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ + QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ $(MAKE) $(PRINT_DIR) -C $$subdir QUIET_FLEX = @echo ' ' FLEX $@; QUIET_BISON = @echo ' ' BISON $@; From 65fb09922d4ca5da54fe18d7b44e5961caf169ad Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 9 Oct 2013 11:49:27 +0200 Subject: [PATCH 134/161] tools: Harmonize the various build messages in perf, lib-traceevent, lib-lk The various build lines from libtraceevent and perf mix up during a parallel build and produce unaligned output like: CC builtin-buildid-list.o CC builtin-buildid-cache.o CC builtin-list.o CC FPIC trace-seq.o CC builtin-record.o CC FPIC parse-filter.o CC builtin-report.o CC builtin-stat.o CC FPIC parse-utils.o CC FPIC kbuffer-parse.o CC builtin-timechart.o CC builtin-top.o CC builtin-script.o BUILD STATIC LIB libtraceevent.a CC builtin-probe.o CC builtin-kmem.o CC builtin-lock.o To solve this, harmonize all the build message alignments to be similar to the kernel's kbuild output: prefixed by two spaces and 11-char wide. After the patch the output looks pretty tidy, even if output lines get mixed up: CC builtin-annotate.o FLAGS: * new build flags or cross compiler CC builtin-bench.o AR liblk.a CC bench/sched-messaging.o CC FPIC event-parse.o CC bench/sched-pipe.o CC FPIC trace-seq.o CC bench/mem-memcpy.o CC bench/mem-memset.o CC FPIC parse-filter.o CC builtin-diff.o CC builtin-evlist.o CC builtin-help.o Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1381312169-17354-3-git-send-email-mingo@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/lib/traceevent/Makefile | 18 +++++++++--------- tools/perf/Documentation/Makefile | 17 +++++++++-------- tools/perf/Makefile | 2 +- tools/perf/Makefile.perf | 2 +- tools/scripts/Makefile.include | 23 ++++++++++++----------- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile index ca6cb779876a..fc1502098595 100644 --- a/tools/lib/traceevent/Makefile +++ b/tools/lib/traceevent/Makefile @@ -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 diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index be5adb1e0290..c4c300cf155f 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -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 diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 9580ebe260e0..5aa3d040bbf3 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -38,7 +38,7 @@ ifneq ($(O),) endif define print_msg - @printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n' + @printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n' endef define make diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 250b276c136f..f91bd5a9b50a 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -784,7 +784,7 @@ TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\ $(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 1>&2 " FLAGS: * new build flags or prefix"; \ echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \ fi diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index 1853736c8106..ee76544deecb 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -59,21 +59,22 @@ QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir QUIET_SUBDIR1 = ifneq ($(findstring $(MAKEFLAGS),s),s) -ifneq ($(V),1) - QUIET_CC = @echo ' ' CC $@; - QUIET_AR = @echo ' ' AR $@; - QUIET_LINK = @echo ' ' LINK $@; - QUIET_MKDIR = @echo ' ' MKDIR $@; - QUIET_GEN = @echo ' ' GEN $@; + ifneq ($(V),1) + QUIET_CC = @echo ' CC '$@; + QUIET_AR = @echo ' AR '$@; + QUIET_LINK = @echo ' LINK '$@; + QUIET_MKDIR = @echo ' MKDIR '$@; + QUIET_GEN = @echo ' GEN '$@; QUIET_SUBDIR0 = +@subdir= - QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ + QUIET_SUBDIR1 = ;$(NO_SUBDIR) \ + echo ' SUBDIR '$$subdir; \ $(MAKE) $(PRINT_DIR) -C $$subdir - QUIET_FLEX = @echo ' ' FLEX $@; - QUIET_BISON = @echo ' ' BISON $@; + QUIET_FLEX = @echo ' FLEX '$@; + QUIET_BISON = @echo ' BISON '$@; descend = \ - +@echo ' ' DESCEND $(1); \ + +@echo ' DESCEND '$(1); \ mkdir -p $(OUTPUT)$(1) && \ $(MAKE) $(COMMAND_O) subdir=$(if $(subdir),$(subdir)/$(1),$(1)) $(PRINT_DIR) -C $(1) $(2) -endif + endif endif From 3fae82db558468c01f36eb6398e9459ac240e697 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 9 Oct 2013 11:49:28 +0200 Subject: [PATCH 135/161] perf tools: Align perf version output to other build messages Before: CC util/pmu.o CC util/parse-events.o PERF_VERSION = 3.12.rc4.g1b30c CC util/parse-events-flex.o GEN perf-archive After: CC util/pmu.o CC util/parse-events.o PERF_VERSION = 3.12.rc4.g1b30c CC util/parse-events-flex.o GEN perf-archive Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1381312169-17354-4-git-send-email-mingo@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/PERF-VERSION-GEN | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index 15a77b7c0e36..ce7a804b2951 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN @@ -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 } From 8a5411e9a3e65ab70b094022e5aa6deaec82ae7c Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 9 Oct 2013 11:49:29 +0200 Subject: [PATCH 136/161] perf tools: Implement summary output for 'make install' 'make install' used to show all the install lines, which is way too verbose to be really informative to the user. Implement summary output instead: comet:~/tip/tools/perf> make install BUILD: Doing 'make -j12' parallel build SUBDIR Documentation INSTALL Documentation-man INSTALL binaries INSTALL libexec INSTALL perf-archive INSTALL perl-scripts INSTALL python-scripts INSTALL bash_completion-script INSTALL tests 'make install V=1' will still show the old, detailed output. Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: http://lkml.kernel.org/r/1381312169-17354-5-git-send-email-mingo@kernel.org [ Fixed conflict with libperf-gtk patches in acme/perf/core, cope with 'trace' alias ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/Makefile | 27 +++++++++------- tools/perf/Makefile.perf | 54 ++++++++++++++++++------------- tools/perf/config/utilities.mak | 3 +- 3 files changed, 48 insertions(+), 36 deletions(-) diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile index c4c300cf155f..3ba1c0b09908 100644 --- a/tools/perf/Documentation/Makefile +++ b/tools/perf/Documentation/Makefile @@ -184,12 +184,13 @@ 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 @@ -202,18 +203,20 @@ 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) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index f91bd5a9b50a..c873e039aafb 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -504,8 +504,9 @@ ifndef NO_GTK2 GTK_OBJS += $(OUTPUT)ui/gtk/annotate.o install-gtk: $(OUTPUT)libperf-gtk.so - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)' - $(INSTALL) $(OUTPUT)libperf-gtk.so '$(DESTDIR_SQ)$(libdir_SQ)' + $(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 @@ -810,31 +811,38 @@ check: $(OUTPUT)common-cmds.h install-gtk: install-bin: all install-gtk - $(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' - $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' - $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' + $(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 - $(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' + $(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 - $(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' + $(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 - $(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' + $(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 diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak index 94908a5fbea7..f168debc5be2 100644 --- a/tools/perf/config/utilities.mak +++ b/tools/perf/config/utilities.mak @@ -181,6 +181,7 @@ _gea_err = $(if $(1),$(error Please set '$(1)' appropriately)) ifneq ($(findstring $(MAKEFLAGS),s),s) ifneq ($(V),1) - QUIET_CLEAN = @printf ' CLEAN %s\n' $(1); + QUIET_CLEAN = @printf ' CLEAN %s\n' $1; + QUIET_INSTALL = @printf ' INSTALL %s\n' $1; endif endif From d366c53e1d4fc9d7a5826fd82010b3cffaabe5f1 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Thu, 3 Oct 2013 14:45:16 +0530 Subject: [PATCH 137/161] perf timechart: Add example in the documentation While at it, update the synopsis to show both forms. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Namhyung Kim <namhyung@gmail.com> Link: http://lkml.kernel.org/r/1380791716-10325-1-git-send-email-artagnon@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-timechart.txt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-timechart.txt b/tools/perf/Documentation/perf-timechart.txt index 1632b0efc757..3ff8bd4f0b4d 100644 --- a/tools/perf/Documentation/perf-timechart.txt +++ b/tools/perf/Documentation/perf-timechart.txt @@ -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] From 87f918685a452be514d060a09eeb4e0c91422e86 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra <artagnon@gmail.com> Date: Fri, 4 Oct 2013 10:47:31 +0530 Subject: [PATCH 138/161] perf trace: Improve the error messages Currently, execution of 'perf trace' reports the following cryptic message to the user: $ perf trace Couldn't read the raw_syscalls tracepoints information! Typically this happens because the user does not have permissions to read the debugfs filesystem. Also handle the case when the kernel was not compiled with debugfs support or when it isn't mounted. Now, the tool prints detailed error messages: $ perf trace Error: Unable to find debugfs Hint: Was your kernel was compiled with debugfs support? Hint: Is the debugfs filesystem mounted? Hint: Try 'sudo mount -t debugfs nodev /sys/kernel/debug' $ perf trace Error: No permissions to read /sys/kernel/debug//tracing/events/raw_syscalls Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/' Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Link: http://lkml.kernel.org/r/1380863851-14460-1-git-send-email-artagnon@gmail.com [ Added ready to use commands to fix the issues as extra hints, use the current debugfs mount point when reporting permission error, use strerror_r instead of the deprecated sys_errlist, as reported by David Ahern ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/builtin-trace.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 19ddcabc73d2..5496546b7c5c 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1590,17 +1590,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv) } if (perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_enter", trace__sys_enter) || - perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) { - fprintf(trace->output, "Couldn't read the raw_syscalls tracepoints information!\n"); - goto out_delete_evlist; - } + perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) + goto out_error_tp; if (trace->sched && - perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", - trace__sched_stat_runtime)) { - fprintf(trace->output, "Couldn't read the sched_stat_runtime tracepoint information!\n"); - goto out_delete_evlist; - } + perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", + trace__sched_stat_runtime)) + goto out_error_tp; err = perf_evlist__create_maps(evlist, &trace->opts.target); if (err < 0) { @@ -1717,6 +1713,29 @@ out_delete_evlist: out: trace->live = false; return err; +out_error_tp: + switch(errno) { + case ENOENT: + fputs("Error:\tUnable to find debugfs\n" + "Hint:\tWas your kernel was compiled with debugfs support?\n" + "Hint:\tIs the debugfs filesystem mounted?\n" + "Hint:\tTry 'sudo mount -t debugfs nodev /sys/kernel/debug'\n", + trace->output); + break; + case EACCES: + fprintf(trace->output, + "Error:\tNo permissions to read %s/tracing/events/raw_syscalls\n" + "Hint:\tTry 'sudo mount -o remount,mode=755 %s'\n", + debugfs_mountpoint, debugfs_mountpoint); + break; + default: { + char bf[256]; + fprintf(trace->output, "Can't trace: %s\n", + strerror_r(errno, bf, sizeof(bf))); + } + break; + } + goto out_delete_evlist; } static int trace__replay(struct trace *trace) From 813335b8b27d9ceeb67a073f501ada8b8dde37a7 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Tue, 8 Oct 2013 21:26:52 -0600 Subject: [PATCH 139/161] perf util: Add findnew method to intlist Similar to other findnew based methods if the requested object is not found, add it to the list. v2: followed format of other findnew methods per acme's request Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381289214-24885-2-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/intlist.c | 22 ++++++++++++++++++---- tools/perf/util/intlist.h | 1 + tools/perf/util/rblist.c | 27 ++++++++++++++++++++++++--- tools/perf/util/rblist.h | 1 + 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c index 826d7b38c9a0..89715b64a315 100644 --- a/tools/perf/util/intlist.c +++ b/tools/perf/util/intlist.c @@ -58,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; diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h index 0eb00ac39e01..aa6877d36858 100644 --- a/tools/perf/util/intlist.h +++ b/tools/perf/util/intlist.h @@ -24,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) { diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c index a16cdd2625ad..0dfe27d99458 100644 --- a/tools/perf/util/rblist.c +++ b/tools/perf/util/rblist.c @@ -48,10 +48,12 @@ void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) rblist->node_delete(rblist, rb_node); } -struct rb_node *rblist__find(struct rblist *rblist, const void *entry) +static struct rb_node *__rblist__findnew(struct rblist *rblist, + const void *entry, + bool create) { struct rb_node **p = &rblist->entries.rb_node; - struct rb_node *parent = NULL; + struct rb_node *parent = NULL, *new_node = NULL; while (*p != NULL) { int rc; @@ -67,7 +69,26 @@ struct rb_node *rblist__find(struct rblist *rblist, const void *entry) return parent; } - return NULL; + if (create) { + new_node = rblist->node_new(rblist, entry); + if (new_node) { + rb_link_node(new_node, parent, p); + rb_insert_color(new_node, &rblist->entries); + ++rblist->nr_entries; + } + } + + return new_node; +} + +struct rb_node *rblist__find(struct rblist *rblist, const void *entry) +{ + return __rblist__findnew(rblist, entry, false); +} + +struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry) +{ + return __rblist__findnew(rblist, entry, true); } void rblist__init(struct rblist *rblist) diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h index 6d0cae5ae83d..ff9913b994c2 100644 --- a/tools/perf/util/rblist.h +++ b/tools/perf/util/rblist.h @@ -32,6 +32,7 @@ void rblist__delete(struct rblist *rblist); int rblist__add_node(struct rblist *rblist, const void *new_entry); void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node); struct rb_node *rblist__find(struct rblist *rblist, const void *entry); +struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry); struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx); static inline bool rblist__empty(const struct rblist *rblist) From bf2575c121ca11247ef07fd02b43f7430834f7b1 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Tue, 8 Oct 2013 21:26:53 -0600 Subject: [PATCH 140/161] perf trace: Add summary option to dump syscall statistics When enabled dumps a summary of all syscalls by task with the usual statistics -- min, max, average and relative stddev. For example, make - 26341 : 3344 [ 17.4% ] 0.000 ms read : 52 0.000 4.802 0.644 30.08 write : 20 0.004 0.036 0.010 21.72 open : 24 0.003 0.046 0.014 23.68 close : 64 0.002 0.055 0.008 22.53 stat : 2714 0.002 0.222 0.004 4.47 fstat : 18 0.001 0.041 0.006 46.26 mmap : 30 0.003 0.009 0.006 5.71 mprotect : 8 0.006 0.039 0.016 32.16 munmap : 12 0.007 0.077 0.020 38.25 brk : 48 0.002 0.014 0.004 10.18 rt_sigaction : 18 0.002 0.002 0.002 2.11 rt_sigprocmask : 60 0.002 0.128 0.010 32.88 access : 2 0.006 0.006 0.006 0.00 pipe : 12 0.004 0.048 0.013 35.98 vfork : 34 0.448 0.980 0.692 3.04 execve : 20 0.000 0.387 0.046 56.66 wait4 : 34 0.017 9923.287 593.221 68.45 fcntl : 8 0.001 0.041 0.013 48.79 getdents : 48 0.002 0.079 0.013 19.62 getcwd : 2 0.005 0.005 0.005 0.00 chdir : 2 0.070 0.070 0.070 0.00 getrlimit : 2 0.045 0.045 0.045 0.00 arch_prctl : 2 0.002 0.002 0.002 0.00 setrlimit : 2 0.002 0.002 0.002 0.00 openat : 94 0.003 0.005 0.003 2.11 Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381289214-24885-3-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Documentation/perf-trace.txt | 4 + tools/perf/builtin-trace.c | 110 +++++++++++++++++++++--- 2 files changed, 102 insertions(+), 12 deletions(-) diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt index 1a224862118f..54139c6457f8 100644 --- a/tools/perf/Documentation/perf-trace.txt +++ b/tools/perf/Documentation/perf-trace.txt @@ -93,6 +93,10 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs. --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] diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 5496546b7c5c..d0f91fe755a3 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -10,6 +10,7 @@ #include "util/strlist.h" #include "util/intlist.h" #include "util/thread_map.h" +#include "util/stat.h" #include <libaudit.h> #include <stdlib.h> @@ -909,6 +910,8 @@ struct thread_trace { int max; char **table; } paths; + + struct intlist *syscall_stats; }; static struct thread_trace *thread_trace__new(void) @@ -918,6 +921,8 @@ static struct thread_trace *thread_trace__new(void) if (ttrace) ttrace->paths.max = -1; + ttrace->syscall_stats = intlist__new(NULL); + return ttrace; } @@ -964,6 +969,7 @@ struct trace { struct intlist *pid_list; bool sched; bool multiple_threads; + bool summary; bool show_comm; double duration_filter; double runtime_ms; @@ -1291,10 +1297,8 @@ typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample); static struct syscall *trace__syscall_info(struct trace *trace, - struct perf_evsel *evsel, - struct perf_sample *sample) + struct perf_evsel *evsel, int id) { - int id = perf_evsel__intval(evsel, sample, "id"); if (id < 0) { @@ -1335,6 +1339,32 @@ out_cant_read: return NULL; } +static void thread__update_stats(struct thread_trace *ttrace, + int id, struct perf_sample *sample) +{ + struct int_node *inode; + struct stats *stats; + u64 duration = 0; + + inode = intlist__findnew(ttrace->syscall_stats, id); + if (inode == NULL) + return; + + stats = inode->priv; + if (stats == NULL) { + stats = malloc(sizeof(struct stats)); + if (stats == NULL) + return; + init_stats(stats); + inode->priv = stats; + } + + if (ttrace->entry_time && sample->time > ttrace->entry_time) + duration = sample->time - ttrace->entry_time; + + update_stats(stats, duration); +} + static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, struct perf_sample *sample) { @@ -1342,7 +1372,8 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, void *args; size_t printed = 0; struct thread *thread; - struct syscall *sc = trace__syscall_info(trace, evsel, sample); + int id = perf_evsel__intval(evsel, sample, "id"); + struct syscall *sc = trace__syscall_info(trace, evsel, id); struct thread_trace *ttrace; if (sc == NULL) @@ -1394,7 +1425,8 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, int ret; u64 duration = 0; struct thread *thread; - struct syscall *sc = trace__syscall_info(trace, evsel, sample); + int id = perf_evsel__intval(evsel, sample, "id"); + struct syscall *sc = trace__syscall_info(trace, evsel, id); struct thread_trace *ttrace; if (sc == NULL) @@ -1408,6 +1440,9 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, if (ttrace == NULL) return -1; + if (trace->summary) + thread__update_stats(ttrace, id, sample); + ret = perf_evsel__intval(evsel, sample, "ret"); ttrace = thread->priv; @@ -1574,6 +1609,8 @@ static int trace__record(int argc, const char **argv) return cmd_record(i, rec_argv, NULL); } +static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp); + static int trace__run(struct trace *trace, int argc, const char **argv) { struct perf_evlist *evlist = perf_evlist__new(); @@ -1703,6 +1740,9 @@ again: goto again; out_unmap_evlist: + if (!err && trace->summary) + trace__fprintf_thread_summary(trace, trace->output); + perf_evlist__munmap(evlist); out_close_evlist: perf_evlist__close(evlist); @@ -1798,6 +1838,9 @@ static int trace__replay(struct trace *trace) if (err) pr_err("Failed to process events, error %d", err); + else if (trace->summary) + trace__fprintf_thread_summary(trace, trace->output); + out: perf_session__delete(session); @@ -1808,10 +1851,53 @@ static size_t trace__fprintf_threads_header(FILE *fp) { size_t printed; - printed = fprintf(fp, "\n _____________________________________________________________________\n"); - printed += fprintf(fp," __) Summary of events (__\n\n"); - printed += fprintf(fp," [ task - pid ] [ events ] [ ratio ] [ runtime ]\n"); - printed += fprintf(fp," _____________________________________________________________________\n\n"); + printed = fprintf(fp, "\n _____________________________________________________________________________\n"); + printed += fprintf(fp, " __) Summary of events (__\n\n"); + printed += fprintf(fp, " [ task - pid ] [ events ] [ ratio ] [ runtime ]\n"); + printed += fprintf(fp, " syscall count min max avg stddev\n"); + printed += fprintf(fp, " msec msec msec %%\n"); + printed += fprintf(fp, " _____________________________________________________________________________\n\n"); + + return printed; +} + +static size_t thread__dump_stats(struct thread_trace *ttrace, + struct trace *trace, FILE *fp) +{ + struct stats *stats; + size_t printed = 0; + struct syscall *sc; + struct int_node *inode = intlist__first(ttrace->syscall_stats); + + if (inode == NULL) + return 0; + + printed += fprintf(fp, "\n"); + + /* each int_node is a syscall */ + while (inode) { + stats = inode->priv; + if (stats) { + double min = (double)(stats->min) / NSEC_PER_MSEC; + double max = (double)(stats->max) / NSEC_PER_MSEC; + double avg = avg_stats(stats); + double pct; + u64 n = (u64) stats->n; + + pct = avg ? 100.0 * stddev_stats(stats)/avg : 0.0; + avg /= NSEC_PER_MSEC; + + sc = &trace->syscalls.table[inode->i]; + printed += fprintf(fp, "%24s %14s : ", "", sc->name); + printed += fprintf(fp, "%5" PRIu64 " %8.3f %8.3f", + n, min, max); + printed += fprintf(fp, " %8.3f %6.2f\n", avg, pct); + } + + inode = intlist__next(inode); + } + + printed += fprintf(fp, "\n\n"); return printed; } @@ -1850,6 +1936,7 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv) printed += fprintf(fp, " - %-5d :%11lu [", thread->tid, ttrace->nr_events); printed += color_fprintf(fp, color, "%5.1f%%", ratio); printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms); + printed += thread__dump_stats(ttrace, trace, fp); data->printed += printed; @@ -1953,6 +2040,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) OPT_INCR('v', "verbose", &verbose, "be more verbose"), OPT_BOOLEAN('T', "time", &trace.full_time, "Show full timestamp, not time relative to first start"), + OPT_BOOLEAN(0, "summary", &trace.summary, + "Show syscall summary with statistics"), OPT_END() }; int err; @@ -2008,9 +2097,6 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused) else err = trace__run(&trace, argc, argv); - if (trace.sched && !err) - trace__fprintf_thread_summary(&trace, trace.output); - out_close: if (output_name != NULL) fclose(trace.output); From a949fffb84df6f9be136198a00f796a9dc696bd0 Mon Sep 17 00:00:00 2001 From: David Ahern <dsahern@gmail.com> Date: Wed, 9 Oct 2013 21:51:31 -0600 Subject: [PATCH 141/161] perf tools: Fix old GCC build error in 'get_srcline' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit trace-event-parse.c:parse_proc_kallsyms() Old GCC (4.4.2) does not see through the code flow of get_srcline() and gets confused about the status of 'file' and 'line': CC /tmp/build/perf/util/srcline.o cc1: warnings being treated as errors util/srcline.c: In function ¿get_srcline¿: util/srcline.c:226: error: ¿file¿ may be used uninitialized in this function util/srcline.c:227: error: ¿line¿ may be used uninitialized in this function make[1]: *** [/tmp/build/perf/util/srcline.o] Error 1 make: *** [install] Error 2 make: Leaving directory `/home/acme/git/linux/tools/perf' [acme@fedora12 linux]$ Help out GCC by initializing 'file' and 'line'. Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@gmail.com> Link: http://lkml.kernel.org/n/tip-h8k7h49z3cndqgjdftkmm9f8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/srcline.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 37353194e0f6..d11aefbc4b8d 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -223,8 +223,8 @@ out: char *get_srcline(struct dso *dso, unsigned long addr) { - char *file; - unsigned line; + char *file = NULL; + unsigned line = 0; char *srcline; char *dso_name = dso->long_name; size_t size; From 1df9297c8535a5bb2b776381e63d8334f87d4abe Mon Sep 17 00:00:00 2001 From: Felipe Pena <felipensp@gmail.com> Date: Wed, 9 Oct 2013 23:00:38 -0300 Subject: [PATCH 142/161] perf tests: Fix memory leak in dso-data.c Fix for a memory leak on test_file() function in dso-data.c. Signed-off-by: Felipe Pena <felipensp@gmail.com> Acked-by: Jiri Olsa <jolsa@redhat.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1381370438-4209-1-git-send-email-felipensp@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/tests/dso-data.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index dffe0551acaa..9cc81a3eb9b4 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -35,6 +35,7 @@ static char *test_file(int size) if (size != write(fd, buf, size)) templ = NULL; + free(buf); close(fd); return templ; } From 3e6a147deef93ddbb899cb394d8d44118289e76a Mon Sep 17 00:00:00 2001 From: Jiri Olsa <jolsa@redhat.com> Date: Thu, 10 Oct 2013 22:24:00 +0200 Subject: [PATCH 143/161] perf tools: Separate lbfd check out of NO_DEMANGLE condition We fail build with NO_DEMANGLE with missing -lbfd externals error. The reason is that we now use bfd code in srcline object: perf tools: Implement addr2line directly using libbfd So we need to check/add -lbfd always now. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/Makefile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 29ad7d6c5311..96804247df08 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -470,6 +470,10 @@ else endif endif +ifeq ($(feature-libbfd), 1) + EXTLIBS += -lbfd +endif + ifdef NO_DEMANGLE CFLAGS += -DNO_DEMANGLE else @@ -477,9 +481,7 @@ else EXTLIBS += -liberty CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT else - ifeq ($(feature-libbfd), 1) - EXTLIBS += -lbfd - else + ifneq ($(feature-libbfd), 1) $(feature_check,liberty) ifeq ($(feature-liberty), 1) EXTLIBS += -lbfd -liberty @@ -502,6 +504,10 @@ else endif endif +ifneq ($(filter -lbfd,$(EXTLIBS)),) + CFLAGS += -DHAVE_LIBBFD_SUPPORT +endif + ifndef NO_ON_EXIT ifeq ($(feature-on-exit), 1) CFLAGS += -DHAVE_ON_EXIT_SUPPORT @@ -524,10 +530,6 @@ ifndef NO_LIBNUMA endif endif -ifndef ($(filter -lbfd,$(EXTLIBS)),) - CFLAGS += -DHAVE_LIBBFD_SUPPORT -endif - # Among the variables below, these: # perfexecdir # template_dir From 52afdaf9f0c6a35e154ba42ac9510044e16d75ec Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Wed, 9 Oct 2013 15:01:11 +0300 Subject: [PATCH 144/161] perf symbols: Validate kcore module addresses Before using kcore we need to check that modules are in memory at the same addresses that they were when data was recorded. This is done because, while we could remap symbols to different addresses, the object code linkages would still be different which would provide an erroneous view of the object code. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381320078-16497-2-git-send-email-adrian.hunter@intel.com [ Rename basename to base_name to avoid shadowing libgen's basename in fedora 12 ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/symbol.c | 202 ++++++++++++++++++++++++++++++++++----- 1 file changed, 178 insertions(+), 24 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 5fd95135e838..b2f60ddc864f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -798,6 +798,178 @@ bool symbol__restricted_filename(const char *filename, return restricted; } +struct module_info { + struct rb_node rb_node; + char *name; + u64 start; +}; + +static void add_module(struct module_info *mi, struct rb_root *modules) +{ + struct rb_node **p = &modules->rb_node; + struct rb_node *parent = NULL; + struct module_info *m; + + while (*p != NULL) { + parent = *p; + m = rb_entry(parent, struct module_info, rb_node); + if (strcmp(mi->name, m->name) < 0) + p = &(*p)->rb_left; + else + p = &(*p)->rb_right; + } + rb_link_node(&mi->rb_node, parent, p); + rb_insert_color(&mi->rb_node, modules); +} + +static void delete_modules(struct rb_root *modules) +{ + struct module_info *mi; + struct rb_node *next = rb_first(modules); + + while (next) { + mi = rb_entry(next, struct module_info, rb_node); + next = rb_next(&mi->rb_node); + rb_erase(&mi->rb_node, modules); + free(mi->name); + free(mi); + } +} + +static struct module_info *find_module(const char *name, + struct rb_root *modules) +{ + struct rb_node *n = modules->rb_node; + + while (n) { + struct module_info *m; + int cmp; + + m = rb_entry(n, struct module_info, rb_node); + cmp = strcmp(name, m->name); + if (cmp < 0) + n = n->rb_left; + else if (cmp > 0) + n = n->rb_right; + else + return m; + } + + return NULL; +} + +static int __read_proc_modules(void *arg, const char *name, u64 start) +{ + struct rb_root *modules = arg; + struct module_info *mi; + + mi = zalloc(sizeof(struct module_info)); + if (!mi) + return -ENOMEM; + + mi->name = strdup(name); + mi->start = start; + + if (!mi->name) { + free(mi); + return -ENOMEM; + } + + add_module(mi, modules); + + return 0; +} + +static int read_proc_modules(const char *filename, struct rb_root *modules) +{ + if (symbol__restricted_filename(filename, "/proc/modules")) + return -1; + + if (modules__parse(filename, modules, __read_proc_modules)) { + delete_modules(modules); + return -1; + } + + return 0; +} + +static int do_validate_kcore_modules(const char *filename, struct map *map, + struct map_groups *kmaps) +{ + struct rb_root modules = RB_ROOT; + struct map *old_map; + int err; + + err = read_proc_modules(filename, &modules); + if (err) + return err; + + old_map = map_groups__first(kmaps, map->type); + while (old_map) { + struct map *next = map_groups__next(old_map); + struct module_info *mi; + + if (old_map == map || old_map->start == map->start) { + /* The kernel map */ + old_map = next; + continue; + } + + /* Module must be in memory at the same address */ + mi = find_module(old_map->dso->short_name, &modules); + if (!mi || mi->start != old_map->start) { + err = -EINVAL; + goto out; + } + + old_map = next; + } +out: + delete_modules(&modules); + return err; +} + +/* + * If kallsyms is referenced by name then we look for filename in the same + * directory. + */ +static bool filename_from_kallsyms_filename(char *filename, + const char *base_name, + const char *kallsyms_filename) +{ + char *name; + + strcpy(filename, kallsyms_filename); + name = strrchr(filename, '/'); + if (!name) + return false; + + name += 1; + + if (!strcmp(name, "kallsyms")) { + strcpy(name, base_name); + return true; + } + + return false; +} + +static int validate_kcore_modules(const char *kallsyms_filename, + struct map *map) +{ + struct map_groups *kmaps = map__kmap(map)->kmaps; + char modules_filename[PATH_MAX]; + + if (!filename_from_kallsyms_filename(modules_filename, "modules", + kallsyms_filename)) + return -EINVAL; + + if (do_validate_kcore_modules(modules_filename, map, kmaps)) + return -EINVAL; + + return 0; +} + struct kcore_mapfn_data { struct dso *dso; enum map_type type; @@ -821,28 +993,6 @@ static int kcore_mapfn(u64 start, u64 len, u64 pgoff, void *data) return 0; } -/* - * If kallsyms is referenced by name then we look for kcore in the same - * directory. - */ -static bool kcore_filename_from_kallsyms_filename(char *kcore_filename, - const char *kallsyms_filename) -{ - char *name; - - strcpy(kcore_filename, kallsyms_filename); - name = strrchr(kcore_filename, '/'); - if (!name) - return false; - - if (!strcmp(name, "/kallsyms")) { - strcpy(name, "/kcore"); - return true; - } - - return false; -} - static int dso__load_kcore(struct dso *dso, struct map *map, const char *kallsyms_filename) { @@ -859,8 +1009,12 @@ static int dso__load_kcore(struct dso *dso, struct map *map, if (map != machine->vmlinux_maps[map->type]) return -EINVAL; - if (!kcore_filename_from_kallsyms_filename(kcore_filename, - kallsyms_filename)) + if (!filename_from_kallsyms_filename(kcore_filename, "kcore", + kallsyms_filename)) + return -EINVAL; + + /* All modules must be present at their original addresses */ + if (validate_kcore_modules(kallsyms_filename, map)) return -EINVAL; md.dso = dso; From afba19d9dc8eba66ea26901708cf99354c637786 Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Wed, 9 Oct 2013 15:01:12 +0300 Subject: [PATCH 145/161] perf symbols: Workaround objdump difficulties with kcore The objdump tool fails to annotate module symbols when looking at kcore. Workaround this by extracting object code from kcore and putting it in a temporary file for objdump to use instead. The temporary file is created to look like kcore but contains only the function being disassembled. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381320078-16497-3-git-send-email-adrian.hunter@intel.com [ Renamed 'index' to 'idx' to avoid shadowing string.h's 'index' in Fedora 12, Replace local with variable length with malloc/free to fix build in Fedora 12 ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/annotate.c | 21 +++ tools/perf/util/symbol-elf.c | 229 +++++++++++++++++++++++++++++++ tools/perf/util/symbol-minimal.c | 9 ++ tools/perf/util/symbol.h | 14 ++ 4 files changed, 273 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index d73e8008aada..882bb864cee0 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -879,6 +879,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 +942,23 @@ fallback: 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 +991,8 @@ fallback: pclose(file); out_free_filename: + if (delete_extract) + kcore_extract__delete(&kce); if (free_filename) free(filename); return err; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index c37693052800..499c71d30225 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1018,6 +1018,235 @@ int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, return err; } +static int copy_bytes(int from, off_t from_offs, int to, off_t to_offs, u64 len) +{ + ssize_t r; + size_t n; + int err = -1; + char *buf = malloc(page_size); + + if (buf == NULL) + return -1; + + if (lseek(to, to_offs, SEEK_SET) != to_offs) + goto out; + + if (lseek(from, from_offs, SEEK_SET) != from_offs) + goto out; + + while (len) { + n = page_size; + if (len < n) + n = len; + /* Use read because mmap won't work on proc files */ + r = read(from, buf, n); + if (r < 0) + goto out; + if (!r) + break; + n = r; + r = write(to, buf, n); + if (r < 0) + goto out; + if ((size_t)r != n) + goto out; + len -= n; + } + + err = 0; +out: + free(buf); + return err; +} + +struct kcore { + int fd; + int elfclass; + Elf *elf; + GElf_Ehdr ehdr; +}; + +static int kcore__open(struct kcore *kcore, const char *filename) +{ + GElf_Ehdr *ehdr; + + kcore->fd = open(filename, O_RDONLY); + if (kcore->fd == -1) + return -1; + + kcore->elf = elf_begin(kcore->fd, ELF_C_READ, NULL); + if (!kcore->elf) + goto out_close; + + kcore->elfclass = gelf_getclass(kcore->elf); + if (kcore->elfclass == ELFCLASSNONE) + goto out_end; + + ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr); + if (!ehdr) + goto out_end; + + return 0; + +out_end: + elf_end(kcore->elf); +out_close: + close(kcore->fd); + return -1; +} + +static int kcore__init(struct kcore *kcore, char *filename, int elfclass, + bool temp) +{ + GElf_Ehdr *ehdr; + + kcore->elfclass = elfclass; + + if (temp) + kcore->fd = mkstemp(filename); + else + kcore->fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400); + if (kcore->fd == -1) + return -1; + + kcore->elf = elf_begin(kcore->fd, ELF_C_WRITE, NULL); + if (!kcore->elf) + goto out_close; + + if (!gelf_newehdr(kcore->elf, elfclass)) + goto out_end; + + ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr); + if (!ehdr) + goto out_end; + + return 0; + +out_end: + elf_end(kcore->elf); +out_close: + close(kcore->fd); + unlink(filename); + return -1; +} + +static void kcore__close(struct kcore *kcore) +{ + elf_end(kcore->elf); + close(kcore->fd); +} + +static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count) +{ + GElf_Ehdr *ehdr = &to->ehdr; + GElf_Ehdr *kehdr = &from->ehdr; + + memcpy(ehdr->e_ident, kehdr->e_ident, EI_NIDENT); + ehdr->e_type = kehdr->e_type; + ehdr->e_machine = kehdr->e_machine; + ehdr->e_version = kehdr->e_version; + ehdr->e_entry = 0; + ehdr->e_shoff = 0; + ehdr->e_flags = kehdr->e_flags; + ehdr->e_phnum = count; + ehdr->e_shentsize = 0; + ehdr->e_shnum = 0; + ehdr->e_shstrndx = 0; + + if (from->elfclass == ELFCLASS32) { + ehdr->e_phoff = sizeof(Elf32_Ehdr); + ehdr->e_ehsize = sizeof(Elf32_Ehdr); + ehdr->e_phentsize = sizeof(Elf32_Phdr); + } else { + ehdr->e_phoff = sizeof(Elf64_Ehdr); + ehdr->e_ehsize = sizeof(Elf64_Ehdr); + ehdr->e_phentsize = sizeof(Elf64_Phdr); + } + + if (!gelf_update_ehdr(to->elf, ehdr)) + return -1; + + if (!gelf_newphdr(to->elf, count)) + return -1; + + return 0; +} + +static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset, + u64 addr, u64 len) +{ + GElf_Phdr gphdr; + GElf_Phdr *phdr; + + phdr = gelf_getphdr(kcore->elf, idx, &gphdr); + if (!phdr) + return -1; + + phdr->p_type = PT_LOAD; + phdr->p_flags = PF_R | PF_W | PF_X; + phdr->p_offset = offset; + phdr->p_vaddr = addr; + phdr->p_paddr = 0; + phdr->p_filesz = len; + phdr->p_memsz = len; + phdr->p_align = page_size; + + if (!gelf_update_phdr(kcore->elf, idx, phdr)) + return -1; + + return 0; +} + +static off_t kcore__write(struct kcore *kcore) +{ + return elf_update(kcore->elf, ELF_C_WRITE); +} + +int kcore_extract__create(struct kcore_extract *kce) +{ + struct kcore kcore; + struct kcore extract; + size_t count = 1; + int idx = 0, err = -1; + off_t offset = page_size, sz; + + if (kcore__open(&kcore, kce->kcore_filename)) + return -1; + + strcpy(kce->extract_filename, PERF_KCORE_EXTRACT); + if (kcore__init(&extract, kce->extract_filename, kcore.elfclass, true)) + goto out_kcore_close; + + if (kcore__copy_hdr(&kcore, &extract, count)) + goto out_extract_close; + + if (kcore__add_phdr(&extract, idx, offset, kce->addr, kce->len)) + goto out_extract_close; + + sz = kcore__write(&extract); + if (sz < 0 || sz > offset) + goto out_extract_close; + + if (copy_bytes(kcore.fd, kce->offs, extract.fd, offset, kce->len)) + goto out_extract_close; + + err = 0; + +out_extract_close: + kcore__close(&extract); + if (err) + unlink(kce->extract_filename); +out_kcore_close: + kcore__close(&kcore); + + return err; +} + +void kcore_extract__delete(struct kcore_extract *kce) +{ + unlink(kce->extract_filename); +} + void symbol__elf_init(void) { elf_version(EV_CURRENT); diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 3a802c300fc5..928556d2508f 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -308,6 +308,15 @@ int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused, return -1; } +int kcore_extract__create(struct kcore_extract *kce __maybe_unused) +{ + return -1; +} + +void kcore_extract__delete(struct kcore_extract *kce __maybe_unused) +{ +} + void symbol__elf_init(void) { } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2d3eb43ab9f9..fb107e13e925 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -256,4 +256,18 @@ typedef int (*mapfn_t)(u64 start, u64 len, u64 pgoff, void *data); int file__read_maps(int fd, bool exe, mapfn_t mapfn, void *data, bool *is_64_bit); +#define PERF_KCORE_EXTRACT "/tmp/perf-kcore-XXXXXX" + +struct kcore_extract { + char *kcore_filename; + u64 addr; + u64 offs; + u64 len; + char extract_filename[sizeof(PERF_KCORE_EXTRACT)]; + int fd; +}; + +int kcore_extract__create(struct kcore_extract *kce); +void kcore_extract__delete(struct kcore_extract *kce); + #endif /* __PERF_SYMBOL */ From 4e987712740a3634c19a6fedaf12577b26775dc5 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo <acme@redhat.com> Date: Mon, 14 Oct 2013 13:43:38 +0300 Subject: [PATCH 146/161] perf symbols: Add map_groups__find_ams() Add a function to find a symbol using an ip that might be on a different map. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381747424-3557-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/map.c | 17 +++++++++++++++++ tools/perf/util/map.h | 4 ++++ 2 files changed, 21 insertions(+) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 17ee458a0870..9dea404de3fa 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -371,6 +371,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) { diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 4886ca280536..0359b4a808f0 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -167,6 +167,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, From 3fb66335e13ef7426affe9efa48c08857202c1cb Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Wed, 9 Oct 2013 17:00:23 +0200 Subject: [PATCH 147/161] tools/perf/build: Fix non-existent build directory handling Arnaldo reported that non-existent build directories were not recognized properly. The reason is readlink failure causing 'O' to become empty. Solve it by passing through the 'O' variable unmodified if readlink fails. Reported-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Link: http://lkml.kernel.org/r/20131009150023.GA10167@gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 5aa3d040bbf3..914704495166 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -34,7 +34,7 @@ endif # Only pass canonical directory names as the output directory: # ifneq ($(O),) - FULL_O := $(shell readlink -f $(O)) + FULL_O := $(shell readlink -f $(O) || echo $(O)) endif define print_msg From fcf92585014f0a0e390d2819de8278ae90da5842 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 08:05:25 +0200 Subject: [PATCH 148/161] tools/perf/build: Pass through DEBUG parameter Arnaldo reported that 'make DEBUG=1' does not work anymore. The reason is that 'Makefile' only passes it through to 'Makefile.perf' via the environment, but 'Makefile.perf' checks that it's a command line option: ifeq ("$(origin DEBUG)", "command line") PERF_DEBUG = $(DEBUG) endif So pass it through properly, and also clean up DEBUG parameter handling while at it and fix a couple of annoyances: - DEBUG=0 used to be interpreted as 'debugging on'. Turn it into 'debugging off' instead. - Same was the case for 'DEBUG=' - turn that into debug-off as well. - Pass in just a clean, sanitized 'DEBUG' value and get rid of the intermediate, unnecessary PERF_DEBUG variable. Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/Makefile | 15 ++++++++++++++- tools/perf/config/Makefile | 7 ++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 914704495166..4835618a5608 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -37,12 +37,25 @@ ifneq ($(O),) FULL_O := $(shell readlink -f $(O) || echo $(O)) endif +# +# 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 + define print_msg @printf ' BUILD: Doing '\''make \033[33m-j'$(JOBS)'\033[m'\'' parallel build\n' endef define make - @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $@ + @$(MAKE) -f Makefile.perf --no-print-directory -j$(JOBS) O=$(FULL_O) $(SET_DEBUG) $@ endef # diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 96804247df08..9524c0c4e88f 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -66,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 @@ -210,7 +207,7 @@ ifeq ($(feature-volatile-register-var), 1) CFLAGS += -Wvolatile-register-var endif -ifndef PERF_DEBUG +ifeq ($(DEBUG),0) ifeq ($(feature-fortify-source), 1) CFLAGS += -D_FORTIFY_SOURCE=2 endif From 0dc097421974e076b47d19806966adf5ebc7fd6b Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 08:47:01 +0200 Subject: [PATCH 149/161] tools/perf/build: Fix DPACKAGE definitions for the libbfd et al testcases Namhyung Kim reported these duplicate DPACKAGE definitions: test-libbfd: $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl Fix all affected places and use Namhyung's suggestion that the definition should look like a normal C string: -DPACKAGE='"perf"'. Reported-by: Namhyung Kim <namhyung@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/feature-checks/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 8ecac1908d5e..cf33596c7300 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -37,7 +37,7 @@ BUILD = $(CC) $(LDFLAGS) -o $(OUTPUT)$@ $@.c ############################### test-all: - $(BUILD) -Werror -fstack-protector -fstack-protector-all -Wvolatile-register-var -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' -DPACKAGE=perf -lbfd -ldl + $(BUILD) -Werror -fstack-protector -fstack-protector-all -Wvolatile-register-var -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) @@ -123,13 +123,13 @@ test-libpython-version: $(BUILD) $(FLAGS_PYTHON_EMBED) test-libbfd: - $(BUILD) -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl + $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl test-liberty: - $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl -liberty + $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty test-liberty-z: - $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='perf' -DPACKAGE=perf -lbfd -ldl -liberty -lz + $(CC) -o $(OUTPUT)$@ test-libbfd.c -DPACKAGE='"perf"' -lbfd -ldl -liberty -lz test-cplus-demangle: $(BUILD) -liberty From 5f36978ca5b12b1e35535dedb8c999694fc0dfcf Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 08:53:17 +0200 Subject: [PATCH 150/161] tools/perf/build: Simplify the libelf logic Ulrich Drepper and Namhyung Kim reported that the libelf logic in config/Makefile is duplicated in part. Remove the duplication, and also remove the now unused FLAGS_LIBELF variable. Reported-by: Ulrich Drepper <drepper@gmail.com> Reported-by: Namhyung Kim <namhyung@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/Makefile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 9524c0c4e88f..d2079220ff87 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -280,7 +280,6 @@ endif # NO_LIBELF ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT - FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT @@ -305,13 +304,6 @@ ifndef NO_LIBELF endif # NO_DWARF endif # NO_LIBELF -ifndef NO_LIBELF - CFLAGS += -DHAVE_LIBELF_SUPPORT - ifeq ($(feature-libelf-mmap), 1) - CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT - endif -endif # NO_LIBELF - # There's only x86 (both 32 and 64) support for CFI unwind so far ifneq ($(ARCH),x86) NO_LIBUNWIND := 1 From 01287e2cb7ad17b3d77751888d458a6b6a2bba15 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 08:58:57 +0200 Subject: [PATCH 151/161] tools/perf/build: Remove the volatile-register-var feature check Namhyung Kim noticed that the volatile-register-var feature check is superfluous: > The gcc manpage says this warning is enabled by -Wall, and we add -Wall > to CFLAGS before doing feature checks. So all gcc versions that support > -Wvolatile-register-var enables it by default without this check and > older gcc versions will always fail the feature check. Remove it - this will further speed up feature checks. Reported-by: Namhyung Kim <namhyung@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/Makefile | 7 +------ tools/perf/config/feature-checks/Makefile | 8 ++------ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index d2079220ff87..c516d6ba6716 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -132,8 +132,7 @@ CORE_FEATURE_TESTS = \ libunwind \ on-exit \ stackprotector \ - stackprotector-all \ - volatile-register-var + stackprotector-all # # So here we detect whether test-all was rebuilt, to be able @@ -203,10 +202,6 @@ ifeq ($(feature-stackprotector), 1) CFLAGS += -Wstack-protector endif -ifeq ($(feature-volatile-register-var), 1) - CFLAGS += -Wvolatile-register-var -endif - ifeq ($(DEBUG),0) ifeq ($(feature-fortify-source), 1) CFLAGS += -D_FORTIFY_SOURCE=2 diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index cf33596c7300..2eb83467cca2 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -25,8 +25,7 @@ FILES= \ test-libunwind \ test-on-exit \ test-stackprotector-all \ - test-stackprotector \ - test-volatile-register-var + test-stackprotector CC := $(CC) -MD @@ -37,7 +36,7 @@ BUILD = $(CC) $(LDFLAGS) -o $(OUTPUT)$@ $@.c ############################### test-all: - $(BUILD) -Werror -fstack-protector -fstack-protector-all -Wvolatile-register-var -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 + $(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) @@ -48,9 +47,6 @@ test-stackprotector-all: test-stackprotector: $(BUILD) -Werror -fstack-protector -test-volatile-register-var: - $(BUILD) -Werror -Wvolatile-register-var - test-fortify-source: $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 From 046fa7ae20d2390c65be8eb406efecff15e8b71d Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 09:06:21 +0200 Subject: [PATCH 152/161] tools/perf/build: Improve the 'stackprotector' feature test Namhyung Kim noticed that the stackprotector testcase was incomplete: > The flag being checked should be -"W"stack-protector instead of > -"f"stack-protector. And the gcc manpage says that -Wstack-protector is > only active when -fstack-protector is active. So the end result should > look like > > $(BUILD) -Werror -fstack-protector -Wstack-protector Add -Wstack-protector. Reported-by: Namhyung Kim <namhyung@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/feature-checks/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 2eb83467cca2..c70d23ecb64e 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -45,7 +45,7 @@ test-stackprotector-all: $(BUILD) -Werror -fstack-protector-all test-stackprotector: - $(BUILD) -Werror -fstack-protector + $(BUILD) -Werror -fstack-protector -Wstack-protector test-fortify-source: $(BUILD) -O2 -Werror -D_FORTIFY_SOURCE=2 From 231486a5223b1023bcabf53d16d63a83b9f27bf7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar <mingo@kernel.org> Date: Thu, 10 Oct 2013 09:10:59 +0200 Subject: [PATCH 153/161] tools/perf/build: Simplify the autodep inclusion rule Namhyung Kim noticed that the autodep .d file inclusion rule was unnecessarily complicated: > > +-include *.d */*.d > > Hmm.. this */*.d part is really needed? Only include *.d files. Reported-by: Namhyung Kim <namhyung@kernel.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/config/feature-checks/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index c70d23ecb64e..452b67cc4d7b 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -136,7 +136,7 @@ test-on-exit: test-backtrace: $(BUILD) --include *.d */*.d +-include *.d ############################### From 6e427ab02c8886ca6c9ecdbb318e68fe8f605469 Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 14 Oct 2013 13:43:40 +0300 Subject: [PATCH 154/161] perf annotate: Find kcore symbols on other maps Use the new map_groups__find_ams() method to find kcore symbols on other maps. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381747424-3557-4-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/annotate.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 882bb864cee0..cf6242c92ee2 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -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); From 9a17d7268d71674f0bbff6821f7d8e6dc0ece19a Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 14 Oct 2013 13:43:41 +0300 Subject: [PATCH 155/161] perf tools: Add copyfile_mode() Add a function to copy a file specifying the permissions to use for the created file. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381747424-3557-5-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/util.c | 18 +++++++++++++----- tools/perf/util/util.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index ab71d6216803..8dc8cf39f4ed 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -55,17 +55,20 @@ int mkdir_p(char *path, mode_t mode) return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; } -static int slow_copyfile(const char *from, const char *to) +static int slow_copyfile(const char *from, const char *to, mode_t mode) { - int err = 0; + int err = -1; char *line = NULL; size_t n; FILE *from_fp = fopen(from, "r"), *to_fp; + mode_t old_umask; if (from_fp == NULL) goto out; + old_umask = umask(mode ^ 0777); to_fp = fopen(to, "w"); + umask(old_umask); if (to_fp == NULL) goto out_fclose_from; @@ -82,7 +85,7 @@ out: return err; } -int copyfile(const char *from, const char *to) +int copyfile_mode(const char *from, const char *to, mode_t mode) { int fromfd, tofd; struct stat st; @@ -93,13 +96,13 @@ int copyfile(const char *from, const char *to) goto out; if (st.st_size == 0) /* /proc? do it slowly... */ - return slow_copyfile(from, to); + return slow_copyfile(from, to, mode); fromfd = open(from, O_RDONLY); if (fromfd < 0) goto out; - tofd = creat(to, 0755); + tofd = creat(to, mode); if (tofd < 0) goto out_close_from; @@ -121,6 +124,11 @@ out: return err; } +int copyfile(const char *from, const char *to) +{ + return copyfile_mode(from, to, 0755); +} + unsigned long convert_unit(unsigned long value, char *unit) { *unit = ' '; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 1f06ba44cd53..42dfba70fbfc 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -243,6 +243,7 @@ static inline int sane_case(int x, int high) int mkdir_p(char *path, mode_t mode); int copyfile(const char *from, const char *to); +int copyfile_mode(const char *from, const char *to, mode_t mode); s64 perf_atoll(const char *str); char **argv_split(const char *str, int *argcp); From 0544d4225c52ca31ab2a55b22ddce1392d8f45a4 Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 14 Oct 2013 13:43:43 +0300 Subject: [PATCH 156/161] perf symbols: Add ability to find kcore in build-id cache When no vmlinux is found, tools will use kallsyms and, if possible, kcore. Add the ability to find kcore in the build-id cache. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381747424-3557-7-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/symbol.c | 147 +++++++++++++++++++++++++++------------ 1 file changed, 103 insertions(+), 44 deletions(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b2f60ddc864f..76a9e933a7a5 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1401,6 +1401,105 @@ out: return err; } +static int find_matching_kcore(struct map *map, char *dir, size_t dir_sz) +{ + char kallsyms_filename[PATH_MAX]; + struct dirent *dent; + int ret = -1; + DIR *d; + + d = opendir(dir); + if (!d) + return -1; + + while (1) { + dent = readdir(d); + if (!dent) + break; + if (dent->d_type != DT_DIR) + continue; + scnprintf(kallsyms_filename, sizeof(kallsyms_filename), + "%s/%s/kallsyms", dir, dent->d_name); + if (!validate_kcore_modules(kallsyms_filename, map)) { + strlcpy(dir, kallsyms_filename, dir_sz); + ret = 0; + break; + } + } + + closedir(d); + + return ret; +} + +static char *dso__find_kallsyms(struct dso *dso, struct map *map) +{ + u8 host_build_id[BUILD_ID_SIZE]; + char sbuild_id[BUILD_ID_SIZE * 2 + 1]; + bool is_host = false; + char path[PATH_MAX]; + + if (!dso->has_build_id) { + /* + * Last resort, if we don't have a build-id and couldn't find + * any vmlinux file, try the running kernel kallsyms table. + */ + goto proc_kallsyms; + } + + if (sysfs__read_build_id("/sys/kernel/notes", host_build_id, + sizeof(host_build_id)) == 0) + is_host = dso__build_id_equal(dso, host_build_id); + + build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); + + /* Use /proc/kallsyms if possible */ + if (is_host) { + DIR *d; + int fd; + + /* If no cached kcore go with /proc/kallsyms */ + scnprintf(path, sizeof(path), "%s/[kernel.kcore]/%s", + buildid_dir, sbuild_id); + d = opendir(path); + if (!d) + goto proc_kallsyms; + closedir(d); + + /* + * Do not check the build-id cache, until we know we cannot use + * /proc/kcore. + */ + fd = open("/proc/kcore", O_RDONLY); + if (fd != -1) { + close(fd); + /* If module maps match go with /proc/kallsyms */ + if (!validate_kcore_modules("/proc/kallsyms", map)) + goto proc_kallsyms; + } + + /* Find kallsyms in build-id cache with kcore */ + if (!find_matching_kcore(map, path, sizeof(path))) + return strdup(path); + + goto proc_kallsyms; + } + + scnprintf(path, sizeof(path), "%s/[kernel.kallsyms]/%s", + buildid_dir, sbuild_id); + + if (access(path, F_OK)) { + pr_err("No kallsyms or vmlinux with build-id %s was found\n", + sbuild_id); + return NULL; + } + + return strdup(path); + +proc_kallsyms: + return strdup("/proc/kallsyms"); +} + static int dso__load_kernel_sym(struct dso *dso, struct map *map, symbol_filter_t filter) { @@ -1449,51 +1548,11 @@ static int dso__load_kernel_sym(struct dso *dso, struct map *map, if (symbol_conf.symfs[0] != 0) return -1; - /* - * Say the kernel DSO was created when processing the build-id header table, - * we have a build-id, so check if it is the same as the running kernel, - * using it if it is. - */ - if (dso->has_build_id) { - u8 kallsyms_build_id[BUILD_ID_SIZE]; - char sbuild_id[BUILD_ID_SIZE * 2 + 1]; + kallsyms_allocated_filename = dso__find_kallsyms(dso, map); + if (!kallsyms_allocated_filename) + return -1; - if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id, - sizeof(kallsyms_build_id)) == 0) { - if (dso__build_id_equal(dso, kallsyms_build_id)) { - kallsyms_filename = "/proc/kallsyms"; - goto do_kallsyms; - } - } - /* - * Now look if we have it on the build-id cache in - * $HOME/.debug/[kernel.kallsyms]. - */ - build_id__sprintf(dso->build_id, sizeof(dso->build_id), - sbuild_id); - - if (asprintf(&kallsyms_allocated_filename, - "%s/.debug/[kernel.kallsyms]/%s", - getenv("HOME"), sbuild_id) == -1) { - pr_err("Not enough memory for kallsyms file lookup\n"); - return -1; - } - - kallsyms_filename = kallsyms_allocated_filename; - - if (access(kallsyms_filename, F_OK)) { - pr_err("No kallsyms or vmlinux with build-id %s " - "was found\n", sbuild_id); - free(kallsyms_allocated_filename); - return -1; - } - } else { - /* - * Last resort, if we don't have a build-id and couldn't find - * any vmlinux file, try the running kernel kallsyms table. - */ - kallsyms_filename = "/proc/kallsyms"; - } + kallsyms_filename = kallsyms_allocated_filename; do_kallsyms: err = dso__load_kallsyms(dso, kallsyms_filename, map, filter); From 1179e11bbb655162e83b33e17a97c45d3fe292da Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 14 Oct 2013 13:43:39 +0300 Subject: [PATCH 157/161] perf annotate: Fix annotate_browser__callq() When following a call, annotate_browser__callq() uses the current symbol's map to look up the target ip. That will not work if the target ip is on a map with a different mapping (i.e. start - pgoff is different). Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381747424-3557-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/ui/browsers/annotate.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 08545ae46992..57d3a8659fc0 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -442,35 +442,34 @@ 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 = 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)) { 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; } From fc1b691d7651d9496e912de7e0fc73a5be3294af Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 14 Oct 2013 16:57:29 +0300 Subject: [PATCH 158/161] perf buildid-cache: Add ability to add kcore to the cache kcore can be used to view the running kernel object code. However, kcore changes as modules are loaded and unloaded, and when the kernel decides to modify its own code. Consequently it is useful to create a copy of kcore at a particular time. Unlike vmlinux, kcore is not unique for a given build-id. And in addition, the kallsyms and modules files are also needed. The tool therefore creates a directory: ~/.debug/[kernel.kcore]/<build-id>/<YYYYmmddHHMMSShh> which contains: kcore, kallsyms and modules. Note that the copied kcore contains only code sections. See the kcore_copy() function for how that is determined. The tool will not make additional copies of kcore if there is already one with the same modules at the same addresses. Currently, perf tools will not look for kcore in the cache. That is addressed in another patch. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/525BF849.5030405@intel.com [ renamed 'index' to 'idx' to avoid shadowing string.h symbol in f12, use at least one member initializer when initializing a struct to zeros, also to fix the build on f12 ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- .../perf/Documentation/perf-buildid-cache.txt | 13 + tools/perf/builtin-buildid-cache.c | 148 ++++++- tools/perf/util/symbol-elf.c | 366 ++++++++++++++++++ tools/perf/util/symbol-minimal.c | 6 + tools/perf/util/symbol.c | 41 ++ tools/perf/util/symbol.h | 3 + 6 files changed, 576 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-buildid-cache.txt b/tools/perf/Documentation/perf-buildid-cache.txt index e9a8349a7172..fd77d81ea748 100644 --- a/tools/perf/Documentation/perf-buildid-cache.txt +++ b/tools/perf/Documentation/perf-buildid-cache.txt @@ -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. diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index c96c8fa38243..8140b7b249fa 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -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; } diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 499c71d30225..d6b8af3ce344 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1202,6 +1202,372 @@ static off_t kcore__write(struct kcore *kcore) return elf_update(kcore->elf, ELF_C_WRITE); } +struct phdr_data { + off_t offset; + u64 addr; + u64 len; +}; + +struct kcore_copy_info { + u64 stext; + u64 etext; + u64 first_symbol; + u64 last_symbol; + u64 first_module; + u64 last_module_symbol; + struct phdr_data kernel_map; + struct phdr_data modules_map; +}; + +static int kcore_copy__process_kallsyms(void *arg, const char *name, char type, + u64 start) +{ + struct kcore_copy_info *kci = arg; + + if (!symbol_type__is_a(type, MAP__FUNCTION)) + return 0; + + if (strchr(name, '[')) { + if (start > kci->last_module_symbol) + kci->last_module_symbol = start; + return 0; + } + + if (!kci->first_symbol || start < kci->first_symbol) + kci->first_symbol = start; + + if (!kci->last_symbol || start > kci->last_symbol) + kci->last_symbol = start; + + if (!strcmp(name, "_stext")) { + kci->stext = start; + return 0; + } + + if (!strcmp(name, "_etext")) { + kci->etext = start; + return 0; + } + + return 0; +} + +static int kcore_copy__parse_kallsyms(struct kcore_copy_info *kci, + const char *dir) +{ + char kallsyms_filename[PATH_MAX]; + + scnprintf(kallsyms_filename, PATH_MAX, "%s/kallsyms", dir); + + if (symbol__restricted_filename(kallsyms_filename, "/proc/kallsyms")) + return -1; + + if (kallsyms__parse(kallsyms_filename, kci, + kcore_copy__process_kallsyms) < 0) + return -1; + + return 0; +} + +static int kcore_copy__process_modules(void *arg, + const char *name __maybe_unused, + u64 start) +{ + struct kcore_copy_info *kci = arg; + + if (!kci->first_module || start < kci->first_module) + kci->first_module = start; + + return 0; +} + +static int kcore_copy__parse_modules(struct kcore_copy_info *kci, + const char *dir) +{ + char modules_filename[PATH_MAX]; + + scnprintf(modules_filename, PATH_MAX, "%s/modules", dir); + + if (symbol__restricted_filename(modules_filename, "/proc/modules")) + return -1; + + if (modules__parse(modules_filename, kci, + kcore_copy__process_modules) < 0) + return -1; + + return 0; +} + +static void kcore_copy__map(struct phdr_data *p, u64 start, u64 end, u64 pgoff, + u64 s, u64 e) +{ + if (p->addr || s < start || s >= end) + return; + + p->addr = s; + p->offset = (s - start) + pgoff; + p->len = e < end ? e - s : end - s; +} + +static int kcore_copy__read_map(u64 start, u64 len, u64 pgoff, void *data) +{ + struct kcore_copy_info *kci = data; + u64 end = start + len; + + kcore_copy__map(&kci->kernel_map, start, end, pgoff, kci->stext, + kci->etext); + + kcore_copy__map(&kci->modules_map, start, end, pgoff, kci->first_module, + kci->last_module_symbol); + + return 0; +} + +static int kcore_copy__read_maps(struct kcore_copy_info *kci, Elf *elf) +{ + if (elf_read_maps(elf, true, kcore_copy__read_map, kci) < 0) + return -1; + + return 0; +} + +static int kcore_copy__calc_maps(struct kcore_copy_info *kci, const char *dir, + Elf *elf) +{ + if (kcore_copy__parse_kallsyms(kci, dir)) + return -1; + + if (kcore_copy__parse_modules(kci, dir)) + return -1; + + if (kci->stext) + kci->stext = round_down(kci->stext, page_size); + else + kci->stext = round_down(kci->first_symbol, page_size); + + if (kci->etext) { + kci->etext = round_up(kci->etext, page_size); + } else if (kci->last_symbol) { + kci->etext = round_up(kci->last_symbol, page_size); + kci->etext += page_size; + } + + kci->first_module = round_down(kci->first_module, page_size); + + if (kci->last_module_symbol) { + kci->last_module_symbol = round_up(kci->last_module_symbol, + page_size); + kci->last_module_symbol += page_size; + } + + if (!kci->stext || !kci->etext) + return -1; + + if (kci->first_module && !kci->last_module_symbol) + return -1; + + return kcore_copy__read_maps(kci, elf); +} + +static int kcore_copy__copy_file(const char *from_dir, const char *to_dir, + const char *name) +{ + char from_filename[PATH_MAX]; + char to_filename[PATH_MAX]; + + scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name); + scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name); + + return copyfile_mode(from_filename, to_filename, 0400); +} + +static int kcore_copy__unlink(const char *dir, const char *name) +{ + char filename[PATH_MAX]; + + scnprintf(filename, PATH_MAX, "%s/%s", dir, name); + + return unlink(filename); +} + +static int kcore_copy__compare_fds(int from, int to) +{ + char *buf_from; + char *buf_to; + ssize_t ret; + size_t len; + int err = -1; + + buf_from = malloc(page_size); + buf_to = malloc(page_size); + if (!buf_from || !buf_to) + goto out; + + while (1) { + /* Use read because mmap won't work on proc files */ + ret = read(from, buf_from, page_size); + if (ret < 0) + goto out; + + if (!ret) + break; + + len = ret; + + if (readn(to, buf_to, len) != (int)len) + goto out; + + if (memcmp(buf_from, buf_to, len)) + goto out; + } + + err = 0; +out: + free(buf_to); + free(buf_from); + return err; +} + +static int kcore_copy__compare_files(const char *from_filename, + const char *to_filename) +{ + int from, to, err = -1; + + from = open(from_filename, O_RDONLY); + if (from < 0) + return -1; + + to = open(to_filename, O_RDONLY); + if (to < 0) + goto out_close_from; + + err = kcore_copy__compare_fds(from, to); + + close(to); +out_close_from: + close(from); + return err; +} + +static int kcore_copy__compare_file(const char *from_dir, const char *to_dir, + const char *name) +{ + char from_filename[PATH_MAX]; + char to_filename[PATH_MAX]; + + scnprintf(from_filename, PATH_MAX, "%s/%s", from_dir, name); + scnprintf(to_filename, PATH_MAX, "%s/%s", to_dir, name); + + return kcore_copy__compare_files(from_filename, to_filename); +} + +/** + * kcore_copy - copy kallsyms, modules and kcore from one directory to another. + * @from_dir: from directory + * @to_dir: to directory + * + * This function copies kallsyms, modules and kcore files from one directory to + * another. kallsyms and modules are copied entirely. Only code segments are + * copied from kcore. It is assumed that two segments suffice: one for the + * kernel proper and one for all the modules. The code segments are determined + * from kallsyms and modules files. The kernel map starts at _stext or the + * lowest function symbol, and ends at _etext or the highest function symbol. + * The module map starts at the lowest module address and ends at the highest + * module symbol. Start addresses are rounded down to the nearest page. End + * addresses are rounded up to the nearest page. An extra page is added to the + * highest kernel symbol and highest module symbol to, hopefully, encompass that + * symbol too. Because it contains only code sections, the resulting kcore is + * unusual. One significant peculiarity is that the mapping (start -> pgoff) + * is not the same for the kernel map and the modules map. That happens because + * the data is copied adjacently whereas the original kcore has gaps. Finally, + * kallsyms and modules files are compared with their copies to check that + * modules have not been loaded or unloaded while the copies were taking place. + * + * Return: %0 on success, %-1 on failure. + */ +int kcore_copy(const char *from_dir, const char *to_dir) +{ + struct kcore kcore; + struct kcore extract; + size_t count = 2; + int idx = 0, err = -1; + off_t offset = page_size, sz, modules_offset = 0; + struct kcore_copy_info kci = { .stext = 0, }; + char kcore_filename[PATH_MAX]; + char extract_filename[PATH_MAX]; + + if (kcore_copy__copy_file(from_dir, to_dir, "kallsyms")) + return -1; + + if (kcore_copy__copy_file(from_dir, to_dir, "modules")) + goto out_unlink_kallsyms; + + scnprintf(kcore_filename, PATH_MAX, "%s/kcore", from_dir); + scnprintf(extract_filename, PATH_MAX, "%s/kcore", to_dir); + + if (kcore__open(&kcore, kcore_filename)) + goto out_unlink_modules; + + if (kcore_copy__calc_maps(&kci, from_dir, kcore.elf)) + goto out_kcore_close; + + if (kcore__init(&extract, extract_filename, kcore.elfclass, false)) + goto out_kcore_close; + + if (!kci.modules_map.addr) + count -= 1; + + if (kcore__copy_hdr(&kcore, &extract, count)) + goto out_extract_close; + + if (kcore__add_phdr(&extract, idx++, offset, kci.kernel_map.addr, + kci.kernel_map.len)) + goto out_extract_close; + + if (kci.modules_map.addr) { + modules_offset = offset + kci.kernel_map.len; + if (kcore__add_phdr(&extract, idx, modules_offset, + kci.modules_map.addr, kci.modules_map.len)) + goto out_extract_close; + } + + sz = kcore__write(&extract); + if (sz < 0 || sz > offset) + goto out_extract_close; + + if (copy_bytes(kcore.fd, kci.kernel_map.offset, extract.fd, offset, + kci.kernel_map.len)) + goto out_extract_close; + + if (modules_offset && copy_bytes(kcore.fd, kci.modules_map.offset, + extract.fd, modules_offset, + kci.modules_map.len)) + goto out_extract_close; + + if (kcore_copy__compare_file(from_dir, to_dir, "modules")) + goto out_extract_close; + + if (kcore_copy__compare_file(from_dir, to_dir, "kallsyms")) + goto out_extract_close; + + err = 0; + +out_extract_close: + kcore__close(&extract); + if (err) + unlink(extract_filename); +out_kcore_close: + kcore__close(&kcore); +out_unlink_modules: + if (err) + kcore_copy__unlink(to_dir, "modules"); +out_unlink_kallsyms: + if (err) + kcore_copy__unlink(to_dir, "kallsyms"); + + return err; +} + int kcore_extract__create(struct kcore_extract *kce) { struct kcore kcore; diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 928556d2508f..2d2dd0532b5a 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -317,6 +317,12 @@ void kcore_extract__delete(struct kcore_extract *kce __maybe_unused) { } +int kcore_copy(const char *from_dir __maybe_unused, + const char *to_dir __maybe_unused) +{ + return -1; +} + void symbol__elf_init(void) { } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 76a9e933a7a5..b66c1eefc313 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -893,6 +893,47 @@ static int read_proc_modules(const char *filename, struct rb_root *modules) return 0; } +int compare_proc_modules(const char *from, const char *to) +{ + struct rb_root from_modules = RB_ROOT; + struct rb_root to_modules = RB_ROOT; + struct rb_node *from_node, *to_node; + struct module_info *from_m, *to_m; + int ret = -1; + + if (read_proc_modules(from, &from_modules)) + return -1; + + if (read_proc_modules(to, &to_modules)) + goto out_delete_from; + + from_node = rb_first(&from_modules); + to_node = rb_first(&to_modules); + while (from_node) { + if (!to_node) + break; + + from_m = rb_entry(from_node, struct module_info, rb_node); + to_m = rb_entry(to_node, struct module_info, rb_node); + + if (from_m->start != to_m->start || + strcmp(from_m->name, to_m->name)) + break; + + from_node = rb_next(from_node); + to_node = rb_next(to_node); + } + + if (!from_node && !to_node) + ret = 0; + + delete_modules(&to_modules); +out_delete_from: + delete_modules(&from_modules); + + return ret; +} + static int do_validate_kcore_modules(const char *filename, struct map *map, struct map_groups *kmaps) { diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index fb107e13e925..07de8fea2f48 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -270,4 +270,7 @@ struct kcore_extract { int kcore_extract__create(struct kcore_extract *kce); void kcore_extract__delete(struct kcore_extract *kce); +int kcore_copy(const char *from_dir, const char *to_dir); +int compare_proc_modules(const char *from, const char *to); + #endif /* __PERF_SYMBOL */ From 1d5077bdd9a10c4297cded139989bb9ee2998a6c Mon Sep 17 00:00:00 2001 From: Adrian Hunter <adrian.hunter@intel.com> Date: Mon, 14 Oct 2013 13:43:44 +0300 Subject: [PATCH 159/161] perf annotate: Another fix for annotate_browser__callq() The target address is provided by objdump and is not necessary a memory address. Add a helper to get the correct address. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/r/1381747424-3557-8-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/ui/browsers/annotate.c | 7 +++++-- tools/perf/util/map.c | 31 ++++++++++++++++++++++++++++++- tools/perf/util/map.h | 3 +++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 57d3a8659fc0..f0697a3aede0 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -445,14 +445,17 @@ static bool annotate_browser__callq(struct annotate_browser *browser, struct annotation *notes; struct addr_map_symbol target = { .map = ms->map, - .addr = dl->ops.target.addr, + .addr = map__objdump_2mem(ms->map, dl->ops.target.addr), }; char title[SYM_TITLE_MAX_SIZE]; if (!ins__is_call(dl->ins)) return false; - if (map_groups__find_ams(&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; } diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 9dea404de3fa..ef5bc913ca7a 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -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; diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 0359b4a808f0..e4e259c3ba16 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -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); From d4f74eb89199dc7bde5579783e9188841e1271e3 Mon Sep 17 00:00:00 2001 From: Chenggang Qin <chenggang.qcg@taobao.com> Date: Fri, 11 Oct 2013 08:27:59 +0800 Subject: [PATCH 160/161] perf symbols: Fix a memory leak due to symbol__delete not being used In function symbols__fixup_duplicate(), while duplicated symbols are found, only the rb_node is removed from the tree. The symbol structures themself are ignored. Then, these memory areas are lost. Signed-off-by: Chenggang Qin <chenggang.qcg@taobao.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Wu Fengguang <fengguang.wu@intel.com> Cc: Yanmin Zhang <yanmin.zhang@intel.com> Link: http://lkml.kernel.org/r/1381451279-4109-3-git-send-email-chenggang.qin@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/symbol.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index b66c1eefc313..c0c36965fff0 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -160,10 +160,12 @@ again: if (choose_best_symbol(curr, next) == SYMBOL_A) { rb_erase(&next->rb_node, symbols); + symbol__delete(next); goto again; } else { nd = rb_next(&curr->rb_node); rb_erase(&curr->rb_node, symbols); + symbol__delete(curr); } } } From 784f3390f9bd900adfb3b0373615e105a0d9749a Mon Sep 17 00:00:00 2001 From: Chenggang Qin <chenggang.qcg@taobao.com> Date: Fri, 11 Oct 2013 08:27:57 +0800 Subject: [PATCH 161/161] perf symbols: Fix a mmap and munmap mismatched bug In function filename__read_debuglink(), while the ELF file is opend and mmapped in elf_begin(), but if this file is considered to not be usable during the following code, we will goto the close(fd) directly. The elf_end() is skipped. So, the mmaped ELF file cannot be munmapped. The mmapped areas exist during the life of perf. This is a memory leak. This patch fixed this bug. Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Chenggang Qin <chenggang.qcg@taobao.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Chenggang Qin <chenggang.qcg@taobao.com> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Wu Fengguang <fengguang.wu@intel.com> Cc: Yanmin Zhang <yanmin.zhang@intel.com> Link: http://lkml.kernel.org/r/1381451279-4109-1-git-send-email-chenggang.qin@gmail.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/perf/util/symbol-elf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index d6b8af3ce344..eed0b96302af 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -487,27 +487,27 @@ int filename__read_debuglink(const char *filename, char *debuglink, ek = elf_kind(elf); if (ek != ELF_K_ELF) - goto out_close; + goto out_elf_end; if (gelf_getehdr(elf, &ehdr) == NULL) { pr_err("%s: cannot get elf header.\n", __func__); - goto out_close; + goto out_elf_end; } sec = elf_section_by_name(elf, &ehdr, &shdr, ".gnu_debuglink", NULL); if (sec == NULL) - goto out_close; + goto out_elf_end; data = elf_getdata(sec, NULL); if (data == NULL) - goto out_close; + goto out_elf_end; /* the start of this section is a zero-terminated string */ strncpy(debuglink, data->d_buf, size); +out_elf_end: elf_end(elf); - out_close: close(fd); out: