* [PATCH] perf test: Add test for events re-armed with PERF_EVENT_IOC_REFRESH
@ 2026-10-21 13:10 Francesco Nigro
0 siblings, 0 replies; 2+ messages in thread
From: Francesco Nigro @ 2026-10-21 13:10 UTC (permalink / raw)
To: peterz, mingo, acme, namhyung
Cc: mark.rutland, alexander.shishkin, jolsa, irogers, adrian.hunter,
james.clark, kan.liang, leo.yan, linux-perf-users, linux-kernel,
regressions, Francesco Nigro
Open a sampling event with sample_period 1, re-arm it with
PERF_EVENT_IOC_REFRESH from its SIGIO handler, as self-profilers such
as async-profiler do, and check that each of 1000 events delivers a
signal. One case uses a software event (page faults), the other the
syscalls:sys_enter_getppid tracepoint.
The tracepoint case fails since
commit 18dbcbfabfff ("perf: Fix the POLL_HUP delivery breakage"):
only the first overflow is delivered. It passes on the parent commit.
The software case passes on both.
The test was written with an AI coding assistant (Claude) from a
standalone reproducer; I reviewed it and ran it in QEMU on current
mainline, on that commit and on its parent.
Link: https://github.com/async-profiler/async-profiler/issues/1813
Signed-off-by: Francesco Nigro <nigro.fra@gmail.com>
---
Notes:
To run it on any x86_64 box with virtme-ng:
vng --kconfig && make -j$(nproc)
make -C tools/perf NO_LIBTRACEEVENT=1
vng -- tools/perf/perf test -v REFRESH
Results, 2 vCPUs:
b320789d6883 (parent) Tracepoint event: Ok
18dbcbfabfff Tracepoint event: FAILED, 1000 events, 1 overflows
a804c5742bff (master) Tracepoint event: FAILED, 1000 events, 1 overflows
The software event passes on all three.
Leo Yan's series "perf: Revert direct PMU stop for refresh limit"
(linux-perf-users, 2026-05-12) reverts 18dbcbfabfff for a different
reason; I haven't tested it against this.
#regzbot introduced: 18dbcbfabfff
tools/perf/tests/Build | 1 +
tools/perf/tests/builtin-test.c | 1 +
tools/perf/tests/event_refresh.c | 136 +++++++++++++++++++++++++++++++
tools/perf/tests/tests.h | 1 +
4 files changed, 139 insertions(+)
create mode 100644 tools/perf/tests/event_refresh.c
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 66944a4f4..199e10c8c 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -23,6 +23,7 @@ perf-test-y += hists_output.o
perf-test-y += hists_cumulate.o
perf-test-y += bp_signal.o
perf-test-y += bp_signal_overflow.o
+perf-test-y += event_refresh.o
perf-test-y += bp_account.o
perf-test-y += wp.o
perf-test-y += task-exit.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 4d0784b16..2b10f4d7f 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -98,6 +98,7 @@ static struct test_suite *generic_tests[] = {
&suite__hists_link,
&suite__bp_signal,
&suite__bp_signal_overflow,
+ &suite__event_refresh,
&suite__bp_accounting,
&suite__wp,
&suite__task_exit,
diff --git a/tools/perf/tests/event_refresh.c b/tools/perf/tests/event_refresh.c
new file mode 100644
index 000000000..480f738de
--- /dev/null
+++ b/tools/perf/tests/event_refresh.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Re-arm a sampling event from its overflow signal handler with
+ * PERF_EVENT_IOC_REFRESH and check that every overflow is delivered.
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+#include <linux/perf_event.h>
+
+#include "cloexec.h"
+#include "debug.h"
+#include "tests.h"
+#include "tp_pmu.h"
+#include <internal/lib.h> // page_size
+#include "../perf-sys.h"
+
+#define NR_EVENTS 1000
+
+static volatile sig_atomic_t overflows;
+
+static void sig_handler(int signum __maybe_unused, siginfo_t *info,
+ void *uc __maybe_unused)
+{
+ overflows++;
+ ioctl(info->si_fd, PERF_EVENT_IOC_REFRESH, 1);
+}
+
+/* Count overflow signals for NR_EVENTS calls of trigger(), period 1. */
+static int count_overflows(struct perf_event_attr *attr, void (*trigger)(int i))
+{
+ struct sigaction sa, old_sa;
+ int fd, i, err = TEST_FAIL;
+
+ attr->size = sizeof(*attr);
+ attr->sample_period = 1;
+ attr->disabled = 1;
+
+ fd = sys_perf_event_open(attr, 0, -1, -1, perf_event_open_cloexec_flag());
+ if (fd < 0) {
+ pr_debug("failed opening event: %s\n", strerror(errno));
+ return TEST_SKIP;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = sig_handler;
+ sa.sa_flags = SA_SIGINFO;
+ if (sigaction(SIGIO, &sa, &old_sa) < 0) {
+ pr_debug("failed setting up signal handler\n");
+ goto out_close;
+ }
+
+ fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK | O_ASYNC);
+ fcntl(fd, F_SETSIG, SIGIO);
+ fcntl(fd, F_SETOWN, getpid());
+
+ overflows = 0;
+ ioctl(fd, PERF_EVENT_IOC_REFRESH, 1);
+ for (i = 0; i < NR_EVENTS; i++)
+ trigger(i);
+ ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
+
+ pr_debug("%d events, %d overflows\n", NR_EVENTS, overflows);
+ if (overflows == NR_EVENTS)
+ err = TEST_OK;
+
+ sigaction(SIGIO, &old_sa, NULL);
+out_close:
+ close(fd);
+ return err;
+}
+
+static char *pages;
+
+static void touch_page(int i)
+{
+ pages[(long)i * page_size] = 1;
+}
+
+static int test__event_refresh_sw(struct test_suite *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_SOFTWARE,
+ .config = PERF_COUNT_SW_PAGE_FAULTS,
+ };
+ int err;
+
+ pages = mmap(NULL, (long)NR_EVENTS * page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (pages == MAP_FAILED)
+ return TEST_FAIL;
+
+ err = count_overflows(&attr, touch_page);
+ munmap(pages, (long)NR_EVENTS * page_size);
+ return err;
+}
+
+static void call_getppid(int i __maybe_unused)
+{
+ syscall(SYS_getppid);
+}
+
+static int test__event_refresh_tp(struct test_suite *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ struct perf_event_attr attr = {
+ .type = PERF_TYPE_TRACEPOINT,
+ };
+ int id = tp_pmu__id("syscalls", "sys_enter_getppid");
+
+ if (id < 0) {
+ pr_debug("no syscalls:sys_enter_getppid tracepoint\n");
+ return TEST_SKIP;
+ }
+ attr.config = id;
+
+ return count_overflows(&attr, call_getppid);
+}
+
+static struct test_case tests__event_refresh[] = {
+ TEST_CASE_REASON("Software event", event_refresh_sw, "permissions"),
+ TEST_CASE_REASON("Tracepoint event", event_refresh_tp, "permissions"),
+ { .name = NULL, }
+};
+
+struct test_suite suite__event_refresh = {
+ .desc = "Event re-armed with PERF_EVENT_IOC_REFRESH",
+ .test_cases = tests__event_refresh,
+};
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index cee9e6b62..ecc25b5a3 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -124,6 +124,7 @@ DECLARE_SUITE(parse_events);
DECLARE_SUITE(hists_link);
DECLARE_SUITE(bp_signal);
DECLARE_SUITE(bp_signal_overflow);
+DECLARE_SUITE(event_refresh);
DECLARE_SUITE(bp_accounting);
DECLARE_SUITE(wp);
DECLARE_SUITE(task_exit);
--
2.55.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] perf test: Add test for events re-armed with PERF_EVENT_IOC_REFRESH
[not found] <sashiko-outbox-180295@kernel.org>
@ 2026-10-21 14:16 ` Francesco Nigro
0 siblings, 0 replies; 2+ messages in thread
From: Francesco Nigro @ 2026-10-21 14:16 UTC (permalink / raw)
To: peterz, mingo, acme, namhyung
Cc: mark.rutland, alexander.shishkin, jolsa, irogers, adrian.hunter,
james.clark, kan.liang, leo.yan, linux-perf-users, linux-kernel,
regressions, Francesco Nigro
> On systems with Transparent Huge Pages (THP) or multi-size THP (mTHP) set
> to "always" [...] As a result, overflows only reaches 489 (or fewer)
> instead of NR_EVENTS (1000), and count_overflows() returns TEST_FAIL.
Confirmed: on master with transparent_hugepage=always the software case
gets 489 of 1000 overflows. With madvise(MADV_NOHUGEPAGE) on the buffer it
gets all 1000, and the tracepoint case still gets 1. I'll send a v2 with
that change.
Thanks,
Francesco
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-21 14:16 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-21 13:10 [PATCH] perf test: Add test for events re-armed with PERF_EVENT_IOC_REFRESH Francesco Nigro
[not found] <sashiko-outbox-180295@kernel.org>
2026-10-21 14:16 ` Francesco Nigro
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®