forked from Minki/linux
perf/core improvements and fixes:
User visible: - Bash completion for subcommands (Yunlong Song) - Allow annotating entries in callchains in the hists browser (top/report). TODO: give some visual cue to what entries in callchains have samples and thus can be annotated and/or allow showing the source code for functions without samples (Arnaldo Carvalho de Melo) - Don't allow empty argument for '-t' in perf report, fixing segfault (Wang Nan) Infrastructure: - Prep work for moving the perf feature tests build system to tools/build (Jiri Olsa) - Fix perf-read-vdsox32 not building and lib64 install dir (H.J. Lu) - ARM64: fix building error and eh/debug frame offset cache fixes (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVCwEzAAoJEBpxZoYYoA717IIH/1Ny9ME8FkVvWnKEIXRMTG2Q HHKF9uwcl41jH8ZCbkgu06fee1aTy7nGPNK2e+hpW3df2Xpq1e/e4JCwvaAwxN1E QCpJqGxfJIpLk1xeUt541M02UXX9bE171bhFWDRjltn/8zDhDdZcOkxBkK3cMeSi rGgABOP7Rk0eOFizavKAt4XAxexTWjxYhRZ4CBe5eP+5mBWPp7UUHsogBUs6wOkr bO3dmmzmkmE0oIpViz1+cHA+CJkn0KregmRei6nUhrwFNe4yAoC0PTdkwiEvFWOV wLIF1PfA2twbk4PGqutb90fgDGdvBkO8CE0gOXltNqpgRfzNV/L8/Smi4tn6Ddc= =DSJH -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Bash completion for subcommands (Yunlong Song) - Allow annotating entries in callchains in the hists browser (top/report). TODO: give some visual cue to what entries in callchains have samples and thus can be annotated and/or allow showing the source code for functions without samples (Arnaldo Carvalho de Melo) - Don't allow empty argument for '-t' in perf report, fixing segfault (Wang Nan) Infrastructure: - Prep work for moving the perf feature tests build system to tools/build (Jiri Olsa) - Fix perf-read-vdsox32 not building and lib64 install dir (H.J. Lu) - ARM64: fix building error and eh/debug frame offset cache fixes (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
08b3f91390
@ -528,8 +528,7 @@ clean: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean config-clean
|
||||
$(Q)find . -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
|
||||
$(Q)$(RM) .config-detected
|
||||
$(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 perf-read-vdsox32
|
||||
$(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-FEATURES $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
|
||||
$(call QUIET_CLEAN, feature-detect) $(RM) $(OUTPUT)config/feature-checks/.make-*.output
|
||||
$(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex*
|
||||
$(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) clean
|
||||
$(python-clean)
|
||||
|
||||
|
@ -22,7 +22,9 @@ static const struct option data_options[] = {
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
static const char * const data_usage[] = {
|
||||
static const char * const data_subcommands[] = { "convert", NULL };
|
||||
|
||||
static const char *data_usage[] = {
|
||||
"perf data [<common options>] <command> [<options>]",
|
||||
NULL
|
||||
};
|
||||
@ -98,7 +100,7 @@ int cmd_data(int argc, const char **argv, const char *prefix)
|
||||
if (argc < 2)
|
||||
goto usage;
|
||||
|
||||
argc = parse_options(argc, argv, data_options, data_usage,
|
||||
argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
if (argc < 1)
|
||||
goto usage;
|
||||
|
@ -437,7 +437,18 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
HELP_FORMAT_INFO),
|
||||
OPT_END(),
|
||||
};
|
||||
const char * const builtin_help_usage[] = {
|
||||
const char * const builtin_help_subcommands[] = {
|
||||
"buildid-cache", "buildid-list", "diff", "evlist", "help", "list",
|
||||
"record", "report", "bench", "stat", "timechart", "top", "annotate",
|
||||
"script", "sched", "kmem", "lock", "kvm", "test", "inject", "mem", "data",
|
||||
#ifdef HAVE_LIBELF_SUPPORT
|
||||
"probe",
|
||||
#endif
|
||||
#ifdef HAVE_LIBAUDIT_SUPPORT
|
||||
"trace",
|
||||
#endif
|
||||
NULL };
|
||||
const char *builtin_help_usage[] = {
|
||||
"perf help [--all] [--man|--web|--info] [command]",
|
||||
NULL
|
||||
};
|
||||
@ -448,8 +459,8 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
|
||||
perf_config(perf_help_config, &help_format);
|
||||
|
||||
argc = parse_options(argc, argv, builtin_help_options,
|
||||
builtin_help_usage, 0);
|
||||
argc = parse_options_subcommand(argc, argv, builtin_help_options,
|
||||
builtin_help_subcommands, builtin_help_usage, 0);
|
||||
|
||||
if (show_all) {
|
||||
printf("\n usage: %s\n\n", perf_usage_string);
|
||||
|
@ -676,7 +676,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
|
||||
"width[,width...]",
|
||||
"don't try to adjust column width, use these fixed values"),
|
||||
OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
|
||||
OPT_STRING_NOEMPTY('t', "field-separator", &symbol_conf.field_sep, "separator",
|
||||
"separator for columns, no spaces will be added between "
|
||||
"columns '.' is reserved."),
|
||||
OPT_BOOLEAN('U', "hide-unresolved", &report.hide_unresolved,
|
||||
|
@ -1572,7 +1572,8 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"Show the mmap events"),
|
||||
OPT_END()
|
||||
};
|
||||
const char * const script_usage[] = {
|
||||
const char * const script_subcommands[] = { "record", "report", NULL };
|
||||
const char *script_usage[] = {
|
||||
"perf script [<options>]",
|
||||
"perf script [<options>] record <script> [<record-options>] <command>",
|
||||
"perf script [<options>] report <script> [script-args]",
|
||||
@ -1586,7 +1587,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
|
||||
setup_scripting();
|
||||
|
||||
argc = parse_options(argc, argv, options, script_usage,
|
||||
argc = parse_options_subcommand(argc, argv, options, script_subcommands, script_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
file.path = input_name;
|
||||
|
@ -1958,7 +1958,8 @@ int cmd_timechart(int argc, const char **argv,
|
||||
parse_time),
|
||||
OPT_END()
|
||||
};
|
||||
const char * const timechart_usage[] = {
|
||||
const char * const timechart_subcommands[] = { "record", NULL };
|
||||
const char *timechart_usage[] = {
|
||||
"perf timechart [<options>] {record}",
|
||||
NULL
|
||||
};
|
||||
@ -1976,8 +1977,8 @@ int cmd_timechart(int argc, const char **argv,
|
||||
"perf timechart record [<options>]",
|
||||
NULL
|
||||
};
|
||||
argc = parse_options(argc, argv, timechart_options, timechart_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
argc = parse_options_subcommand(argc, argv, timechart_options, timechart_subcommands,
|
||||
timechart_usage, PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
if (tchart.power_only && tchart.tasks_only) {
|
||||
pr_err("-P and -T options cannot be used at the same time.\n");
|
||||
|
@ -2609,7 +2609,7 @@ static void evlist__set_evsel_handler(struct perf_evlist *evlist, void *handler)
|
||||
|
||||
int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
{
|
||||
const char * const trace_usage[] = {
|
||||
const char *trace_usage[] = {
|
||||
"perf trace [<options>] [<command>]",
|
||||
"perf trace [<options>] -- <command> [<options>]",
|
||||
"perf trace record [<options>] [<command>]",
|
||||
@ -2684,6 +2684,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
|
||||
OPT_END()
|
||||
};
|
||||
const char * const trace_subcommands[] = { "record", NULL };
|
||||
int err;
|
||||
char bf[BUFSIZ];
|
||||
|
||||
@ -2699,8 +2700,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
goto out;
|
||||
}
|
||||
|
||||
argc = parse_options(argc, argv, trace_options, trace_usage,
|
||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
argc = parse_options_subcommand(argc, argv, trace_options, trace_subcommands,
|
||||
trace_usage, PARSE_OPT_STOP_AT_NON_OPTION);
|
||||
|
||||
if (trace.trace_pgfaults) {
|
||||
trace.opts.sample_address = true;
|
||||
|
@ -15,7 +15,6 @@ $(shell echo -n > .config-detected)
|
||||
detected = $(shell echo "$(1)=y" >> .config-detected)
|
||||
detected_var = $(shell echo "$(1)=$($(1))" >> .config-detected)
|
||||
|
||||
LIB_INCLUDE := $(srctree)/tools/lib/
|
||||
CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
|
||||
|
||||
include $(src-perf)/config/Makefile.arch
|
||||
@ -184,7 +183,7 @@ endif
|
||||
|
||||
feature_check = $(eval $(feature_check_code))
|
||||
define feature_check_code
|
||||
feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin > $(OUTPUT)config/feature-checks/.make-$(1).output 2>&1 && echo 1 || echo 0)
|
||||
feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C config/feature-checks test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
|
||||
endef
|
||||
|
||||
feature_set = $(eval $(feature_set_code))
|
||||
@ -204,7 +203,7 @@ endef
|
||||
# the rule that uses them - an example for that is the 'bionic'
|
||||
# feature check. ]
|
||||
#
|
||||
CORE_FEATURE_TESTS = \
|
||||
FEATURE_TESTS = \
|
||||
backtrace \
|
||||
dwarf \
|
||||
fortify-source \
|
||||
@ -227,10 +226,9 @@ CORE_FEATURE_TESTS = \
|
||||
stackprotector-all \
|
||||
timerfd \
|
||||
libdw-dwarf-unwind \
|
||||
libbabeltrace \
|
||||
zlib
|
||||
|
||||
LIB_FEATURE_TESTS = \
|
||||
FEATURE_DISPLAY = \
|
||||
dwarf \
|
||||
glibc \
|
||||
gtk2 \
|
||||
@ -243,29 +241,9 @@ LIB_FEATURE_TESTS = \
|
||||
libslang \
|
||||
libunwind \
|
||||
libdw-dwarf-unwind \
|
||||
libbabeltrace \
|
||||
zlib
|
||||
|
||||
VF_FEATURE_TESTS = \
|
||||
backtrace \
|
||||
fortify-source \
|
||||
sync-compare-and-swap \
|
||||
gtk2-infobar \
|
||||
libelf-getphdrnum \
|
||||
libelf-mmap \
|
||||
libpython-version \
|
||||
pthread-attr-setaffinity-np \
|
||||
stackprotector-all \
|
||||
timerfd \
|
||||
libunwind-debug-frame \
|
||||
bionic \
|
||||
liberty \
|
||||
liberty-z \
|
||||
cplus-demangle \
|
||||
compile-32 \
|
||||
compile-x32
|
||||
|
||||
# Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features.
|
||||
# Set FEATURE_CHECK_(C|LD)FLAGS-all for all FEATURE_TESTS features.
|
||||
# If in the future we need per-feature checks/flags for features not
|
||||
# mentioned in this list we need to refactor this ;-).
|
||||
set_test_all_flags = $(eval $(set_test_all_flags_code))
|
||||
@ -274,7 +252,7 @@ define set_test_all_flags_code
|
||||
FEATURE_CHECK_LDFLAGS-all += $(FEATURE_CHECK_LDFLAGS-$(1))
|
||||
endef
|
||||
|
||||
$(foreach feat,$(CORE_FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call set_test_all_flags,$(feat)))
|
||||
|
||||
#
|
||||
# Special fast-path for the 'all features are available' case:
|
||||
@ -289,10 +267,10 @@ ifeq ($(feature-all), 1)
|
||||
#
|
||||
# test-all.c passed - just set all the core feature flags to 1:
|
||||
#
|
||||
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_set,$(feat)))
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call feature_set,$(feat)))
|
||||
else
|
||||
$(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(CORE_FEATURE_TESTS)) >/dev/null 2>&1)
|
||||
$(foreach feat,$(CORE_FEATURE_TESTS),$(call feature_check,$(feat)))
|
||||
$(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CFLAGS="$(EXTRA_CFLAGS)" LDFLAGS=$(LDFLAGS) -i -j -C config/feature-checks $(addsuffix .bin,$(FEATURE_TESTS)) >/dev/null 2>&1)
|
||||
$(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
|
||||
endif
|
||||
|
||||
ifeq ($(feature-stackprotector-all), 1)
|
||||
@ -322,7 +300,7 @@ endif
|
||||
|
||||
CFLAGS += -I$(src-perf)/util
|
||||
CFLAGS += -I$(src-perf)
|
||||
CFLAGS += -I$(LIB_INCLUDE)
|
||||
CFLAGS += -I$(srctree)/tools/lib/
|
||||
|
||||
CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
|
||||
|
||||
@ -688,7 +666,7 @@ ifeq (${IS_64_BIT}, 1)
|
||||
NO_PERF_READ_VDSO32 := 1
|
||||
endif
|
||||
endif
|
||||
ifneq (${IS_X86_64}, 1)
|
||||
ifneq ($(ARCH), x86)
|
||||
NO_PERF_READ_VDSOX32 := 1
|
||||
endif
|
||||
ifndef NO_PERF_READ_VDSOX32
|
||||
@ -705,14 +683,15 @@ else
|
||||
endif
|
||||
|
||||
ifndef NO_LIBBABELTRACE
|
||||
ifeq ($(feature-libbabeltrace), 0)
|
||||
msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev);
|
||||
NO_LIBBABELTRACE := 1
|
||||
else
|
||||
$(call feature_check,libbabeltrace)
|
||||
ifeq ($(feature-libbabeltrace), 1)
|
||||
CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS)
|
||||
LDFLAGS += $(LIBBABELTRACE_LDFLAGS)
|
||||
EXTLIBS += -lbabeltrace-ctf
|
||||
$(call detected,CONFIG_LIBBABELTRACE)
|
||||
else
|
||||
msg := $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev);
|
||||
NO_LIBBABELTRACE := 1
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -748,7 +727,7 @@ sysconfdir = $(prefix)/etc
|
||||
ETC_PERFCONFIG = etc/perfconfig
|
||||
endif
|
||||
ifndef lib
|
||||
ifeq ($(IS_X86_64),1)
|
||||
ifeq ($(ARCH)$(IS_64_BIT), x861)
|
||||
lib = lib64
|
||||
else
|
||||
lib = lib
|
||||
@ -797,8 +776,8 @@ define feature_print_status_code
|
||||
endif
|
||||
endef
|
||||
|
||||
feature_print_var = $(eval $(feature_print_var_code)) $(info $(MSG))
|
||||
define feature_print_var_code
|
||||
print_var = $(eval $(print_var_code)) $(info $(MSG))
|
||||
define print_var_code
|
||||
MSG = $(shell printf '...%30s: %s' $(1) $($(1)))
|
||||
endef
|
||||
|
||||
@ -807,61 +786,63 @@ define feature_print_text_code
|
||||
MSG = $(shell printf '...%30s: %s' $(1) $(2))
|
||||
endef
|
||||
|
||||
PERF_FEATURES := $(foreach feat,$(LIB_FEATURE_TESTS),feature-$(feat)($(feature-$(feat))))
|
||||
PERF_FEATURES_FILE := $(shell touch $(OUTPUT)PERF-FEATURES; cat $(OUTPUT)PERF-FEATURES)
|
||||
FEATURE_DUMP := $(foreach feat,$(FEATURE_DISPLAY),feature-$(feat)($(feature-$(feat))))
|
||||
FEATURE_DUMP_FILE := $(shell touch $(OUTPUT)FEATURE-DUMP; cat $(OUTPUT)FEATURE-DUMP)
|
||||
|
||||
ifeq ($(dwarf-post-unwind),1)
|
||||
PERF_FEATURES += dwarf-post-unwind($(dwarf-post-unwind-text))
|
||||
FEATURE_DUMP += dwarf-post-unwind($(dwarf-post-unwind-text))
|
||||
endif
|
||||
|
||||
# The $(display_lib) controls the default detection message
|
||||
# The $(feature_display) controls the default detection message
|
||||
# output. It's set if:
|
||||
# - detected features differes from stored features from
|
||||
# last build (in PERF-FEATURES file)
|
||||
# - one of the $(LIB_FEATURE_TESTS) is not detected
|
||||
# last build (in FEATURE-DUMP file)
|
||||
# - one of the $(FEATURE_DISPLAY) is not detected
|
||||
# - VF is enabled
|
||||
|
||||
ifneq ("$(PERF_FEATURES)","$(PERF_FEATURES_FILE)")
|
||||
$(shell echo "$(PERF_FEATURES)" > $(OUTPUT)PERF-FEATURES)
|
||||
display_lib := 1
|
||||
ifneq ("$(FEATURE_DUMP)","$(FEATURE_DUMP_FILE)")
|
||||
$(shell echo "$(FEATURE_DUMP)" > $(OUTPUT)FEATURE-DUMP)
|
||||
feature_display := 1
|
||||
endif
|
||||
|
||||
feature_check = $(eval $(feature_check_code))
|
||||
define feature_check_code
|
||||
ifneq ($(feature-$(1)), 1)
|
||||
display_lib := 1
|
||||
feature_display := 1
|
||||
endif
|
||||
endef
|
||||
|
||||
$(foreach feat,$(LIB_FEATURE_TESTS),$(call feature_check,$(feat)))
|
||||
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_check,$(feat)))
|
||||
|
||||
ifeq ($(VF),1)
|
||||
display_lib := 1
|
||||
display_vf := 1
|
||||
feature_display := 1
|
||||
feature_verbose := 1
|
||||
endif
|
||||
|
||||
ifeq ($(display_lib),1)
|
||||
ifeq ($(feature_display),1)
|
||||
$(info )
|
||||
$(info Auto-detecting system features:)
|
||||
$(foreach feat,$(LIB_FEATURE_TESTS),$(call feature_print_status,$(feat),))
|
||||
$(foreach feat,$(FEATURE_DISPLAY),$(call feature_print_status,$(feat),))
|
||||
|
||||
ifeq ($(dwarf-post-unwind),1)
|
||||
$(call feature_print_text,"DWARF post unwind library", $(dwarf-post-unwind-text))
|
||||
endif
|
||||
|
||||
ifneq ($(feature_verbose),1)
|
||||
$(info )
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(display_vf),1)
|
||||
$(foreach feat,$(VF_FEATURE_TESTS),$(call feature_print_status,$(feat),))
|
||||
ifeq ($(feature_verbose),1)
|
||||
TMP := $(filter-out $(FEATURE_DISPLAY),$(FEATURE_TESTS))
|
||||
$(foreach feat,$(TMP),$(call feature_print_status,$(feat),))
|
||||
$(info )
|
||||
$(call feature_print_var,prefix)
|
||||
$(call feature_print_var,bindir)
|
||||
$(call feature_print_var,libdir)
|
||||
$(call feature_print_var,sysconfdir)
|
||||
$(call feature_print_var,LIBUNWIND_DIR)
|
||||
$(call feature_print_var,LIBDW_DIR)
|
||||
endif
|
||||
|
||||
ifeq ($(display_lib),1)
|
||||
$(call print_var,prefix)
|
||||
$(call print_var,bindir)
|
||||
$(call print_var,libdir)
|
||||
$(call print_var,sysconfdir)
|
||||
$(call print_var,LIBUNWIND_DIR)
|
||||
$(call print_var,LIBDW_DIR)
|
||||
$(info )
|
||||
endif
|
||||
|
||||
|
@ -4,7 +4,7 @@ endif
|
||||
|
||||
ARCH := $(shell echo $(ARCH) | sed -e s/i.86/x86/ -e s/x86_64/x86/ \
|
||||
-e s/sun4u/sparc/ -e s/sparc64/sparc/ \
|
||||
-e s/arm.*/arm/ -e s/sa110/arm/ \
|
||||
-e /arm64/!s/arm.*/arm/ -e s/sa110/arm/ \
|
||||
-e s/s390x/s390/ -e s/parisc64/parisc/ \
|
||||
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
|
||||
-e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \
|
||||
|
@ -39,12 +39,13 @@ PKG_CONFIG := $(CROSS_COMPILE)pkg-config
|
||||
|
||||
all: $(FILES)
|
||||
|
||||
BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS)
|
||||
__BUILD = $(CC) $(CFLAGS) -Wall -Werror -o $(OUTPUT)$@ $(patsubst %.bin,%.c,$@) $(LDFLAGS)
|
||||
BUILD = $(__BUILD) > $(OUTPUT)$(@:.bin=.make.output) 2>&1
|
||||
|
||||
###############################
|
||||
|
||||
test-all.bin:
|
||||
$(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -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 -lz -lbabeltrace
|
||||
$(BUILD) -fstack-protector-all -O2 -D_FORTIFY_SOURCE=2 -ldw -lelf -lnuma -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 -lz
|
||||
|
||||
test-hello.bin:
|
||||
$(BUILD)
|
||||
@ -156,4 +157,4 @@ test-zlib.bin:
|
||||
###############################
|
||||
|
||||
clean:
|
||||
rm -f $(FILES) *.d
|
||||
rm -f $(FILES) *.d $(FILES:.bin=.make.output)
|
||||
|
@ -98,12 +98,20 @@
|
||||
#undef main
|
||||
|
||||
#define main main_test_pthread_attr_setaffinity_np
|
||||
# include "test-pthread_attr_setaffinity_np.c"
|
||||
# include "test-pthread-attr-setaffinity-np.c"
|
||||
#undef main
|
||||
|
||||
# if 0
|
||||
/*
|
||||
* Disable libbabeltrace check for test-all, because the requested
|
||||
* library version is not released yet in most distributions. Will
|
||||
* reenable later.
|
||||
*/
|
||||
|
||||
#define main main_test_libbabeltrace
|
||||
# include "test-libbabeltrace.c"
|
||||
#undef main
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -130,7 +138,6 @@ int main(int argc, char *argv[])
|
||||
main_test_sync_compare_and_swap(argc, argv);
|
||||
main_test_zlib();
|
||||
main_test_pthread_attr_setaffinity_np();
|
||||
main_test_libbabeltrace();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -47,8 +47,16 @@ __my_reassemble_comp_words_by_ref()
|
||||
done
|
||||
}
|
||||
|
||||
type _get_comp_words_by_ref &>/dev/null ||
|
||||
_get_comp_words_by_ref()
|
||||
# Define preload_get_comp_words_by_ref="false", if the function
|
||||
# __perf_get_comp_words_by_ref() is required instead.
|
||||
preload_get_comp_words_by_ref="true"
|
||||
|
||||
if [ $preload_get_comp_words_by_ref = "true" ]; then
|
||||
type _get_comp_words_by_ref &>/dev/null ||
|
||||
preload_get_comp_words_by_ref="false"
|
||||
fi
|
||||
[ $preload_get_comp_words_by_ref = "true" ] ||
|
||||
__perf_get_comp_words_by_ref()
|
||||
{
|
||||
local exclude cur_ words_ cword_
|
||||
if [ "$1" = "-n" ]; then
|
||||
@ -76,8 +84,16 @@ _get_comp_words_by_ref()
|
||||
done
|
||||
}
|
||||
|
||||
type __ltrim_colon_completions &>/dev/null ||
|
||||
__ltrim_colon_completions()
|
||||
# Define preload__ltrim_colon_completions="false", if the function
|
||||
# __perf__ltrim_colon_completions() is required instead.
|
||||
preload__ltrim_colon_completions="true"
|
||||
|
||||
if [ $preload__ltrim_colon_completions = "true" ]; then
|
||||
type __ltrim_colon_completions &>/dev/null ||
|
||||
preload__ltrim_colon_completions="false"
|
||||
fi
|
||||
[ $preload__ltrim_colon_completions = "true" ] ||
|
||||
__perf__ltrim_colon_completions()
|
||||
{
|
||||
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
|
||||
# Remove colon-word prefix from COMPREPLY items
|
||||
@ -97,7 +113,32 @@ __perfcomp ()
|
||||
__perfcomp_colon ()
|
||||
{
|
||||
__perfcomp "$1" "$2"
|
||||
__ltrim_colon_completions $cur
|
||||
if [ $preload__ltrim_colon_completions = "true" ]; then
|
||||
__ltrim_colon_completions $cur
|
||||
else
|
||||
__perf__ltrim_colon_completions $cur
|
||||
fi
|
||||
}
|
||||
|
||||
__perf_prev_skip_opts ()
|
||||
{
|
||||
local i cmd_ cmds_
|
||||
|
||||
let i=cword-1
|
||||
cmds_=$($cmd $1 --list-cmds)
|
||||
prev_skip_opts=()
|
||||
while [ $i -ge 0 ]; do
|
||||
if [[ ${words[i]} == $1 ]]; then
|
||||
return
|
||||
fi
|
||||
for cmd_ in $cmds_; do
|
||||
if [[ ${words[i]} == $cmd_ ]]; then
|
||||
prev_skip_opts=${words[i]}
|
||||
return
|
||||
fi
|
||||
done
|
||||
((i--))
|
||||
done
|
||||
}
|
||||
|
||||
__perf_main ()
|
||||
@ -107,8 +148,10 @@ __perf_main ()
|
||||
cmd=${words[0]}
|
||||
COMPREPLY=()
|
||||
|
||||
# Skip options backward and find the last perf command
|
||||
__perf_prev_skip_opts
|
||||
# List perf subcommands or long options
|
||||
if [ $cword -eq 1 ]; then
|
||||
if [ -z $prev_skip_opts ]; then
|
||||
if [[ $cur == --* ]]; then
|
||||
cmds=$($cmd --list-opts)
|
||||
else
|
||||
@ -116,18 +159,25 @@ __perf_main ()
|
||||
fi
|
||||
__perfcomp "$cmds" "$cur"
|
||||
# List possible events for -e option
|
||||
elif [[ $prev == "-e" && "${words[1]}" == @(record|stat|top) ]]; then
|
||||
elif [[ $prev == @("-e"|"--event") &&
|
||||
$prev_skip_opts == @(record|stat|top) ]]; then
|
||||
evts=$($cmd list --raw-dump)
|
||||
__perfcomp_colon "$evts" "$cur"
|
||||
# List subcommands for perf commands
|
||||
elif [[ $prev == @(kvm|kmem|mem|lock|sched) ]]; then
|
||||
subcmds=$($cmd $prev --list-cmds)
|
||||
__perfcomp_colon "$subcmds" "$cur"
|
||||
# List long option names
|
||||
elif [[ $cur == --* ]]; then
|
||||
subcmd=${words[1]}
|
||||
opts=$($cmd $subcmd --list-opts)
|
||||
__perfcomp "$opts" "$cur"
|
||||
else
|
||||
# List subcommands for perf commands
|
||||
if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched|
|
||||
|data|help|script|test|timechart|trace) ]]; then
|
||||
subcmds=$($cmd $prev_skip_opts --list-cmds)
|
||||
__perfcomp_colon "$subcmds" "$cur"
|
||||
fi
|
||||
# List long option names
|
||||
if [[ $cur == --* ]]; then
|
||||
subcmd=$prev_skip_opts
|
||||
__perf_prev_skip_opts $subcmd
|
||||
subcmd=$subcmd" "$prev_skip_opts
|
||||
opts=$($cmd $subcmd --list-opts)
|
||||
__perfcomp "$opts" "$cur"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -196,7 +246,11 @@ type perf &>/dev/null &&
|
||||
_perf()
|
||||
{
|
||||
local cur words cword prev
|
||||
_get_comp_words_by_ref -n =: cur words cword prev
|
||||
if [ $preload_get_comp_words_by_ref = "true" ]; then
|
||||
_get_comp_words_by_ref -n =: cur words cword prev
|
||||
else
|
||||
__perf_get_comp_words_by_ref -n =: cur words cword prev
|
||||
fi
|
||||
__perf_main
|
||||
} &&
|
||||
|
||||
|
@ -291,7 +291,7 @@ static int perf_test__list(int argc, const char **argv)
|
||||
|
||||
int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
{
|
||||
const char * const test_usage[] = {
|
||||
const char *test_usage[] = {
|
||||
"perf test [<options>] [{list <test-name-fragment>|[<test-name-fragments>|<test-numbers>]}]",
|
||||
NULL,
|
||||
};
|
||||
@ -302,13 +302,14 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||
"be more verbose (show symbol address, etc)"),
|
||||
OPT_END()
|
||||
};
|
||||
const char * const test_subcommands[] = { "list", NULL };
|
||||
struct intlist *skiplist = NULL;
|
||||
int ret = hists__init();
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
argc = parse_options(argc, argv, test_options, test_usage, 0);
|
||||
argc = parse_options_subcommand(argc, argv, test_options, test_subcommands, test_usage, 0);
|
||||
if (argc >= 1 && !strcmp(argv[0], "list"))
|
||||
return perf_test__list(argc, argv);
|
||||
|
||||
|
@ -5,7 +5,7 @@ include config/Makefile.arch
|
||||
|
||||
# FIXME looks like x86 is the only arch running tests ;-)
|
||||
# we need some IS_(32/64) flag to make this generic
|
||||
ifeq ($(IS_X86_64),1)
|
||||
ifeq ($(ARCH)$(IS_64_BIT), x861)
|
||||
lib = lib64
|
||||
else
|
||||
lib = lib
|
||||
|
@ -829,10 +829,16 @@ out:
|
||||
return key;
|
||||
}
|
||||
|
||||
int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt)
|
||||
{
|
||||
return symbol__tui_annotate(ms->sym, ms->map, evsel, hbt);
|
||||
}
|
||||
|
||||
int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt)
|
||||
{
|
||||
return symbol__tui_annotate(he->ms.sym, he->ms.map, evsel, hbt);
|
||||
return map_symbol__tui_annotate(&he->ms, evsel, hbt);
|
||||
}
|
||||
|
||||
static void annotate_browser__mark_jump_targets(struct annotate_browser *browser,
|
||||
|
@ -1612,28 +1612,30 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
if (!sort__has_sym)
|
||||
goto add_exit_option;
|
||||
|
||||
if (browser->selection == NULL)
|
||||
goto skip_annotation;
|
||||
|
||||
if (sort__mode == SORT_MODE__BRANCH) {
|
||||
bi = browser->he_selection->branch_info;
|
||||
if (browser->selection != NULL &&
|
||||
bi &&
|
||||
bi->from.sym != NULL &&
|
||||
!bi->from.map->dso->annotate_warned &&
|
||||
asprintf(&options[nr_options], "Annotate %s",
|
||||
bi->from.sym->name) > 0)
|
||||
annotate_f = nr_options++;
|
||||
|
||||
if (browser->selection != NULL &&
|
||||
bi &&
|
||||
bi->to.sym != NULL &&
|
||||
if (bi == NULL)
|
||||
goto skip_annotation;
|
||||
|
||||
if (bi->from.sym != NULL &&
|
||||
!bi->from.map->dso->annotate_warned &&
|
||||
asprintf(&options[nr_options], "Annotate %s", bi->from.sym->name) > 0) {
|
||||
annotate_f = nr_options++;
|
||||
}
|
||||
|
||||
if (bi->to.sym != NULL &&
|
||||
!bi->to.map->dso->annotate_warned &&
|
||||
(bi->to.sym != bi->from.sym ||
|
||||
bi->to.map->dso != bi->from.map->dso) &&
|
||||
asprintf(&options[nr_options], "Annotate %s",
|
||||
bi->to.sym->name) > 0)
|
||||
asprintf(&options[nr_options], "Annotate %s", bi->to.sym->name) > 0) {
|
||||
annotate_t = nr_options++;
|
||||
}
|
||||
} else {
|
||||
if (browser->selection != NULL &&
|
||||
browser->selection->sym != NULL &&
|
||||
if (browser->selection->sym != NULL &&
|
||||
!browser->selection->map->dso->annotate_warned) {
|
||||
struct annotation *notes;
|
||||
|
||||
@ -1641,11 +1643,12 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
|
||||
|
||||
if (notes->src &&
|
||||
asprintf(&options[nr_options], "Annotate %s",
|
||||
browser->selection->sym->name) > 0)
|
||||
browser->selection->sym->name) > 0) {
|
||||
annotate = nr_options++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
skip_annotation:
|
||||
if (thread != NULL &&
|
||||
asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
|
||||
(browser->hists->thread_filter ? "out of" : "into"),
|
||||
@ -1701,6 +1704,7 @@ retry_popup_menu:
|
||||
if (choice == annotate || choice == annotate_t || choice == annotate_f) {
|
||||
struct hist_entry *he;
|
||||
struct annotation *notes;
|
||||
struct map_symbol ms;
|
||||
int err;
|
||||
do_annotate:
|
||||
if (!objdump_path && perf_session_env__lookup_objdump(env))
|
||||
@ -1710,30 +1714,21 @@ do_annotate:
|
||||
if (he == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* we stash the branch_info symbol + map into the
|
||||
* the ms so we don't have to rewrite all the annotation
|
||||
* code to use branch_info.
|
||||
* in branch mode, the ms struct is not used
|
||||
*/
|
||||
if (choice == annotate_f) {
|
||||
he->ms.sym = he->branch_info->from.sym;
|
||||
he->ms.map = he->branch_info->from.map;
|
||||
} else if (choice == annotate_t) {
|
||||
he->ms.sym = he->branch_info->to.sym;
|
||||
he->ms.map = he->branch_info->to.map;
|
||||
ms.map = he->branch_info->from.map;
|
||||
ms.sym = he->branch_info->from.sym;
|
||||
} else if (choice == annotate_t) {
|
||||
ms.map = he->branch_info->to.map;
|
||||
ms.sym = he->branch_info->to.sym;
|
||||
} else {
|
||||
ms = *browser->selection;
|
||||
}
|
||||
|
||||
notes = symbol__annotation(he->ms.sym);
|
||||
notes = symbol__annotation(ms.sym);
|
||||
if (!notes->src)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Don't let this be freed, say, by hists__decay_entry.
|
||||
*/
|
||||
he->used = true;
|
||||
err = hist_entry__tui_annotate(he, evsel, hbt);
|
||||
he->used = false;
|
||||
err = map_symbol__tui_annotate(&ms, evsel, hbt);
|
||||
/*
|
||||
* offer option to annotate the other branch source or target
|
||||
* (if they exists) when returning from annotate
|
||||
|
@ -139,7 +139,8 @@ struct dso {
|
||||
u32 status_seen;
|
||||
size_t file_size;
|
||||
struct list_head open_entry;
|
||||
u64 frame_offset;
|
||||
u64 debug_frame_offset;
|
||||
u64 eh_frame_hdr_offset;
|
||||
} data;
|
||||
|
||||
union { /* Tool specific area */
|
||||
|
@ -263,15 +263,9 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
|
||||
while (next) {
|
||||
n = rb_entry(next, struct hist_entry, rb_node);
|
||||
next = rb_next(&n->rb_node);
|
||||
/*
|
||||
* We may be annotating this, for instance, so keep it here in
|
||||
* case some it gets new samples, we'll eventually free it when
|
||||
* the user stops browsing and it agains gets fully decayed.
|
||||
*/
|
||||
if (((zap_user && n->level == '.') ||
|
||||
(zap_kernel && n->level != '.') ||
|
||||
hists__decay_entry(hists, n)) &&
|
||||
!n->used) {
|
||||
hists__decay_entry(hists, n))) {
|
||||
hists__delete_entry(hists, n);
|
||||
}
|
||||
}
|
||||
|
@ -303,6 +303,9 @@ struct hist_browser_timer {
|
||||
|
||||
#ifdef HAVE_SLANG_SUPPORT
|
||||
#include "../ui/keysyms.h"
|
||||
int map_symbol__tui_annotate(struct map_symbol *ms, struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
|
||||
int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
|
||||
struct hist_browser_timer *hbt);
|
||||
|
||||
@ -321,6 +324,12 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int map_symbol__tui_annotate(struct map_symbol *ms __maybe_unused,
|
||||
struct perf_evsel *evsel __maybe_unused,
|
||||
struct hist_browser_timer *hbt __maybe_unused)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused,
|
||||
struct perf_evsel *evsel __maybe_unused,
|
||||
|
@ -37,6 +37,7 @@ static int get_value(struct parse_opt_ctx_t *p,
|
||||
{
|
||||
const char *s, *arg = NULL;
|
||||
const int unset = flags & OPT_UNSET;
|
||||
int err;
|
||||
|
||||
if (unset && p->opt)
|
||||
return opterror(opt, "takes no value", flags);
|
||||
@ -114,13 +115,29 @@ static int get_value(struct parse_opt_ctx_t *p,
|
||||
return 0;
|
||||
|
||||
case OPTION_STRING:
|
||||
err = 0;
|
||||
if (unset)
|
||||
*(const char **)opt->value = NULL;
|
||||
else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
|
||||
*(const char **)opt->value = (const char *)opt->defval;
|
||||
else
|
||||
return get_arg(p, opt, flags, (const char **)opt->value);
|
||||
return 0;
|
||||
err = get_arg(p, opt, flags, (const char **)opt->value);
|
||||
|
||||
/* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
|
||||
if (opt->flags & PARSE_OPT_NOEMPTY) {
|
||||
const char *val = *(const char **)opt->value;
|
||||
|
||||
if (!val)
|
||||
return err;
|
||||
|
||||
/* Similar to unset if we are given an empty string. */
|
||||
if (val[0] == '\0') {
|
||||
*(const char **)opt->value = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
case OPTION_CALLBACK:
|
||||
if (unset)
|
||||
|
@ -40,6 +40,7 @@ enum parse_opt_option_flags {
|
||||
PARSE_OPT_LASTARG_DEFAULT = 16,
|
||||
PARSE_OPT_DISABLED = 32,
|
||||
PARSE_OPT_EXCLUSIVE = 64,
|
||||
PARSE_OPT_NOEMPTY = 128,
|
||||
};
|
||||
|
||||
struct option;
|
||||
@ -122,6 +123,7 @@ struct option {
|
||||
#define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
|
||||
#define OPT_U64(s, l, v, h) { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
|
||||
#define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) }
|
||||
#define OPT_STRING_NOEMPTY(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h), .flags = PARSE_OPT_NOEMPTY}
|
||||
#define OPT_DATE(s, l, v, h) \
|
||||
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
|
||||
#define OPT_CALLBACK(s, l, v, a, h, f) \
|
||||
|
@ -102,7 +102,6 @@ struct hist_entry {
|
||||
|
||||
bool init_have_children;
|
||||
char level;
|
||||
bool used;
|
||||
u8 filtered;
|
||||
char *srcline;
|
||||
struct symbol *parent;
|
||||
|
@ -266,7 +266,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
|
||||
u64 *fde_count)
|
||||
{
|
||||
int ret = -EINVAL, fd;
|
||||
u64 offset = dso->data.frame_offset;
|
||||
u64 offset = dso->data.eh_frame_hdr_offset;
|
||||
|
||||
if (offset == 0) {
|
||||
fd = dso__data_fd(dso, machine);
|
||||
@ -275,7 +275,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
|
||||
|
||||
/* Check the .eh_frame section for unwinding info */
|
||||
offset = elf_section_offset(fd, ".eh_frame_hdr");
|
||||
dso->data.frame_offset = offset;
|
||||
dso->data.eh_frame_hdr_offset = offset;
|
||||
}
|
||||
|
||||
if (offset)
|
||||
@ -291,7 +291,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
|
||||
struct machine *machine, u64 *offset)
|
||||
{
|
||||
int fd;
|
||||
u64 ofs = dso->data.frame_offset;
|
||||
u64 ofs = dso->data.debug_frame_offset;
|
||||
|
||||
if (ofs == 0) {
|
||||
fd = dso__data_fd(dso, machine);
|
||||
@ -300,7 +300,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
|
||||
|
||||
/* Check the .debug_frame section for unwinding info */
|
||||
ofs = elf_section_offset(fd, ".debug_frame");
|
||||
dso->data.frame_offset = ofs;
|
||||
dso->data.debug_frame_offset = ofs;
|
||||
}
|
||||
|
||||
*offset = ofs;
|
||||
|
Loading…
Reference in New Issue
Block a user