perf/core improvements and fixes:
perf annotate: - Allow showing offsets in more than just jump targets, use the new 'O' hotkey in the TUI, config ~/.perfconfig annotate.offset_level for it and for --stdio2 (Arnaldo Carvalho de Melo) - Use the resolved variable names from objdump disassembled lines to make them more compact, just like was already done for some instructions, like "mov", this eventually will be done more generally, but lets now add some more to the existing mechanism (Arnaldo Carvalho de Melo) perf record: - Change warning for missing topology sysfs entry to debug, as not all architectures have those files, s390 being one of those (Thomas Richter) perf sched: - Fix -g/--call-graph documentation (Takuya Yamamoto) perf stat: - Enable 1ms interval for printing event counters values in (Alexey Budankov) perf test: - Run dwarf unwind on arm32 (Kim Phillips) - Remove unused ptrace.h include from LLVM test, sidesteping older clang's lack of support for some asm constructs (Arnaldo Carvalho de Melo) perf version: - Do not print info about HAVE_LIBAUDIT_SUPPORT in 'perf version --build-options' when HAVE_SYSCALL_TABLE_SUPPORT is true, as libaudit won't be used in that case, print info about syscall_table support instead (Jin Yao) Build system: - Use HAVE_..._SUPPORT used consistently (Jin Yao) - Restore READ_ONCE() C++ compatibility in tools/include (Mark Rutland) - Give hints about package names needed to build jvmti (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEELb9bqkb7Te0zijNb1lAW81NSqkAFAlrQq1MACgkQ1lAW81NS qkCt3A/+N3Tq41g6zxvO5kIH/mnjCdZ6D1n+7qPOkBnmEPZhsyo6QCiYld3gHxaq kmOecRqKzdMx/4xDArdCXizw0iNWecAEa0vCk+A8qfEeBS9ZiditU+vqrzLhzbxr wHR1YA3oJSUeQzGmTbXgjjc2ySmfK7EJcBdP+diESXQIRkO6DfpPsxeR6UBoyGT+ gWM5GvTRxa4P6hlVv+uEsdWDvziPIL7Uk/ykKJA6s2BVScvXog2uJqfzroYlqJWG TIEobGfU7zoLVuZtuj/8E8tncQwyNSX+BgFRiZxX5gHxv4VGG1q7D4ug302Q/ctU Dkted9+lL7W1cFcNOgsFJAm5TkaczGKFezRvVMVv6T9LCJbJIddRxG5LjKWPb1Gk ok242hlFzH2a1Sas7MQKRXnhaHxjjVUTKO6Vgq24AXoWgFWVyTdNtFL8D7FBkQfZ eL0S10mgUSG5n3WnfKeomgt2BqwTMURXEIwRnMv+er2hkmeBl80K9BbKBc8KyAAX CLn2bS35S/NXyX4Cin44gBYLPdbDjg7r8WDdtstIQsmF6SvofDtTCKlVhQL9++BH lOH+hPkwuai1eOXnhUgCd0pUbO5PmcKfpd2Tv5hOR3Xr6ATL7HEZ8k24Tl6r1T7T MAfz4lv/wUoX+Gx1xpxt/6+hAau+yNs2QW5i7Szk/NCMUSx/rlw= =mR6l -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo-4.17-20180413' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent Pull tooling improvements and fixes from Arnaldo Carvalho de Melo: perf annotate fixes and improvements: - Allow showing offsets in more than just jump targets, use the new 'O' hotkey in the TUI, config ~/.perfconfig annotate.offset_level for it and for --stdio2 (Arnaldo Carvalho de Melo) - Use the resolved variable names from objdump disassembled lines to make them more compact, just like was already done for some instructions, like "mov", this eventually will be done more generally, but lets now add some more to the existing mechanism (Arnaldo Carvalho de Melo) perf record fixes: - Change warning for missing topology sysfs entry to debug, as not all architectures have those files, s390 being one of those (Thomas Richter) perf sched fixes: - Fix -g/--call-graph documentation (Takuya Yamamoto) perf stat: - Enable 1ms interval for printing event counters values in (Alexey Budankov) perf test fixes: - Run dwarf unwind on arm32 (Kim Phillips) - Remove unused ptrace.h include from LLVM test, sidesteping older clang's lack of support for some asm constructs (Arnaldo Carvalho de Melo) perf version fixes: - Do not print info about HAVE_LIBAUDIT_SUPPORT in 'perf version --build-options' when HAVE_SYSCALL_TABLE_SUPPORT is true, as libaudit won't be used in that case, print info about syscall_table support instead (Jin Yao) Build system fixes: - Use HAVE_..._SUPPORT used consistently (Jin Yao) - Restore READ_ONCE() C++ compatibility in tools/include (Mark Rutland) - Give hints about package names needed to build jvmti (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
commit
aacd188a2d
|
@ -136,7 +136,6 @@
|
|||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifndef __BPF__
|
||||
/*
|
||||
* This output constraint should be used for any inline asm which has a "call"
|
||||
* instruction. Otherwise the asm may be inserted before the frame pointer
|
||||
|
@ -146,6 +145,5 @@
|
|||
register unsigned long current_stack_pointer asm(_ASM_SP);
|
||||
#define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_ASM_H */
|
||||
|
|
|
@ -151,11 +151,21 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
|
|||
* required ordering.
|
||||
*/
|
||||
|
||||
#define READ_ONCE(x) \
|
||||
({ union { typeof(x) __val; char __c[1]; } __u; __read_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
union { typeof(x) __val; char __c[1]; } __u = \
|
||||
{ .__c = { 0 } }; \
|
||||
__read_once_size(&(x), __u.__c, sizeof(x)); \
|
||||
__u.__val; \
|
||||
})
|
||||
|
||||
#define WRITE_ONCE(x, val) \
|
||||
({ union { typeof(x) __val; char __c[1]; } __u = { .__val = (val) }; __write_once_size(&(x), __u.__c, sizeof(x)); __u.__val; })
|
||||
#define WRITE_ONCE(x, val) \
|
||||
({ \
|
||||
union { typeof(x) __val; char __c[1]; } __u = \
|
||||
{ .__val = (val) }; \
|
||||
__write_once_size(&(x), __u.__c, sizeof(x)); \
|
||||
__u.__val; \
|
||||
})
|
||||
|
||||
|
||||
#ifndef __fallthrough
|
||||
|
|
|
@ -334,6 +334,11 @@ annotate.*::
|
|||
|
||||
99.93 │ mov %eax,%eax
|
||||
|
||||
annotate.offset_level::
|
||||
Default is '1', meaning just jump targets will have offsets show right beside
|
||||
the instruction. When set to '2' 'call' instructions will also have its offsets
|
||||
shown, 3 or higher will show offsets for all instructions.
|
||||
|
||||
hist.*::
|
||||
hist.percentage::
|
||||
This option control the way to calculate overhead of filtered entries -
|
||||
|
|
|
@ -104,8 +104,8 @@ OPTIONS for 'perf sched timehist'
|
|||
kallsyms pathname
|
||||
|
||||
-g::
|
||||
--no-call-graph::
|
||||
Do not display call chains if present.
|
||||
--call-graph::
|
||||
Display call chains if present (default on).
|
||||
|
||||
--max-stack::
|
||||
Maximum number of functions to display in backtrace, default 5.
|
||||
|
|
|
@ -153,7 +153,7 @@ perf stat --repeat 10 --null --sync --pre 'make -s O=defconfig-build/clean' -- m
|
|||
|
||||
-I msecs::
|
||||
--interval-print msecs::
|
||||
Print count deltas every N milliseconds (minimum: 10ms)
|
||||
Print count deltas every N milliseconds (minimum: 1ms)
|
||||
The overhead percentage could be high in some cases, for instance with small, sub 100ms intervals. Use with caution.
|
||||
example: 'perf stat -I 1000 -e cycles -a sleep 5'
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ ifeq ($(NO_PERF_REGS),0)
|
|||
endif
|
||||
|
||||
ifneq ($(NO_SYSCALL_TABLE),1)
|
||||
CFLAGS += -DHAVE_SYSCALL_TABLE
|
||||
CFLAGS += -DHAVE_SYSCALL_TABLE_SUPPORT
|
||||
endif
|
||||
|
||||
# So far there's only x86 and arm libdw unwind support merged in perf.
|
||||
|
@ -847,7 +847,7 @@ ifndef NO_JVMTI
|
|||
ifeq ($(feature-jvmti), 1)
|
||||
$(call detected_var,JDIR)
|
||||
else
|
||||
$(warning No openjdk development package found, please install JDK package)
|
||||
$(warning No openjdk development package found, please install JDK package, e.g. openjdk-8-jdk, java-1.8.0-openjdk-devel)
|
||||
NO_JVMTI := 1
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef ARCH_TESTS_H
|
||||
#define ARCH_TESTS_H
|
||||
|
||||
#ifdef HAVE_DWARF_UNWIND_SUPPORT
|
||||
struct thread;
|
||||
struct perf_sample;
|
||||
#endif
|
||||
|
||||
extern struct test arch_tests[];
|
||||
|
||||
#endif
|
|
@ -1,2 +1,4 @@
|
|||
libperf-y += regs_load.o
|
||||
libperf-y += dwarf-unwind.o
|
||||
|
||||
libperf-y += arch-tests.o
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <string.h>
|
||||
#include "tests/tests.h"
|
||||
#include "arch-tests.h"
|
||||
|
||||
struct test arch_tests[] = {
|
||||
#ifdef HAVE_DWARF_UNWIND_SUPPORT
|
||||
{
|
||||
.desc = "DWARF unwind",
|
||||
.func = test__dwarf_unwind,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.func = NULL,
|
||||
},
|
||||
};
|
|
@ -1,21 +1,43 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
static struct ins x86__instructions[] = {
|
||||
{ .name = "adc", .ops = &mov_ops, },
|
||||
{ .name = "adcb", .ops = &mov_ops, },
|
||||
{ .name = "adcl", .ops = &mov_ops, },
|
||||
{ .name = "add", .ops = &mov_ops, },
|
||||
{ .name = "addl", .ops = &mov_ops, },
|
||||
{ .name = "addq", .ops = &mov_ops, },
|
||||
{ .name = "addsd", .ops = &mov_ops, },
|
||||
{ .name = "addw", .ops = &mov_ops, },
|
||||
{ .name = "and", .ops = &mov_ops, },
|
||||
{ .name = "andb", .ops = &mov_ops, },
|
||||
{ .name = "andl", .ops = &mov_ops, },
|
||||
{ .name = "andpd", .ops = &mov_ops, },
|
||||
{ .name = "andps", .ops = &mov_ops, },
|
||||
{ .name = "andq", .ops = &mov_ops, },
|
||||
{ .name = "andw", .ops = &mov_ops, },
|
||||
{ .name = "bsr", .ops = &mov_ops, },
|
||||
{ .name = "bt", .ops = &mov_ops, },
|
||||
{ .name = "btr", .ops = &mov_ops, },
|
||||
{ .name = "bts", .ops = &mov_ops, },
|
||||
{ .name = "btsq", .ops = &mov_ops, },
|
||||
{ .name = "call", .ops = &call_ops, },
|
||||
{ .name = "callq", .ops = &call_ops, },
|
||||
{ .name = "cmovbe", .ops = &mov_ops, },
|
||||
{ .name = "cmove", .ops = &mov_ops, },
|
||||
{ .name = "cmovae", .ops = &mov_ops, },
|
||||
{ .name = "cmp", .ops = &mov_ops, },
|
||||
{ .name = "cmpb", .ops = &mov_ops, },
|
||||
{ .name = "cmpl", .ops = &mov_ops, },
|
||||
{ .name = "cmpq", .ops = &mov_ops, },
|
||||
{ .name = "cmpw", .ops = &mov_ops, },
|
||||
{ .name = "cmpxch", .ops = &mov_ops, },
|
||||
{ .name = "cmpxchg", .ops = &mov_ops, },
|
||||
{ .name = "cs", .ops = &mov_ops, },
|
||||
{ .name = "dec", .ops = &dec_ops, },
|
||||
{ .name = "decl", .ops = &dec_ops, },
|
||||
{ .name = "divsd", .ops = &mov_ops, },
|
||||
{ .name = "divss", .ops = &mov_ops, },
|
||||
{ .name = "gs", .ops = &mov_ops, },
|
||||
{ .name = "imul", .ops = &mov_ops, },
|
||||
{ .name = "inc", .ops = &dec_ops, },
|
||||
{ .name = "incl", .ops = &dec_ops, },
|
||||
|
@ -57,25 +79,68 @@ static struct ins x86__instructions[] = {
|
|||
{ .name = "lea", .ops = &mov_ops, },
|
||||
{ .name = "lock", .ops = &lock_ops, },
|
||||
{ .name = "mov", .ops = &mov_ops, },
|
||||
{ .name = "movapd", .ops = &mov_ops, },
|
||||
{ .name = "movaps", .ops = &mov_ops, },
|
||||
{ .name = "movb", .ops = &mov_ops, },
|
||||
{ .name = "movdqa", .ops = &mov_ops, },
|
||||
{ .name = "movdqu", .ops = &mov_ops, },
|
||||
{ .name = "movl", .ops = &mov_ops, },
|
||||
{ .name = "movq", .ops = &mov_ops, },
|
||||
{ .name = "movsd", .ops = &mov_ops, },
|
||||
{ .name = "movslq", .ops = &mov_ops, },
|
||||
{ .name = "movss", .ops = &mov_ops, },
|
||||
{ .name = "movupd", .ops = &mov_ops, },
|
||||
{ .name = "movups", .ops = &mov_ops, },
|
||||
{ .name = "movw", .ops = &mov_ops, },
|
||||
{ .name = "movzbl", .ops = &mov_ops, },
|
||||
{ .name = "movzwl", .ops = &mov_ops, },
|
||||
{ .name = "mulsd", .ops = &mov_ops, },
|
||||
{ .name = "mulss", .ops = &mov_ops, },
|
||||
{ .name = "nop", .ops = &nop_ops, },
|
||||
{ .name = "nopl", .ops = &nop_ops, },
|
||||
{ .name = "nopw", .ops = &nop_ops, },
|
||||
{ .name = "or", .ops = &mov_ops, },
|
||||
{ .name = "orb", .ops = &mov_ops, },
|
||||
{ .name = "orl", .ops = &mov_ops, },
|
||||
{ .name = "orps", .ops = &mov_ops, },
|
||||
{ .name = "orq", .ops = &mov_ops, },
|
||||
{ .name = "pand", .ops = &mov_ops, },
|
||||
{ .name = "paddq", .ops = &mov_ops, },
|
||||
{ .name = "pcmpeqb", .ops = &mov_ops, },
|
||||
{ .name = "por", .ops = &mov_ops, },
|
||||
{ .name = "rclb", .ops = &mov_ops, },
|
||||
{ .name = "rcll", .ops = &mov_ops, },
|
||||
{ .name = "retq", .ops = &ret_ops, },
|
||||
{ .name = "sbb", .ops = &mov_ops, },
|
||||
{ .name = "sbbl", .ops = &mov_ops, },
|
||||
{ .name = "sete", .ops = &mov_ops, },
|
||||
{ .name = "sub", .ops = &mov_ops, },
|
||||
{ .name = "subl", .ops = &mov_ops, },
|
||||
{ .name = "subq", .ops = &mov_ops, },
|
||||
{ .name = "subsd", .ops = &mov_ops, },
|
||||
{ .name = "subw", .ops = &mov_ops, },
|
||||
{ .name = "test", .ops = &mov_ops, },
|
||||
{ .name = "testb", .ops = &mov_ops, },
|
||||
{ .name = "testl", .ops = &mov_ops, },
|
||||
{ .name = "ucomisd", .ops = &mov_ops, },
|
||||
{ .name = "ucomiss", .ops = &mov_ops, },
|
||||
{ .name = "vaddsd", .ops = &mov_ops, },
|
||||
{ .name = "vandpd", .ops = &mov_ops, },
|
||||
{ .name = "vmovdqa", .ops = &mov_ops, },
|
||||
{ .name = "vmovq", .ops = &mov_ops, },
|
||||
{ .name = "vmovsd", .ops = &mov_ops, },
|
||||
{ .name = "vmulsd", .ops = &mov_ops, },
|
||||
{ .name = "vorpd", .ops = &mov_ops, },
|
||||
{ .name = "vsubsd", .ops = &mov_ops, },
|
||||
{ .name = "vucomisd", .ops = &mov_ops, },
|
||||
{ .name = "xadd", .ops = &mov_ops, },
|
||||
{ .name = "xbeginl", .ops = &jump_ops, },
|
||||
{ .name = "xbeginq", .ops = &jump_ops, },
|
||||
{ .name = "retq", .ops = &ret_ops, },
|
||||
{ .name = "xchg", .ops = &mov_ops, },
|
||||
{ .name = "xor", .ops = &mov_ops, },
|
||||
{ .name = "xorb", .ops = &mov_ops, },
|
||||
{ .name = "xorpd", .ops = &mov_ops, },
|
||||
{ .name = "xorps", .ops = &mov_ops, },
|
||||
};
|
||||
|
||||
static bool x86__ins_is_fused(struct arch *arch, const char *ins1,
|
||||
|
|
|
@ -439,7 +439,7 @@ int cmd_help(int argc, const char **argv)
|
|||
#ifdef HAVE_LIBELF_SUPPORT
|
||||
"probe",
|
||||
#endif
|
||||
#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
|
||||
#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
|
||||
"trace",
|
||||
#endif
|
||||
NULL };
|
||||
|
|
|
@ -2801,11 +2801,11 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
|
|||
for_each_lang(scripts_path, scripts_dir, lang_dirent) {
|
||||
scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path,
|
||||
lang_dirent->d_name);
|
||||
#ifdef NO_LIBPERL
|
||||
#ifndef HAVE_LIBPERL_SUPPORT
|
||||
if (strstr(lang_path, "perl"))
|
||||
continue;
|
||||
#endif
|
||||
#ifdef NO_LIBPYTHON
|
||||
#ifndef HAVE_LIBPYTHON_SUPPORT
|
||||
if (strstr(lang_path, "python"))
|
||||
continue;
|
||||
#endif
|
||||
|
|
|
@ -1943,7 +1943,8 @@ static const struct option stat_options[] = {
|
|||
OPT_STRING(0, "post", &post_cmd, "command",
|
||||
"command to run after to the measured command"),
|
||||
OPT_UINTEGER('I', "interval-print", &stat_config.interval,
|
||||
"print counts at regular interval in ms (>= 10)"),
|
||||
"print counts at regular interval in ms "
|
||||
"(overhead is possible for values <= 100ms)"),
|
||||
OPT_INTEGER(0, "interval-count", &stat_config.times,
|
||||
"print counts for fixed number of times"),
|
||||
OPT_UINTEGER(0, "timeout", &stat_config.timeout,
|
||||
|
@ -2923,17 +2924,6 @@ int cmd_stat(int argc, const char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (interval && interval < 100) {
|
||||
if (interval < 10) {
|
||||
pr_err("print interval must be >= 10ms\n");
|
||||
parse_options_usage(stat_usage, stat_options, "I", 1);
|
||||
goto out;
|
||||
} else
|
||||
pr_warning("print interval < 100ms. "
|
||||
"The overhead percentage could be high in some cases. "
|
||||
"Please proceed with caution.\n");
|
||||
}
|
||||
|
||||
if (stat_config.times && interval)
|
||||
interval_count = true;
|
||||
else if (stat_config.times && !interval) {
|
||||
|
|
|
@ -60,7 +60,10 @@ static void library_status(void)
|
|||
STATUS(HAVE_DWARF_GETLOCATIONS_SUPPORT, dwarf_getlocations);
|
||||
STATUS(HAVE_GLIBC_SUPPORT, glibc);
|
||||
STATUS(HAVE_GTK2_SUPPORT, gtk2);
|
||||
#ifndef HAVE_SYSCALL_TABLE_SUPPORT
|
||||
STATUS(HAVE_LIBAUDIT_SUPPORT, libaudit);
|
||||
#endif
|
||||
STATUS(HAVE_SYSCALL_TABLE_SUPPORT, syscall_table);
|
||||
STATUS(HAVE_LIBBFD_SUPPORT, libbfd);
|
||||
STATUS(HAVE_LIBELF_SUPPORT, libelf);
|
||||
STATUS(HAVE_LIBNUMA_SUPPORT, libnuma);
|
||||
|
|
|
@ -73,7 +73,7 @@ static struct cmd_struct commands[] = {
|
|||
{ "lock", cmd_lock, 0 },
|
||||
{ "kvm", cmd_kvm, 0 },
|
||||
{ "test", cmd_test, 0 },
|
||||
#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
|
||||
#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
|
||||
{ "trace", cmd_trace, 0 },
|
||||
#endif
|
||||
{ "inject", cmd_inject, 0 },
|
||||
|
@ -491,7 +491,7 @@ int main(int argc, const char **argv)
|
|||
argv[0] = cmd;
|
||||
}
|
||||
if (strstarts(cmd, "trace")) {
|
||||
#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)
|
||||
#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)
|
||||
setup_path();
|
||||
argv[0] = "trace";
|
||||
return cmd_trace(argc, argv);
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#define SEC(NAME) __attribute__((section(NAME), used))
|
||||
|
||||
#include <uapi/linux/fs.h>
|
||||
#include <uapi/asm/ptrace.h>
|
||||
|
||||
SEC("func=vfs_llseek")
|
||||
int bpf_func__vfs_llseek(void *ctx)
|
||||
|
|
|
@ -118,6 +118,7 @@ static struct test generic_tests[] = {
|
|||
{
|
||||
.desc = "Breakpoint accounting",
|
||||
.func = test__bp_accounting,
|
||||
.is_supported = test__bp_signal_is_supported,
|
||||
},
|
||||
{
|
||||
.desc = "Number of exit events of a simple workload",
|
||||
|
|
|
@ -692,6 +692,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
|
|||
"J Toggle showing number of jump sources on targets\n"
|
||||
"n Search next string\n"
|
||||
"o Toggle disassembler output/simplified view\n"
|
||||
"O Bump offset level (jump targets -> +call -> all -> cycle thru)\n"
|
||||
"s Toggle source code view\n"
|
||||
"t Circulate percent, total period, samples view\n"
|
||||
"/ Search string\n"
|
||||
|
@ -719,6 +720,10 @@ static int annotate_browser__run(struct annotate_browser *browser,
|
|||
notes->options->use_offset = !notes->options->use_offset;
|
||||
annotation__update_column_widths(notes);
|
||||
continue;
|
||||
case 'O':
|
||||
if (++notes->options->offset_level > ANNOTATION__MAX_OFFSET_LEVEL)
|
||||
notes->options->offset_level = ANNOTATION__MIN_OFFSET_LEVEL;
|
||||
continue;
|
||||
case 'j':
|
||||
notes->options->jump_arrows = !notes->options->jump_arrows;
|
||||
continue;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
struct annotation_options annotation__default_options = {
|
||||
.use_offset = true,
|
||||
.jump_arrows = true,
|
||||
.offset_level = ANNOTATION__OFFSET_JUMP_TARGETS,
|
||||
};
|
||||
|
||||
const char *disassembler_style;
|
||||
|
@ -2512,7 +2513,8 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
|
|||
if (!notes->options->use_offset) {
|
||||
printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
|
||||
} else {
|
||||
if (al->jump_sources) {
|
||||
if (al->jump_sources &&
|
||||
notes->options->offset_level >= ANNOTATION__OFFSET_JUMP_TARGETS) {
|
||||
if (notes->options->show_nr_jumps) {
|
||||
int prev;
|
||||
printed = scnprintf(bf, sizeof(bf), "%*d ",
|
||||
|
@ -2523,9 +2525,14 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
|
|||
obj__printf(obj, bf);
|
||||
obj__set_color(obj, prev);
|
||||
}
|
||||
|
||||
print_addr:
|
||||
printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
|
||||
notes->widths.target, addr);
|
||||
} else if (ins__is_call(&disasm_line(al)->ins) &&
|
||||
notes->options->offset_level >= ANNOTATION__OFFSET_CALL) {
|
||||
goto print_addr;
|
||||
} else if (notes->options->offset_level == ANNOTATION__MAX_OFFSET_LEVEL) {
|
||||
goto print_addr;
|
||||
} else {
|
||||
printed = scnprintf(bf, sizeof(bf), "%-*s ",
|
||||
notes->widths.addr, " ");
|
||||
|
@ -2642,10 +2649,11 @@ int __annotation__scnprintf_samples_period(struct annotation *notes,
|
|||
*/
|
||||
static struct annotation_config {
|
||||
const char *name;
|
||||
bool *value;
|
||||
void *value;
|
||||
} annotation__configs[] = {
|
||||
ANNOTATION__CFG(hide_src_code),
|
||||
ANNOTATION__CFG(jump_arrows),
|
||||
ANNOTATION__CFG(offset_level),
|
||||
ANNOTATION__CFG(show_linenr),
|
||||
ANNOTATION__CFG(show_nr_jumps),
|
||||
ANNOTATION__CFG(show_nr_samples),
|
||||
|
@ -2677,8 +2685,16 @@ static int annotation__config(const char *var, const char *value,
|
|||
|
||||
if (cfg == NULL)
|
||||
pr_debug("%s variable unknown, ignoring...", var);
|
||||
else
|
||||
*cfg->value = perf_config_bool(name, value);
|
||||
else if (strcmp(var, "annotate.offset_level") == 0) {
|
||||
perf_config_int(cfg->value, name, value);
|
||||
|
||||
if (*(int *)cfg->value > ANNOTATION__MAX_OFFSET_LEVEL)
|
||||
*(int *)cfg->value = ANNOTATION__MAX_OFFSET_LEVEL;
|
||||
else if (*(int *)cfg->value < ANNOTATION__MIN_OFFSET_LEVEL)
|
||||
*(int *)cfg->value = ANNOTATION__MIN_OFFSET_LEVEL;
|
||||
} else {
|
||||
*(bool *)cfg->value = perf_config_bool(name, value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,8 +70,17 @@ struct annotation_options {
|
|||
show_nr_jumps,
|
||||
show_nr_samples,
|
||||
show_total_period;
|
||||
u8 offset_level;
|
||||
};
|
||||
|
||||
enum {
|
||||
ANNOTATION__OFFSET_JUMP_TARGETS = 1,
|
||||
ANNOTATION__OFFSET_CALL,
|
||||
ANNOTATION__MAX_OFFSET_LEVEL,
|
||||
};
|
||||
|
||||
#define ANNOTATION__MIN_OFFSET_LEVEL ANNOTATION__OFFSET_JUMP_TARGETS
|
||||
|
||||
extern struct annotation_options annotation__default_options;
|
||||
|
||||
struct annotation;
|
||||
|
|
|
@ -38,7 +38,7 @@ do
|
|||
done
|
||||
echo "#endif /* HAVE_LIBELF_SUPPORT */"
|
||||
|
||||
echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE)"
|
||||
echo "#if defined(HAVE_LIBAUDIT_SUPPORT) || defined(HAVE_SYSCALL_TABLE_SUPPORT)"
|
||||
sed -n -e 's/^perf-\([^ ]*\)[ ].* audit*/\1/p' command-list.txt |
|
||||
sort |
|
||||
while read cmd
|
||||
|
|
|
@ -1320,7 +1320,8 @@ static int build_mem_topology(struct memory_node *nodes, u64 size, u64 *cntp)
|
|||
|
||||
dir = opendir(path);
|
||||
if (!dir) {
|
||||
pr_warning("failed: can't open node sysfs data\n");
|
||||
pr_debug2("%s: could't read %s, does this arch have topology information?\n",
|
||||
__func__, path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -2091,16 +2091,14 @@ static bool symbol__read_kptr_restrict(void)
|
|||
|
||||
int symbol__annotation_init(void)
|
||||
{
|
||||
if (symbol_conf.init_annotation)
|
||||
return 0;
|
||||
|
||||
if (symbol_conf.initialized) {
|
||||
pr_err("Annotation needs to be init before symbol__init()\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (symbol_conf.init_annotation) {
|
||||
pr_warning("Annotation being initialized multiple times\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
symbol_conf.priv_size += sizeof(struct annotation);
|
||||
symbol_conf.init_annotation = true;
|
||||
return 0;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifdef HAVE_SYSCALL_TABLE
|
||||
#ifdef HAVE_SYSCALL_TABLE_SUPPORT
|
||||
#include <string.h>
|
||||
#include "string2.h"
|
||||
#include "util.h"
|
||||
|
@ -139,7 +139,7 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
|
|||
return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
|
||||
}
|
||||
|
||||
#else /* HAVE_SYSCALL_TABLE */
|
||||
#else /* HAVE_SYSCALL_TABLE_SUPPORT */
|
||||
|
||||
#include <libaudit.h>
|
||||
|
||||
|
@ -176,4 +176,4 @@ int syscalltbl__strglobmatch_first(struct syscalltbl *tbl, const char *syscall_g
|
|||
{
|
||||
return syscalltbl__strglobmatch_next(tbl, syscall_glob, idx);
|
||||
}
|
||||
#endif /* HAVE_SYSCALL_TABLE */
|
||||
#endif /* HAVE_SYSCALL_TABLE_SUPPORT */
|
||||
|
|
|
@ -98,7 +98,7 @@ static void register_python_scripting(struct scripting_ops *scripting_ops)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NO_LIBPYTHON
|
||||
#ifndef HAVE_LIBPYTHON_SUPPORT
|
||||
void setup_python_scripting(void)
|
||||
{
|
||||
register_python_scripting(&python_scripting_unsupported_ops);
|
||||
|
@ -161,7 +161,7 @@ static void register_perl_scripting(struct scripting_ops *scripting_ops)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef NO_LIBPERL
|
||||
#ifndef HAVE_LIBPERL_SUPPORT
|
||||
void setup_perl_scripting(void)
|
||||
{
|
||||
register_perl_scripting(&perl_scripting_unsupported_ops);
|
||||
|
|
Loading…
Reference in New Issue