Re: [PATCH v4] mm/vmalloc: make vm_struct.nr_pages an unsigned long

Andrew Morton <[email protected]>
Newsgroups org.kvack.linux-mm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Sat,  1 Aug 2026 14:49:15 +0300 Artem Lytkin <[email protected]> wrote:

> vm_struct::nr_pages is an unsigned int, and the file keeps deriving byte
> counts from it as nr_pages << PAGE_SHIFT. A shift is evaluated in the type
> of its promoted left operand, so those are 32-bit arithmetic and wrap at
> 4 GiB of bytes, which is 2^20 pages. Every site depends on a cast being
> remembered; vmap() has one, two recent commits did not. vread_iter() then
> computes a size of zero for a 4 GiB VM_ALLOC area and /proc/kcore returns
> it as zeros while reporting a successful read, which drgn, crash or gdb
> cannot tell from real memory, and the vrealloc() grow-in-place check
> declines a request that would have fit.
> 
> Widen the field so the class of bug goes away instead of one site at a
> time. Everything feeding or consuming it widens too: vm_area_alloc_pages()
> and its accumulators, nr_small_pages, new_nr_pages and old_nr_pages, the
> index range of vm_area_free_pages(), and three page indexes that were
> plain int. Five casts go. Two prints needed fixing as well, %u in
> vmalloc_dump_obj() and %d for the unsigned field in vmalloc_info_show().
> 
> No bug report behind this, I found it reading the code. The 4 GiB wrap
> needs only a machine with over 4 GiB of memory. Neither larger threshold
> is a practical concern: 2^32 pages, where the field itself truncates, is
> 16 TiB and beyond what hardware can populate, and 2^31, where the plain
> int indexes break, is 8 TiB and larger than anything in the tree asks for.
> The int *nr cursor in the mapping path is unchanged and is separate work.
> Users outside mm/vmalloc.c need no change either. Those handing the count
> to a narrower parameter cannot drive it near 2^31, and
> kho_preserve_vmalloc() stores it into a 32-bit ABI field that still
> receives the same low bits; above 2^32 pages the truncation just moves out
> of vm_struct into that store.
> 
> sizeof(struct vm_struct) on x86-64 stays 72 bytes with
> CONFIG_HAVE_ARCH_HUGE_VMALLOC=n and goes from 72 to 80 with it enabled,
> both inside the kmalloc-96 bucket it already comes from.

Thanks.

Ulad, AI review suggests that vrealloc() has an issue handling
__GFP_ZERO.  Can you please check?

	https://sashiko.dev/#/patchset/[email protected]
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.