[Devel] [PATCH RHEL10 COMMIT] selftests/perf_events: fix sigtrap_threads tests fail with -O2
Konstantin Khorenko
khorenko at virtuozzo.com
Tue May 12 16:33:10 MSK 2026
The commit is pushed to "branch-rh10-6.12.0-55.52.1.5.x.vz10-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh10-6.12.0-55.52.1.5.22.vz10
------>
commit cc62869ce03326d81f1869b61bb8582cf1455e70
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date: Tue May 12 14:49:54 2026 +0200
selftests/perf_events: fix sigtrap_threads tests fail with -O2
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>
---
.../testing/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));
More information about the Devel
mailing list