diff options
author | Joel Fernandes (Google) <joel@joelfernandes.org> | 2020-11-18 11:15:41 -0500 |
---|---|---|
committer | Paul E. McKenney <paulmck@kernel.org> | 2021-01-06 16:24:19 -0800 |
commit | b4e6039e8af8c20dfbbdfcaebfcbd7c9d9ffe713 (patch) | |
tree | a739b9f1aef750d312a7b0002a8db189c197477e /kernel/rcu/tree.c | |
parent | 3afe7fa535491ecd0382c3968dc2349602bff8a2 (diff) | |
download | linux-stable-b4e6039e8af8c20dfbbdfcaebfcbd7c9d9ffe713.tar.gz linux-stable-b4e6039e8af8c20dfbbdfcaebfcbd7c9d9ffe713.tar.bz2 linux-stable-b4e6039e8af8c20dfbbdfcaebfcbd7c9d9ffe713.zip |
rcu/segcblist: Add debug checks for segment lengths
This commit adds debug checks near the end of rcu_do_batch() that emit
warnings if an empty rcu_segcblist structure has non-zero segment counts,
or, conversely, if a non-empty structure has all-zero segment counts.
Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
[ paulmck: Fix queue/segment-length checks. ]
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Diffstat (limited to 'kernel/rcu/tree.c')
-rw-r--r-- | kernel/rcu/tree.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 6bf269c91393..8086c0467c15 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2434,6 +2434,7 @@ int rcutree_dead_cpu(unsigned int cpu) static void rcu_do_batch(struct rcu_data *rdp) { int div; + bool __maybe_unused empty; unsigned long flags; const bool offloaded = rcu_segcblist_is_offloaded(&rdp->cblist); struct rcu_head *rhp; @@ -2548,9 +2549,12 @@ static void rcu_do_batch(struct rcu_data *rdp) * The following usually indicates a double call_rcu(). To track * this down, try building with CONFIG_DEBUG_OBJECTS_RCU_HEAD=y. */ - WARN_ON_ONCE(count == 0 && !rcu_segcblist_empty(&rdp->cblist)); + empty = rcu_segcblist_empty(&rdp->cblist); + WARN_ON_ONCE(count == 0 && !empty); WARN_ON_ONCE(!IS_ENABLED(CONFIG_RCU_NOCB_CPU) && - count != 0 && rcu_segcblist_empty(&rdp->cblist)); + count != 0 && empty); + WARN_ON_ONCE(count == 0 && rcu_segcblist_n_segment_cbs(&rdp->cblist) != 0); + WARN_ON_ONCE(!empty && rcu_segcblist_n_segment_cbs(&rdp->cblist) == 0); rcu_nocb_unlock_irqrestore(rdp, flags); |