From: Francesco Nigro <nigro.fra@gmail.com>
To: peterz@infradead.org, mingo@redhat.com, acme@kernel.org,
namhyung@kernel.org
Cc: mark.rutland@arm.com, alexander.shishkin@linux.intel.com,
jolsa@kernel.org, irogers@google.com, adrian.hunter@intel.com,
james.clark@linaro.org, kan.liang@linux.intel.com,
leo.yan@arm.com, linux-perf-users@vger.kernel.org,
linux-kernel@vger.kernel.org, regressions@lists.linux.dev,
Francesco Nigro <nigro.fra@gmail.com>
Subject: [PATCH] perf test: Add test for events re-armed with PERF_EVENT_IOC_REFRESH
Date: Wed, 21 Oct 2026 15:10:06 +0200 [thread overview]
Message-ID: <20261021131006.2101248-1-nigro.fra@gmail.com> (raw)
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
next reply other threads:[~2026-10-21 13:10 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 13:10 Francesco Nigro [this message]
[not found] <sashiko-outbox-180295@kernel.org>
2026-10-21 14:16 ` Francesco Nigro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261021131006.2101248-1-nigro.fra@gmail.com \
--to=nigro.fra@gmail.com \
--cc=acme@kernel.org \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=irogers@google.com \
--cc=james.clark@linaro.org \
--cc=jolsa@kernel.org \
--cc=kan.liang@linux.intel.com \
--cc=leo.yan@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-perf-users@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=mingo@redhat.com \
--cc=namhyung@kernel.org \
--cc=peterz@infradead.org \
--cc=regressions@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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®