Skip to content

Commit ade3a58

Browse files
melverpaulmckrcu
authored andcommitted
kcsan: test: Fix flaky test case
If CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY=n, then we may also see data races between the writers only. If we get unlucky and never capture a read-write data race, but only the write-write data races, then the test_no_value_change* test cases may incorrectly fail. The second problem is that the initial value needs to be reset, as otherwise we might actually observe a value change at the start. Fix it by also looking for the write-write data races, and resetting the value to what will be written. Signed-off-by: Marco Elver <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 8080428 commit ade3a58

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

kernel/kcsan/kcsan_test.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -493,17 +493,24 @@ static void test_concurrent_races(struct kunit *test)
493493
__no_kcsan
494494
static void test_novalue_change(struct kunit *test)
495495
{
496-
const struct expect_report expect = {
496+
const struct expect_report expect_rw = {
497497
.access = {
498498
{ test_kernel_write_nochange, &test_var, sizeof(test_var), KCSAN_ACCESS_WRITE },
499499
{ test_kernel_read, &test_var, sizeof(test_var), 0 },
500500
},
501501
};
502+
const struct expect_report expect_ww = {
503+
.access = {
504+
{ test_kernel_write_nochange, &test_var, sizeof(test_var), KCSAN_ACCESS_WRITE },
505+
{ test_kernel_write_nochange, &test_var, sizeof(test_var), KCSAN_ACCESS_WRITE },
506+
},
507+
};
502508
bool match_expect = false;
503509

510+
test_kernel_write_nochange(); /* Reset value. */
504511
begin_test_checks(test_kernel_write_nochange, test_kernel_read);
505512
do {
506-
match_expect = report_matches(&expect);
513+
match_expect = report_matches(&expect_rw) || report_matches(&expect_ww);
507514
} while (!end_test_checks(match_expect));
508515
if (IS_ENABLED(CONFIG_KCSAN_REPORT_VALUE_CHANGE_ONLY))
509516
KUNIT_EXPECT_FALSE(test, match_expect);
@@ -518,17 +525,24 @@ static void test_novalue_change(struct kunit *test)
518525
__no_kcsan
519526
static void test_novalue_change_exception(struct kunit *test)
520527
{
521-
const struct expect_report expect = {
528+
const struct expect_report expect_rw = {
522529
.access = {
523530
{ test_kernel_write_nochange_rcu, &test_var, sizeof(test_var), KCSAN_ACCESS_WRITE },
524531
{ test_kernel_read, &test_var, sizeof(test_var), 0 },
525532
},
526533
};
534+
const struct expect_report expect_ww = {
535+
.access = {
536+
{ test_kernel_write_nochange_rcu, &test_var, sizeof(test_var), KCSAN_ACCESS_WRITE },
537+
{ test_kernel_write_nochange_rcu, &test_var, sizeof(test_var), KCSAN_ACCESS_WRITE },
538+
},
539+
};
527540
bool match_expect = false;
528541

542+
test_kernel_write_nochange_rcu(); /* Reset value. */
529543
begin_test_checks(test_kernel_write_nochange_rcu, test_kernel_read);
530544
do {
531-
match_expect = report_matches(&expect);
545+
match_expect = report_matches(&expect_rw) || report_matches(&expect_ww);
532546
} while (!end_test_checks(match_expect));
533547
KUNIT_EXPECT_TRUE(test, match_expect);
534548
}

0 commit comments

Comments
 (0)