<dwmw2> why doesn't lockdep catch us calling synchronize_srcu() with a lock held, and elsewhere obtaining that lock within an srcu critical region ("read lock") ? Because synchronize_srcu() doesn't acquire the lock, merely checks that it isn't held. Would this work? Not even compile tested. You can put my SoB on this if it works. diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index ca4b5dcec675..e9c2ab8369c0 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -1267,11 +1267,11 @@ static void __synchronize_srcu(struct srcu_struct *ssp, bool do_norm) { struct rcu_synchronize rcu; - RCU_LOCKDEP_WARN(lockdep_is_held(ssp) || - lock_is_held(&rcu_bh_lock_map) || + rcu_lock_acquire(&ssp->dep_map); + RCU_LOCKDEP_WARN(lock_is_held(&rcu_bh_lock_map) || lock_is_held(&rcu_lock_map) || lock_is_held(&rcu_sched_lock_map), - "Illegal synchronize_srcu() in same-type SRCU (or in RCU) read-side critical section"); + "Illegal synchronize_srcu() in RCU read-side critical section"); if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE) return; @@ -1282,6 +1282,7 @@ static void __synchronize_srcu(struct srcu_struct *ssp, bool do_norm) __call_srcu(ssp, &rcu.head, wakeme_after_rcu, do_norm); wait_for_completion(&rcu.completion); destroy_rcu_head_on_stack(&rcu.head); + rcu_lock_release(&ssp->dep_map); /* * Make sure that later code is ordered after the SRCU grace