[PATCH 1/1] rcu: fix shrink budget underflow in lazy_rcu_shrink_scan

Longlong Xia <[email protected]>
Newsgroups org.kernel.vger.rcu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
From: Longlong Xia <[email protected]>

The lazy RCU shrinker decremented sc->nr_to_scan (unsigned long)
and then tested the result with <= 0.  When a single CPU's lazy
callback count exceeds the remaining budget, the subtraction wraps
to a large positive value and the <= 0 comparison, which is
equivalent to == 0 for an unsigned type, never fires again.  The
scan loop then iterates through every nocb CPU instead of honouring
the reclaim budget.

Reorder the logic to compare _count against nr_to_scan before
subtracting, so the loop exits as soon as the budget is met.

Fixes: c945b4da7a448 ("rcu: Shrinker for lazy rcu")
Assisted-by: Zcode:GLM-5.2
Signed-off-by: Longlong Xia <[email protected]>
---
 kernel/rcu/tree_nocb.h | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
index 19bb42672baf..afc3ab84cc47 100644
--- a/kernel/rcu/tree_nocb.h
+++ b/kernel/rcu/tree_nocb.h
@@ -1332,10 +1332,11 @@ lazy_rcu_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
 		rcu_nocb_try_flush_bypass(rdp, jiffies);
 		rcu_nocb_unlock_irqrestore(rdp, flags);
 		wake_nocb_gp(rdp);
-		sc->nr_to_scan -= _count;
 		count += _count;
-		if (sc->nr_to_scan <= 0)
+
+		if (_count >= sc->nr_to_scan)
 			break;
+		sc->nr_to_scan -= _count;
 	}
 
 	mutex_unlock(&rcu_state.nocb_mutex);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.