The fastpath of synchronize_srcu_atomic() should always be taken
because readers always disable preemption.  Therefore, the fact that
synchronize_srcu_atomic() is running at all should mean that all readers
have ended.

But there are always bugs.  And responding to a usage bug with a
too-short SRCU grace period, and thus possibly corrupting memory
is at best a sadistic response so such a bug.  For this reason,
synchronize_srcu_atomic() explicitly waits for readers.  Except that
it does so silently, possibly failing to flag this bug.  This commit
therefore adds a splat if synchronize_srcu_atomic() fails to take the
early exit.

Signed-off-by: Paul E. McKenney <[email protected]>
---
 kernel/rcu/srcutiny.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/rcu/srcutiny.c b/kernel/rcu/srcutiny.c
index c6a2b74ae9d6..99f8bfd98b04 100644
--- a/kernel/rcu/srcutiny.c
+++ b/kernel/rcu/srcutiny.c
@@ -375,6 +375,14 @@ void synchronize_srcu_atomic(struct srcu_struct *ssp)
                return;
        }
 
+       // Because readers disable preemption, we should never get here.
+       // However, a splat and some spinning is usually preferable to
+       // memory corruption due to a too-short grace period.  There is
+       // the possibility that this will hang if the preempted reader is
+       // not looked upon favorably by the scheduler, but this is still
+       // preferable to memory corruption.
+       WARN_ON_ONCE(1);
+
        // Wait to drive a grace period or for someone else to do it
        // for us while we are lazily preempted.
        while (ssp->srcu_atomic_gp_flag) {
-- 
2.40.1


Reply via email to