Re: [PATCH 1/1] rcu: fix shrink budget underflow in lazy_rcu_shrink_scan
From: Paul E. McKenney
Date: Thu Aug 27 2026 - 14:00:31 EST
On Mon, Aug 24, 2026 at 09:31:42PM +0800, Longlong Xia wrote:
> From: Longlong Xia <xialonglong@xxxxxxxxxx>
>
> 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 <xialonglong@xxxxxxxxxx>
Good catch, and plausible fix. Queued for further review and testing.
Frederic, thoughts?
Thanx, Paul
> ---
> 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
>