diff options
Diffstat (limited to 'tools/perf/arch/x86')
-rw-r--r-- | tools/perf/arch/x86/annotate/instructions.c | 28 | ||||
-rw-r--r-- | tools/perf/arch/x86/entry/syscalls/syscall_64.tbl | 1 | ||||
-rw-r--r-- | tools/perf/arch/x86/include/arch-tests.h | 14 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/arch-tests.c | 47 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/bp-modify.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/insn-x86.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/intel-cqm.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/rdpmc.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/tests/sample-parsing.c | 2 | ||||
-rw-r--r-- | tools/perf/arch/x86/util/evsel.c | 23 | ||||
-rw-r--r-- | tools/perf/arch/x86/util/iostat.c | 2 |
12 files changed, 83 insertions, 44 deletions
diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/x86/annotate/instructions.c index 24ea12ec7e02..305872692bfd 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -144,9 +144,32 @@ static struct ins x86__instructions[] = { { .name = "xorps", .ops = &mov_ops, }, }; -static bool x86__ins_is_fused(struct arch *arch, const char *ins1, +static bool amd__ins_is_fused(struct arch *arch, const char *ins1, const char *ins2) { + if (strstr(ins2, "jmp")) + return false; + + /* Family >= 15h supports cmp/test + branch fusion */ + if (arch->family >= 0x15 && (strstarts(ins1, "test") || + (strstarts(ins1, "cmp") && !strstr(ins1, "xchg")))) { + return true; + } + + /* Family >= 19h supports some ALU + branch fusion */ + if (arch->family >= 0x19 && (strstarts(ins1, "add") || + strstarts(ins1, "sub") || strstarts(ins1, "and") || + strstarts(ins1, "inc") || strstarts(ins1, "dec") || + strstarts(ins1, "or") || strstarts(ins1, "xor"))) { + return true; + } + + return false; +} + +static bool intel__ins_is_fused(struct arch *arch, const char *ins1, + const char *ins2) +{ if (arch->family != 6 || arch->model < 0x1e || strstr(ins2, "jmp")) return false; @@ -184,6 +207,9 @@ static int x86__cpuid_parse(struct arch *arch, char *cpuid) if (ret == 3) { arch->family = family; arch->model = model; + arch->ins_is_fused = strstarts(cpuid, "AuthenticAMD") ? + amd__ins_is_fused : + intel__ins_is_fused; return 0; } diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index 18b5500ea8bf..fe8f8dd157b4 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -370,6 +370,7 @@ 446 common landlock_restrict_self sys_landlock_restrict_self 447 common memfd_secret sys_memfd_secret 448 common process_mrelease sys_process_mrelease +449 common futex_waitv sys_futex_waitv # # Due to a historical design error, certain syscalls are numbered differently diff --git a/tools/perf/arch/x86/include/arch-tests.h b/tools/perf/arch/x86/include/arch-tests.h index 9599e7a3f1af..6a1a1b3c0827 100644 --- a/tools/perf/arch/x86/include/arch-tests.h +++ b/tools/perf/arch/x86/include/arch-tests.h @@ -2,15 +2,15 @@ #ifndef ARCH_TESTS_H #define ARCH_TESTS_H -struct test; +struct test_suite; /* Tests */ -int test__rdpmc(struct test *test, int subtest); -int test__insn_x86(struct test *test, int subtest); -int test__intel_pt_pkt_decoder(struct test *test, int subtest); -int test__bp_modify(struct test *test, int subtest); -int test__x86_sample_parsing(struct test *test, int subtest); +int test__rdpmc(struct test_suite *test, int subtest); +int test__insn_x86(struct test_suite *test, int subtest); +int test__intel_pt_pkt_decoder(struct test_suite *test, int subtest); +int test__bp_modify(struct test_suite *test, int subtest); +int test__x86_sample_parsing(struct test_suite *test, int subtest); -extern struct test arch_tests[]; +extern struct test_suite *arch_tests[]; #endif diff --git a/tools/perf/arch/x86/tests/arch-tests.c b/tools/perf/arch/x86/tests/arch-tests.c index 71aa67367ad6..64fb73d14d2f 100644 --- a/tools/perf/arch/x86/tests/arch-tests.c +++ b/tools/perf/arch/x86/tests/arch-tests.c @@ -3,39 +3,28 @@ #include "tests/tests.h" #include "arch-tests.h" -struct test arch_tests[] = { - { - .desc = "x86 rdpmc", - .func = test__rdpmc, - }, +DEFINE_SUITE("x86 rdpmc", rdpmc); +#ifdef HAVE_AUXTRACE_SUPPORT +DEFINE_SUITE("x86 instruction decoder - new instructions", insn_x86); +DEFINE_SUITE("Intel PT packet decoder", intel_pt_pkt_decoder); +#endif +#if defined(__x86_64__) +DEFINE_SUITE("x86 bp modify", bp_modify); +#endif +DEFINE_SUITE("x86 Sample parsing", x86_sample_parsing); + +struct test_suite *arch_tests[] = { + &suite__rdpmc, #ifdef HAVE_DWARF_UNWIND_SUPPORT - { - .desc = "DWARF unwind", - .func = test__dwarf_unwind, - }, + &suite__dwarf_unwind, #endif #ifdef HAVE_AUXTRACE_SUPPORT - { - .desc = "x86 instruction decoder - new instructions", - .func = test__insn_x86, - }, - { - .desc = "Intel PT packet decoder", - .func = test__intel_pt_pkt_decoder, - }, + &suite__insn_x86, + &suite__intel_pt_pkt_decoder, #endif #if defined(__x86_64__) - { - .desc = "x86 bp modify", - .func = test__bp_modify, - }, + &suite__bp_modify, #endif - { - .desc = "x86 Sample parsing", - .func = test__x86_sample_parsing, - }, - { - .func = NULL, - }, - + &suite__x86_sample_parsing, + NULL, }; diff --git a/tools/perf/arch/x86/tests/bp-modify.c b/tools/perf/arch/x86/tests/bp-modify.c index dffcf9b52153..0924ccd9e36d 100644 --- a/tools/perf/arch/x86/tests/bp-modify.c +++ b/tools/perf/arch/x86/tests/bp-modify.c @@ -204,7 +204,7 @@ out: return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; } -int test__bp_modify(struct test *test __maybe_unused, +int test__bp_modify(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { TEST_ASSERT_VAL("modify test 1 failed\n", !bp_modify1()); diff --git a/tools/perf/arch/x86/tests/insn-x86.c b/tools/perf/arch/x86/tests/insn-x86.c index 0262b0d8ccf5..94b490c434d0 100644 --- a/tools/perf/arch/x86/tests/insn-x86.c +++ b/tools/perf/arch/x86/tests/insn-x86.c @@ -173,7 +173,7 @@ static int test_data_set(struct test_data *dat_set, int x86_64) * verbose (-v) option to see all the instructions and whether or not they * decoded successfully. */ -int test__insn_x86(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__insn_x86(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int ret = 0; diff --git a/tools/perf/arch/x86/tests/intel-cqm.c b/tools/perf/arch/x86/tests/intel-cqm.c index 27dd8cf9e060..cb5b2c6c3b3b 100644 --- a/tools/perf/arch/x86/tests/intel-cqm.c +++ b/tools/perf/arch/x86/tests/intel-cqm.c @@ -37,7 +37,7 @@ static pid_t spawn(void) * the last read counter value to avoid triggering a WARN_ON_ONCE() in * smp_call_function_many() caused by sending IPIs from NMI context. */ -int test__intel_cqm_count_nmi_context(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__intel_cqm_count_nmi_context(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct evlist *evlist = NULL; struct evsel *evsel = NULL; diff --git a/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c b/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c index c933e3dcd0a8..2fc882ab24c1 100644 --- a/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c +++ b/tools/perf/arch/x86/tests/intel-pt-pkt-decoder-test.c @@ -289,7 +289,7 @@ static int test_one(struct test_data *d) * This test feeds byte sequences to the Intel PT packet decoder and checks the * results. Changes to the packet context are also checked. */ -int test__intel_pt_pkt_decoder(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__intel_pt_pkt_decoder(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { struct test_data *d = data; int ret; diff --git a/tools/perf/arch/x86/tests/rdpmc.c b/tools/perf/arch/x86/tests/rdpmc.c index 1ea916656a2d..498413ad9c97 100644 --- a/tools/perf/arch/x86/tests/rdpmc.c +++ b/tools/perf/arch/x86/tests/rdpmc.c @@ -157,7 +157,7 @@ out_close: return 0; } -int test__rdpmc(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__rdpmc(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { int status = 0; int wret = 0; diff --git a/tools/perf/arch/x86/tests/sample-parsing.c b/tools/perf/arch/x86/tests/sample-parsing.c index c92db87e4479..bfbd3662b69e 100644 --- a/tools/perf/arch/x86/tests/sample-parsing.c +++ b/tools/perf/arch/x86/tests/sample-parsing.c @@ -115,7 +115,7 @@ out_free: * For now, the PERF_SAMPLE_WEIGHT_STRUCT is the only X86 specific sample type. * The test only checks the PERF_SAMPLE_WEIGHT_STRUCT type. */ -int test__x86_sample_parsing(struct test *test __maybe_unused, int subtest __maybe_unused) +int test__x86_sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { return do_test(PERF_SAMPLE_WEIGHT_STRUCT); } diff --git a/tools/perf/arch/x86/util/evsel.c b/tools/perf/arch/x86/util/evsel.c index 2f733cdc8dbb..ac2899a25b7a 100644 --- a/tools/perf/arch/x86/util/evsel.c +++ b/tools/perf/arch/x86/util/evsel.c @@ -1,8 +1,31 @@ // SPDX-License-Identifier: GPL-2.0 #include <stdio.h> +#include <stdlib.h> #include "util/evsel.h" +#include "util/env.h" +#include "linux/string.h" void arch_evsel__set_sample_weight(struct evsel *evsel) { evsel__set_sample_bit(evsel, WEIGHT_STRUCT); } + +void arch_evsel__fixup_new_cycles(struct perf_event_attr *attr) +{ + struct perf_env env = { .total_mem = 0, } ; + + if (!perf_env__cpuid(&env)) + return; + + /* + * On AMD, precise cycles event sampling internally uses IBS pmu. + * But IBS does not have filtering capabilities and perf by default + * sets exclude_guest = 1. This makes IBS pmu event init fail and + * thus perf ends up doing non-precise sampling. Avoid it by clearing + * exclude_guest. + */ + if (env.cpuid && strstarts(env.cpuid, "AuthenticAMD")) + attr->exclude_guest = 0; + + free(env.cpuid); +} diff --git a/tools/perf/arch/x86/util/iostat.c b/tools/perf/arch/x86/util/iostat.c index eeafe97b8105..792cd75ade33 100644 --- a/tools/perf/arch/x86/util/iostat.c +++ b/tools/perf/arch/x86/util/iostat.c @@ -432,7 +432,7 @@ void iostat_print_metric(struct perf_stat_config *config, struct evsel *evsel, u8 die = ((struct iio_root_port *)evsel->priv)->die; struct perf_counts_values *count = perf_counts(evsel->counts, die, 0); - if (count->run && count->ena) { + if (count && count->run && count->ena) { if (evsel->prev_raw_counts && !out->force_header) { struct perf_counts_values *prev_count = perf_counts(evsel->prev_raw_counts, die, 0); |