Messages in this thread Patch in this message | | | Date | Sat, 8 Oct 2022 10:41:28 +0200 | From | Marco Elver <> | Subject | Re: [PATCH] perf: Fix missing SIGTRAPs |
| |
On Fri, Oct 07, 2022 at 06:14PM +0200, Marco Elver wrote: > On Fri, Oct 07, 2022 at 03:58PM +0200, Marco Elver wrote: > > On Fri, Oct 07, 2022 at 03:09PM +0200, Peter Zijlstra wrote: > > > On Fri, Oct 07, 2022 at 11:37:34AM +0200, Marco Elver wrote: > > > > > > > That worked. In addition I had to disable the ctx->task != current check > > > > if we're in task_work, because presumably the event might have already > > > > been disabled/moved?? > > > > > > Uhmmm... uhhh... damn. (wall-time was significantly longer) > > > > > > Does this help? > > > > No unfortunately - still see: > > > > [ 82.300827] ------------[ cut here ]------------ > > [ 82.301680] WARNING: CPU: 0 PID: 976 at kernel/events/core.c:6466 perf_sigtrap+0x60/0x70 > > Whenever the warning fires, I see that event->state is OFF.
The below patch to the sigtrap_threads test can repro the issue (when run lots of them concurrently again). It also illustrates the original problem we're trying to solve, where the event never gets rearmed again and the test times out (doesn't happen with the almost-working fix).
Thanks, -- Marco
------ >8 ------
From 98d225bda6d94dd793a1d0c77ae4b301c364166e Mon Sep 17 00:00:00 2001 From: Marco Elver <elver@google.com> Date: Sat, 8 Oct 2022 10:26:58 +0200 Subject: [PATCH] selftests/perf_events: Add a SIGTRAP stress test with disables
Add a SIGTRAP stress test that exercises repeatedly enabling/disabling an event while it concurrently keeps firing.
Signed-off-by: Marco Elver <elver@google.com> --- .../selftests/perf_events/sigtrap_threads.c | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c b/tools/testing/selftests/perf_events/sigtrap_threads.c index 6d849dc2bee0..d1d8483ac628 100644 --- a/tools/testing/selftests/perf_events/sigtrap_threads.c +++ b/tools/testing/selftests/perf_events/sigtrap_threads.c @@ -62,6 +62,8 @@ static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr, .remove_on_exec = 1, /* Required by sigtrap. */ .sigtrap = 1, /* Request synchronous SIGTRAP on event. */ .sig_data = TEST_SIG_DATA(addr, id), + .exclude_kernel = 1, /* To allow */ + .exclude_hv = 1, /* running as !root */ }; return attr; } @@ -93,9 +95,13 @@ static void *test_thread(void *arg) __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); iter = ctx.iterate_on; /* read */ - for (i = 0; i < iter - 1; i++) { - __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); - ctx.iterate_on = iter; /* idempotent write */ + if (iter >= 0) { + for (i = 0; i < iter - 1; i++) { + __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); + ctx.iterate_on = iter; /* idempotent write */ + } + } else { + while (ctx.iterate_on); } return NULL; @@ -208,4 +214,27 @@ TEST_F(sigtrap_threads, signal_stress) EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0)); } +TEST_F(sigtrap_threads, signal_stress_with_disable) +{ + const int target_count = NUM_THREADS * 3000; + int i; + + ctx.iterate_on = -1; + + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + pthread_barrier_wait(&self->barrier); + while (__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED) < target_count) { + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0); + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); + } + ctx.iterate_on = 0; + for (i = 0; i < NUM_THREADS; i++) + ASSERT_EQ(pthread_join(self->threads[i], NULL), 0); + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0); + + EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); + EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT); + EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0)); +} + TEST_HARNESS_MAIN -- 2.38.0.rc1.362.ged0d419d3c-goog
| |