Re: [PATCH] [v2] mm/vmscan: avoid false-positive -Wuninitialized warning

David Laight
2026-04-14T21:05:35Z

On Tue, 14 Apr 2026 08:51:58 +0200
Arnd Bergmann <arnd@kernel.org> wrote:

> From: Arnd Bergmann <arnd@arndb.de>
>
> When the -fsanitize=bounds sanitizer is enabled, gcc-16 sometimes runs
> into a corner case in the read_ctrl_pos() pos function, where it sees
> possible undefined behavior from the 'tier' index overflowing, presumably
> in the case that this was called with a negative tier:
>
> In function 'get_tier_idx',
> inlined from 'isolate_folios' at mm/vmscan.c:4671:14:
> mm/vmscan.c: In function 'isolate_folios':
> mm/vmscan.c:4645:29: error: 'pv.refaulted' is used uninitialized [-Werror=uninitialized]
>
> Part of the problem seems to be that read_ctrl_pos() has unusual calling
> conventions since commit 37a260870f2c ("mm/mglru: rework type selection")
> where passing MAX_NR_TIERS makes it accumulate all tiers but passing a
> smaller positive number makes it read a single tier instead.

We've had issues with that code before, might have been related to the min().
Unless that function is inlined (and the compiler generates a sane loop)
the generated code will be completely horrid.

If this code is executed in any kind of 'hot path' it should really be
done differently.
It isn't as though there are many callers; and one want to process
all the tiers - but not in the same way.

The code isn't even that readable.

David

>
> Shut up the warning by adding a fake initialization to the two instances
> of this variable that can run into that corner case.
>
> Link: https://lore.kernel.org/all/CAJHvVcjtFW86o5FoQC8MMEXCHAC0FviggaQsd5EmiCHP+1fBpg@mail.gmail.com/
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> v2: replace the earlier more invasive cleanup with a trivial
> workaround
> ---
> mm/vmscan.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index d3312c51f3f2..f829435d2807 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -4760,7 +4760,7 @@ static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
> static int get_tier_idx(struct lruvec *lruvec, int type)
> {
> int tier;
> - struct ctrl_pos sp, pv;
> + struct ctrl_pos sp, pv = {};
>
> /*
> * To leave a margin for fluctuations, use a larger gain factor (2:3).
> @@ -4779,7 +4779,7 @@ static int get_tier_idx(struct lruvec *lruvec, int type)
>
> static int get_type_to_scan(struct lruvec *lruvec, int swappiness)
> {
> - struct ctrl_pos sp, pv;
> + struct ctrl_pos sp, pv = {};
>
> if (swappiness <= MIN_SWAPPINESS + 1)
> return LRU_GEN_FILE;