Skip to content

mm/vmalloc: stop truncating byte counts derived from nr_pages

Artem Lytkin linux-mm lkml 2 versions – In review

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v2 Latest3 patches 1 replyIn review
  2. v12 patches 3 repliesSuperseded

Changes in v2 from the cover letter

- rebased on mm-new
- 3/3: the changelog separates what is reachable, what is latent and what is merely unexercised, and answers the 16 TiB question directly
- 3/3: the note on the mapping path no longer calls the int *nr cursor a cap, since it is an overflow and not a bound, and no longer claims that every user outside mm/vmalloc.c only indexes or shifts the count. Three of them pass it to a narrower parameter, which is now named
- 1/3: dropped the claim that alloc_large_system_hash() cannot reach a 4 GiB area. Its cap is a sixteenth of memory, so it can on a 64 GiB machine, just not without an explicit table size on the command line

Patches in v2 No applies recorded yet

#Subject and filesSizeRepliesApplied
1/3mm/vmalloc: fix 32-bit truncation of the area size in vread_iter()mm/vmalloc.c+1 -10 replies
2/3mm/vmalloc: fix 32-bit truncation in the vrealloc() grow-in-place checkmm/vmalloc.c+1 -10 replies
3/3mm/vmalloc: make vm_struct.nr_pages an unsigned longinclude/linux/vmalloc.h mm/vmalloc.c+31 -330 replies

Reviews trailers per patch

None of the 3 patches has a Reviewed-by or Acked-by of their own; the series has one for all of them.

PatchUladzislau Rezki (Sony)
SeriesR-b R-b
1/3
2/3
3/3

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.

Read the v2 thread

Cover letter [PATCH v2 0/3] mm/vmalloc: stop truncating byte counts derived from nr_pages

Andrew asked for a v2 of the nr_pages widening, rebased on mm-new, with the changelog clarified on what has actually been observed.

The widening reverts the two casts added by the patches I sent on 25 July, so it needs those in the tree first, and they are not in mm-new, mm-unstable or mm-hotfixes-unstable today. They are here as 1/3 and 2/3 so that the series applies and Sashiko can chew on it. 2/3 is byte for byte what I sent; 1/3 has one corrected sentence in its changelog and the same one-line diff.

Keeping the three separate is deliberate. 1/3 is a one-line fix for a v7.2 regression and carries a Fixes: tag, so it is the part that wants to go in on its own. 3/3 is a type change across the file.

On what has been seen in practice, since v1 of 3/3 read as though the bug had been hit: it has not. There is no report behind any of this, I found it reading the code. What is reachable is the 4 GiB truncation in vread_iter(), which needs a machine with more than 4 GiB of memory and nothing else, and makes /proc/kcore return zeros for such an area while reporting a successful read. The vrealloc() case has the same cause but stays latent, no in-tree caller grows an allocation that far. The rest is unexercised, and 3/3 now separates the two thresholds instead of lumping them together: 2^32 pages, where the field truncates, is 16 TiB and out of reach of any hardware, while 2^31, where the plain int page indexes break, is 8 TiB and only out of reach because nothing asks for an area that large.

Changes in v2:
- rebased on mm-new
- 3/3: the changelog separates what is reachable, what is latent and what is merely unexercised, and answers the 16 TiB question directly
- 3/3: the note on the mapping path no longer calls the int *nr cursor a cap, since it is an overflow and not a bound, and no longer claims that every user outside mm/vmalloc.c only indexes or shifts the count. Three of them pass it to a narrower parameter, which is now named
- 1/3: dropped the claim that alloc_large_system_hash() cannot reach a 4 GiB area. Its cap is a sixteenth of memory, so it can on a 64 GiB machine, just not without an explicit table size on the command line

v1 of 3/3:
https://lore.kernel.org/linux-mm/[email protected]/
1/3 and 2/3 as first posted:
https://lore.kernel.org/linux-mm/[email protected]/

Checked on x86-64: vmlinux and modules build clean, and mm/vmalloc.c plus every file that touches vm_struct::nr_pages are clean at W=1, with HAVE_ARCH_HUGE_VMALLOC, NUMA, KEXEC_HANDOVER, DEBUG_KMEMLEAK, DMA_API_DEBUG and PROC_KCORE enabled. sizeof(struct vm_struct) measured against the real headers: 72 bytes before and after with HAVE_ARCH_HUGE_VMALLOC=n, 72 to 80 with it enabled, both sizes inside the kmalloc-96 bucket that __get_vm_area_node() already allocates from.

Artem Lytkin (3):
mm/vmalloc: fix 32-bit truncation of the area size in vread_iter() mm/vmalloc: fix 32-bit truncation in the vrealloc() grow-in-place
check
mm/vmalloc: make vm_struct.nr_pages an unsigned long

 include/linux/vmalloc.h |  2 +-
 mm/vmalloc.c            | 58 ++++++++++++++++++++---------------------
 2 files changed, 29 insertions(+), 31 deletions(-)

base-commit: eee677bbc48890b2bcaa42ea7942478302937a09

Signature · 1 line
2.43.0