Skip to content

Commit 9470a18

Browse files
committed
rcutorture: Manually clean up after rcu_barrier() failure
Currently, if rcu_barrier() returns too soon, the test waits 100ms and then does another instance of the test. However, if rcu_barrier() were to have waited for more than 100ms too short a time, this could cause the test's rcu_head structures to be reused while they were still on RCU's callback lists. This can result in knock-on errors that obscure the original rcu_barrier() test failure. This commit therefore adds code that attempts to wait until all of the test's callbacks have been invoked. Of course, if RCU completely lost track of the corresponding rcu_head structures, this wait could be forever. This commit therefore also complains if this attempted recovery takes more than one second, and it also gives up when the test ends. Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 50d4b62 commit 9470a18

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

kernel/rcu/rcutorture.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2124,7 +2124,21 @@ static int rcu_torture_barrier(void *arg)
21242124
pr_err("barrier_cbs_invoked = %d, n_barrier_cbs = %d\n",
21252125
atomic_read(&barrier_cbs_invoked),
21262126
n_barrier_cbs);
2127-
WARN_ON_ONCE(1);
2127+
WARN_ON(1);
2128+
// Wait manually for the remaining callbacks
2129+
i = 0;
2130+
do {
2131+
if (WARN_ON(i++ > HZ))
2132+
i = INT_MIN;
2133+
schedule_timeout_interruptible(1);
2134+
cur_ops->cb_barrier();
2135+
} while (atomic_read(&barrier_cbs_invoked) !=
2136+
n_barrier_cbs &&
2137+
!torture_must_stop());
2138+
smp_mb(); // Can't trust ordering if broken.
2139+
if (!torture_must_stop())
2140+
pr_err("Recovered: barrier_cbs_invoked = %d\n",
2141+
atomic_read(&barrier_cbs_invoked));
21282142
} else {
21292143
n_barrier_successes++;
21302144
}

0 commit comments

Comments
 (0)