Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/Y0E3uG7jOywn7vy3@elver.google.com/

authored by

Marco Elver and committed by
Peter Zijlstra
23488ec6 ca6c2132

+32 -3
+32 -3
tools/testing/selftests/perf_events/sigtrap_threads.c
··· 62 62 .remove_on_exec = 1, /* Required by sigtrap. */ 63 63 .sigtrap = 1, /* Request synchronous SIGTRAP on event. */ 64 64 .sig_data = TEST_SIG_DATA(addr, id), 65 + .exclude_kernel = 1, /* To allow */ 66 + .exclude_hv = 1, /* running as !root */ 65 67 }; 66 68 return attr; 67 69 } ··· 95 93 96 94 __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); 97 95 iter = ctx.iterate_on; /* read */ 98 - for (i = 0; i < iter - 1; i++) { 99 - __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); 100 - ctx.iterate_on = iter; /* idempotent write */ 96 + if (iter >= 0) { 97 + for (i = 0; i < iter - 1; i++) { 98 + __atomic_fetch_add(&ctx.tids_want_signal, tid, __ATOMIC_RELAXED); 99 + ctx.iterate_on = iter; /* idempotent write */ 100 + } 101 + } else { 102 + while (ctx.iterate_on); 101 103 } 102 104 103 105 return NULL; ··· 209 203 210 204 EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on); 211 205 EXPECT_EQ(ctx.tids_want_signal, 0); 206 + EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); 207 + EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT); 208 + EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0)); 209 + } 210 + 211 + TEST_F(sigtrap_threads, signal_stress_with_disable) 212 + { 213 + const int target_count = NUM_THREADS * 3000; 214 + int i; 215 + 216 + ctx.iterate_on = -1; 217 + 218 + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); 219 + pthread_barrier_wait(&self->barrier); 220 + while (__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED) < target_count) { 221 + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0); 222 + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0); 223 + } 224 + ctx.iterate_on = 0; 225 + for (i = 0; i < NUM_THREADS; i++) 226 + ASSERT_EQ(pthread_join(self->threads[i], NULL), 0); 227 + EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0); 228 + 212 229 EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); 213 230 EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT); 214 231 EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));