[Devel] [PATCH vz10 v2 1/2] selftests/perf_events: fix sigtrap_threads tests fail with -O2
Konstantin Khorenko
khorenko at virtuozzo.com
Tue May 12 16:15:36 MSK 2026
The enable_event and modify_and_enable_event tests fail when compiled
with -O2:
Expected ctx.signal_count (5) == NUM_THREADS + 1 (6)
The test sequence is:
EXPECT_EQ(ctx.signal_count, NUM_THREADS); /* compiler loads into reg */
ctx.iterate_on = 0; /* triggers SIGTRAP, handler
increments signal_count */
EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1); /* stale cached value */
The signal handler already uses __atomic_fetch_add/__atomic_fetch_sub for
signal_count and tids_want_signal, but the test body reads them as plain
variables. At -O2 the compiler is free to cache the value across the
SIGTRAP-triggering store to iterate_on, so the second EXPECT_EQ sees
a stale register value.
Fix by using __atomic_load_n() for every read of signal_count and
tids_want_signal in test assertions.
https://virtuozzo.atlassian.net/browse/VSTOR-127669
Feature: fix selftests
Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
.../selftests/perf_events/sigtrap_threads.c | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c b/tools/testing/selftests/perf_events/sigtrap_threads.c
index d1d8483ac628d..ab4d18a6d4256 100644
--- a/tools/testing/selftests/perf_events/sigtrap_threads.c
+++ b/tools/testing/selftests/perf_events/sigtrap_threads.c
@@ -159,8 +159,8 @@ static void run_test_threads(struct __test_metadata *_metadata,
TEST_F(sigtrap_threads, remain_disabled)
{
run_test_threads(_metadata, self);
- EXPECT_EQ(ctx.signal_count, 0);
- EXPECT_NE(ctx.tids_want_signal, 0);
+ EXPECT_EQ(__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED), 0);
+ EXPECT_NE(__atomic_load_n(&ctx.tids_want_signal, __ATOMIC_RELAXED), 0);
}
TEST_F(sigtrap_threads, enable_event)
@@ -168,15 +168,15 @@ TEST_F(sigtrap_threads, enable_event)
EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_ENABLE, 0), 0);
run_test_threads(_metadata, self);
- EXPECT_EQ(ctx.signal_count, NUM_THREADS);
- EXPECT_EQ(ctx.tids_want_signal, 0);
+ EXPECT_EQ(__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED), NUM_THREADS);
+ EXPECT_EQ(__atomic_load_n(&ctx.tids_want_signal, __ATOMIC_RELAXED), 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));
/* Check enabled for parent. */
ctx.iterate_on = 0;
- EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1);
+ EXPECT_EQ(__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED), NUM_THREADS + 1);
}
/* Test that modification propagates to all inherited events. */
@@ -187,15 +187,15 @@ TEST_F(sigtrap_threads, modify_and_enable_event)
EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &new_attr), 0);
run_test_threads(_metadata, self);
- EXPECT_EQ(ctx.signal_count, NUM_THREADS);
- EXPECT_EQ(ctx.tids_want_signal, 0);
+ EXPECT_EQ(__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED), NUM_THREADS);
+ EXPECT_EQ(__atomic_load_n(&ctx.tids_want_signal, __ATOMIC_RELAXED), 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, 42));
/* Check enabled for parent. */
ctx.iterate_on = 0;
- EXPECT_EQ(ctx.signal_count, NUM_THREADS + 1);
+ EXPECT_EQ(__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED), NUM_THREADS + 1);
}
/* Stress test event + signal handling. */
@@ -207,8 +207,8 @@ TEST_F(sigtrap_threads, signal_stress)
run_test_threads(_metadata, self);
EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_DISABLE, 0), 0);
- EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on);
- EXPECT_EQ(ctx.tids_want_signal, 0);
+ EXPECT_EQ(__atomic_load_n(&ctx.signal_count, __ATOMIC_RELAXED), NUM_THREADS * ctx.iterate_on);
+ EXPECT_EQ(__atomic_load_n(&ctx.tids_want_signal, __ATOMIC_RELAXED), 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));
--
2.43.0
More information about the Devel
mailing list