mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 18:56:24 +00:00
perf tools fixes for v5.18: 6th batch
- Fix and validate CPU map inputs in synthetic PERF_RECORD_STAT events in 'perf stat'. - Fix x86's arch__intr_reg_mask() for the hybrid platform. - Address 'perf bench numa' compiler error on s390. - Fix check for btf__load_from_kernel_by_id() in libbpf. - Fix "all PMU test" 'perf test' to skip hv_24x7/hv_gpci tests on powerpc. - Fix session topology test to skip the test in guest environment. - Skip BPF 'perf test' if clang is not present. - Avoid shell test description infinite loop in 'perf test'. - Fix Intel LBR callstack entries and nr print message. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQR2GiIUctdOfX2qHhGyPKLppCJ+JwUCYokzYwAKCRCyPKLppCJ+ J9rLAQCwp6FAAbbh/Kxv9jiU51xTYRItpjNk0SDJsh+hb+vwYgD7BTvbTco5d6TJ n8BkHw2v3iLCUHJX23qzMKgZyOa87w4= =9T87 -----END PGP SIGNATURE----- Merge tag 'perf-tools-fixes-for-v5.18-2022-05-21' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux Pull perf tools fixes from Arnaldo Carvalho de Melo: - Fix and validate CPU map inputs in synthetic PERF_RECORD_STAT events in 'perf stat'. - Fix x86's arch__intr_reg_mask() for the hybrid platform. - Address 'perf bench numa' compiler error on s390. - Fix check for btf__load_from_kernel_by_id() in libbpf. - Fix "all PMU test" 'perf test' to skip hv_24x7/hv_gpci tests on powerpc. - Fix session topology test to skip the test in guest environment. - Skip BPF 'perf test' if clang is not present. - Avoid shell test description infinite loop in 'perf test'. - Fix Intel LBR callstack entries and nr print message. * tag 'perf-tools-fixes-for-v5.18-2022-05-21' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux: perf session: Fix Intel LBR callstack entries and nr print message perf test bpf: Skip test if clang is not present perf test session topology: Fix test to skip the test in guest environment perf bench numa: Address compiler error on s390 perf test: Avoid shell test description infinite loop perf regs x86: Fix arch__intr_reg_mask() for the hybrid platform perf test: Fix "all PMU test" to skip hv_24x7/hv_gpci tests on powerpc perf stat: Fix and validate CPU map inputs in synthetic PERF_RECORD_STAT events perf build: Fix check for btf__load_from_kernel_by_id() in libbpf
This commit is contained in:
commit
eaea45fc0e
@ -98,6 +98,7 @@ FEATURE_TESTS_EXTRA := \
|
||||
llvm-version \
|
||||
clang \
|
||||
libbpf \
|
||||
libbpf-btf__load_from_kernel_by_id \
|
||||
libpfm4 \
|
||||
libdebuginfod \
|
||||
clang-bpf-co-re
|
||||
|
@ -57,6 +57,7 @@ FILES= \
|
||||
test-lzma.bin \
|
||||
test-bpf.bin \
|
||||
test-libbpf.bin \
|
||||
test-libbpf-btf__load_from_kernel_by_id.bin \
|
||||
test-get_cpuid.bin \
|
||||
test-sdt.bin \
|
||||
test-cxx.bin \
|
||||
@ -287,6 +288,9 @@ $(OUTPUT)test-bpf.bin:
|
||||
$(OUTPUT)test-libbpf.bin:
|
||||
$(BUILD) -lbpf
|
||||
|
||||
$(OUTPUT)test-libbpf-btf__load_from_kernel_by_id.bin:
|
||||
$(BUILD) -lbpf
|
||||
|
||||
$(OUTPUT)test-sdt.bin:
|
||||
$(BUILD)
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <bpf/libbpf.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return btf__load_from_kernel_by_id(20151128, NULL);
|
||||
}
|
@ -553,9 +553,16 @@ ifndef NO_LIBELF
|
||||
ifeq ($(feature-libbpf), 1)
|
||||
EXTLIBS += -lbpf
|
||||
$(call detected,CONFIG_LIBBPF_DYNAMIC)
|
||||
|
||||
$(call feature_check,libbpf-btf__load_from_kernel_by_id)
|
||||
ifeq ($(feature-libbpf-btf__load_from_kernel_by_id), 1)
|
||||
CFLAGS += -DHAVE_LIBBPF_BTF__LOAD_FROM_KERNEL_BY_ID
|
||||
endif
|
||||
else
|
||||
dummy := $(error Error: No libbpf devel library found, please install libbpf-devel);
|
||||
endif
|
||||
else
|
||||
CFLAGS += -DHAVE_LIBBPF_BTF__LOAD_FROM_KERNEL_BY_ID
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "../../../util/perf_regs.h"
|
||||
#include "../../../util/debug.h"
|
||||
#include "../../../util/event.h"
|
||||
#include "../../../util/pmu.h"
|
||||
#include "../../../util/pmu-hybrid.h"
|
||||
|
||||
const struct sample_reg sample_reg_masks[] = {
|
||||
SMPL_REG(AX, PERF_REG_X86_AX),
|
||||
@ -284,12 +286,22 @@ uint64_t arch__intr_reg_mask(void)
|
||||
.disabled = 1,
|
||||
.exclude_kernel = 1,
|
||||
};
|
||||
struct perf_pmu *pmu;
|
||||
int fd;
|
||||
/*
|
||||
* In an unnamed union, init it here to build on older gcc versions
|
||||
*/
|
||||
attr.sample_period = 1;
|
||||
|
||||
if (perf_pmu__has_hybrid()) {
|
||||
/*
|
||||
* The same register set is supported among different hybrid PMUs.
|
||||
* Only check the first available one.
|
||||
*/
|
||||
pmu = list_first_entry(&perf_pmu__hybrid_pmus, typeof(*pmu), hybrid_list);
|
||||
attr.config |= (__u64)pmu->type << PERF_PMU_TYPE_SHIFT;
|
||||
}
|
||||
|
||||
event_attr_init(&attr);
|
||||
|
||||
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
|
||||
|
@ -1740,7 +1740,7 @@ static int __bench_numa(const char *name)
|
||||
"GB/sec,", "total-speed", "GB/sec total speed");
|
||||
|
||||
if (g->p.show_details >= 2) {
|
||||
char tname[14 + 2 * 10 + 1];
|
||||
char tname[14 + 2 * 11 + 1];
|
||||
struct thread_data *td;
|
||||
for (p = 0; p < g->p.nr_proc; p++) {
|
||||
for (t = 0; t < g->p.nr_threads; t++) {
|
||||
|
@ -222,11 +222,11 @@ static int __test__bpf(int idx)
|
||||
|
||||
ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
|
||||
bpf_testcase_table[idx].prog_id,
|
||||
true, NULL);
|
||||
false, NULL);
|
||||
if (ret != TEST_OK || !obj_buf || !obj_buf_sz) {
|
||||
pr_debug("Unable to get BPF object, %s\n",
|
||||
bpf_testcase_table[idx].msg_compile_fail);
|
||||
if (idx == 0)
|
||||
if ((idx == 0) || (ret == TEST_SKIP))
|
||||
return TEST_SKIP;
|
||||
else
|
||||
return TEST_FAIL;
|
||||
@ -364,9 +364,11 @@ static int test__bpf_prologue_test(struct test_suite *test __maybe_unused,
|
||||
static struct test_case bpf_tests[] = {
|
||||
#ifdef HAVE_LIBBPF_SUPPORT
|
||||
TEST_CASE("Basic BPF filtering", basic_bpf_test),
|
||||
TEST_CASE("BPF pinning", bpf_pinning),
|
||||
TEST_CASE_REASON("BPF pinning", bpf_pinning,
|
||||
"clang isn't installed or environment missing BPF support"),
|
||||
#ifdef HAVE_BPF_PROLOGUE
|
||||
TEST_CASE("BPF prologue generation", bpf_prologue_test),
|
||||
TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test,
|
||||
"clang isn't installed or environment missing BPF support"),
|
||||
#else
|
||||
TEST_CASE_REASON("BPF prologue generation", bpf_prologue_test, "not compiled in"),
|
||||
#endif
|
||||
|
@ -279,6 +279,7 @@ static const char *shell_test__description(char *description, size_t size,
|
||||
{
|
||||
FILE *fp;
|
||||
char filename[PATH_MAX];
|
||||
int ch;
|
||||
|
||||
path__join(filename, sizeof(filename), path, name);
|
||||
fp = fopen(filename, "r");
|
||||
@ -286,7 +287,9 @@ static const char *shell_test__description(char *description, size_t size,
|
||||
return NULL;
|
||||
|
||||
/* Skip shebang */
|
||||
while (fgetc(fp) != '\n');
|
||||
do {
|
||||
ch = fgetc(fp);
|
||||
} while (ch != EOF && ch != '\n');
|
||||
|
||||
description = fgets(description, size, fp);
|
||||
fclose(fp);
|
||||
@ -417,7 +420,8 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width,
|
||||
.priv = &st,
|
||||
};
|
||||
|
||||
if (!perf_test__matches(test_suite.desc, curr, argc, argv))
|
||||
if (test_suite.desc == NULL ||
|
||||
!perf_test__matches(test_suite.desc, curr, argc, argv))
|
||||
continue;
|
||||
|
||||
st.file = ent->d_name;
|
||||
|
@ -5,6 +5,16 @@
|
||||
set -e
|
||||
|
||||
for p in $(perf list --raw-dump pmu); do
|
||||
# In powerpc, skip the events for hv_24x7 and hv_gpci.
|
||||
# These events needs input values to be filled in for
|
||||
# core, chip, partition id based on system.
|
||||
# Example: hv_24x7/CPM_ADJUNCT_INST,domain=?,core=?/
|
||||
# hv_gpci/event,partition_id=?/
|
||||
# Hence skip these events for ppc.
|
||||
if echo "$p" |grep -Eq 'hv_24x7|hv_gpci' ; then
|
||||
echo "Skipping: Event '$p' in powerpc"
|
||||
continue
|
||||
fi
|
||||
echo "Testing $p"
|
||||
result=$(perf stat -e "$p" true 2>&1)
|
||||
if ! echo "$result" | grep -q "$p" && ! echo "$result" | grep -q "<not supported>" ; then
|
||||
|
@ -109,6 +109,17 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
|
||||
&& strncmp(session->header.env.arch, "aarch64", 7))
|
||||
return TEST_SKIP;
|
||||
|
||||
/*
|
||||
* In powerpc pSeries platform, not all the topology information
|
||||
* are exposed via sysfs. Due to restriction, detail like
|
||||
* physical_package_id will be set to -1. Hence skip this
|
||||
* test if physical_package_id returns -1 for cpu from perf_cpu_map.
|
||||
*/
|
||||
if (strncmp(session->header.env.arch, "powerpc", 7)) {
|
||||
if (cpu__get_socket_id(perf_cpu_map__cpu(map, 0)) == -1)
|
||||
return TEST_SKIP;
|
||||
}
|
||||
|
||||
TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
|
||||
|
||||
for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
|
||||
|
@ -22,7 +22,8 @@
|
||||
#include "record.h"
|
||||
#include "util/synthetic-events.h"
|
||||
|
||||
struct btf * __weak btf__load_from_kernel_by_id(__u32 id)
|
||||
#ifndef HAVE_LIBBPF_BTF__LOAD_FROM_KERNEL_BY_ID
|
||||
struct btf *btf__load_from_kernel_by_id(__u32 id)
|
||||
{
|
||||
struct btf *btf;
|
||||
#pragma GCC diagnostic push
|
||||
@ -32,6 +33,7 @@ struct btf * __weak btf__load_from_kernel_by_id(__u32 id)
|
||||
|
||||
return err ? ERR_PTR(err) : btf;
|
||||
}
|
||||
#endif
|
||||
|
||||
int __weak bpf_prog_load(enum bpf_prog_type prog_type,
|
||||
const char *prog_name __maybe_unused,
|
||||
|
@ -1151,9 +1151,20 @@ static void branch_stack__printf(struct perf_sample *sample, bool callstack)
|
||||
struct branch_entry *entries = perf_sample__branch_entries(sample);
|
||||
uint64_t i;
|
||||
|
||||
printf("%s: nr:%" PRIu64 "\n",
|
||||
!callstack ? "... branch stack" : "... branch callstack",
|
||||
sample->branch_stack->nr);
|
||||
if (!callstack) {
|
||||
printf("%s: nr:%" PRIu64 "\n", "... branch stack", sample->branch_stack->nr);
|
||||
} else {
|
||||
/* the reason of adding 1 to nr is because after expanding
|
||||
* branch stack it generates nr + 1 callstack records. e.g.,
|
||||
* B()->C()
|
||||
* A()->B()
|
||||
* the final callstack should be:
|
||||
* C()
|
||||
* B()
|
||||
* A()
|
||||
*/
|
||||
printf("%s: nr:%" PRIu64 "\n", "... branch callstack", sample->branch_stack->nr+1);
|
||||
}
|
||||
|
||||
for (i = 0; i < sample->branch_stack->nr; i++) {
|
||||
struct branch_entry *e = &entries[i];
|
||||
@ -1169,8 +1180,13 @@ static void branch_stack__printf(struct perf_sample *sample, bool callstack)
|
||||
(unsigned)e->flags.reserved,
|
||||
e->flags.type ? branch_type_name(e->flags.type) : "");
|
||||
} else {
|
||||
printf("..... %2"PRIu64": %016" PRIx64 "\n",
|
||||
i, i > 0 ? e->from : e->to);
|
||||
if (i == 0) {
|
||||
printf("..... %2"PRIu64": %016" PRIx64 "\n"
|
||||
"..... %2"PRIu64": %016" PRIx64 "\n",
|
||||
i, e->to, i+1, e->from);
|
||||
} else {
|
||||
printf("..... %2"PRIu64": %016" PRIx64 "\n", i+1, e->from);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -472,9 +472,10 @@ int perf_stat_process_counter(struct perf_stat_config *config,
|
||||
int perf_event__process_stat_event(struct perf_session *session,
|
||||
union perf_event *event)
|
||||
{
|
||||
struct perf_counts_values count;
|
||||
struct perf_counts_values count, *ptr;
|
||||
struct perf_record_stat *st = &event->stat;
|
||||
struct evsel *counter;
|
||||
int cpu_map_idx;
|
||||
|
||||
count.val = st->val;
|
||||
count.ena = st->ena;
|
||||
@ -485,8 +486,18 @@ int perf_event__process_stat_event(struct perf_session *session,
|
||||
pr_err("Failed to resolve counter for stat event.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*perf_counts(counter->counts, st->cpu, st->thread) = count;
|
||||
cpu_map_idx = perf_cpu_map__idx(evsel__cpus(counter), (struct perf_cpu){.cpu = st->cpu});
|
||||
if (cpu_map_idx == -1) {
|
||||
pr_err("Invalid CPU %d for event %s.\n", st->cpu, evsel__name(counter));
|
||||
return -EINVAL;
|
||||
}
|
||||
ptr = perf_counts(counter->counts, cpu_map_idx, st->thread);
|
||||
if (ptr == NULL) {
|
||||
pr_err("Failed to find perf count for CPU %d thread %d on event %s.\n",
|
||||
st->cpu, st->thread, evsel__name(counter));
|
||||
return -EINVAL;
|
||||
}
|
||||
*ptr = count;
|
||||
counter->supported = true;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user