[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