From 5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 12:05:51 +0200 Subject: Adding upstream version 5.10.209. Signed-off-by: Daniel Baumann --- .../selftests/powerpc/pmu/per_event_excludes.c | 111 +++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 tools/testing/selftests/powerpc/pmu/per_event_excludes.c (limited to 'tools/testing/selftests/powerpc/pmu/per_event_excludes.c') diff --git a/tools/testing/selftests/powerpc/pmu/per_event_excludes.c b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c new file mode 100644 index 000000000..ad32a09a6 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/per_event_excludes.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2014, Michael Ellerman, IBM Corp. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#include "event.h" +#include "lib.h" +#include "utils.h" + +/* + * Test that per-event excludes work. + */ + +static int per_event_excludes(void) +{ + struct event *e, events[4]; + int i; + + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07)); + + /* + * We need to create the events disabled, otherwise the running/enabled + * counts don't match up. + */ + e = &events[0]; + event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, + PERF_TYPE_HARDWARE, "instructions"); + e->attr.disabled = 1; + + e = &events[1]; + event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, + PERF_TYPE_HARDWARE, "instructions(k)"); + e->attr.disabled = 1; + e->attr.exclude_user = 1; + e->attr.exclude_hv = 1; + + e = &events[2]; + event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, + PERF_TYPE_HARDWARE, "instructions(h)"); + e->attr.disabled = 1; + e->attr.exclude_user = 1; + e->attr.exclude_kernel = 1; + + e = &events[3]; + event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, + PERF_TYPE_HARDWARE, "instructions(u)"); + e->attr.disabled = 1; + e->attr.exclude_hv = 1; + e->attr.exclude_kernel = 1; + + FAIL_IF(event_open(&events[0])); + + /* + * The open here will fail if we don't have per event exclude support, + * because the second event has an incompatible set of exclude settings + * and we're asking for the events to be in a group. + */ + for (i = 1; i < 4; i++) + FAIL_IF(event_open_with_group(&events[i], events[0].fd)); + + /* + * Even though the above will fail without per-event excludes we keep + * testing in order to be thorough. + */ + prctl(PR_TASK_PERF_EVENTS_ENABLE); + + /* Spin for a while */ + for (i = 0; i < INT_MAX; i++) + asm volatile("" : : : "memory"); + + prctl(PR_TASK_PERF_EVENTS_DISABLE); + + for (i = 0; i < 4; i++) { + FAIL_IF(event_read(&events[i])); + event_report(&events[i]); + } + + /* + * We should see that all events have enabled == running. That + * shows that they were all on the PMU at once. + */ + for (i = 0; i < 4; i++) + FAIL_IF(events[i].result.running != events[i].result.enabled); + + /* + * We can also check that the result for instructions is >= all the + * other counts. That's because it is counting all instructions while + * the others are counting a subset. + */ + for (i = 1; i < 4; i++) + FAIL_IF(events[0].result.value < events[i].result.value); + + for (i = 0; i < 4; i++) + event_close(&events[i]); + + return 0; +} + +int main(void) +{ + return test_harness(per_event_excludes, "per_event_excludes"); +} -- cgit v1.2.3