> With a machine with 3 TB (more than 2 TB memory). If you use vmalloc to > allocate > 2 TB memory, the array_size below will be overflowed. How was this observed? Is there any know userspace operation which causes the kernel to try to vmalloc such a large hunk of memory? [Frank] The Dell PowerEdge R740/R940 can have up to 3TB/6TB memory. installed. Our application requires reserve consecutive memory in the kernel space and protected from userspace programs. ---------------------------------------------------------------------------------------------------- OK, thanks. Against current mainline your proposed change would look like this, yes? [Frank] Yes. This will support up to less than 16 TB. If you want to support more than 16 TB, we need to expand nr_pages to unsigned long as Matthew pointed out. Will it be possible to add this to kernel 3.10.0-957.27.2.el7.x86_64? Thanks, Frank On Tue, Nov 3, 2020 at 7:27 PM Andrew Morton wrote: > (switched to email. Please respond via emailed reply-to-all, not via the > bugzilla web interface). > > On Tue, 03 Nov 2020 18:50:07 +0000 bugzilla-daemon@bugzilla.kernel.org > wrote: > > > https://bugzilla.kernel.org/show_bug.cgi?id=210023 > > > > Bug ID: 210023 > > Summary: Crash when allocating > 2 TB memory > > Product: Memory Management > > Version: 2.5 > > Kernel Version: 3.10.0-957.27.2.el7.x86_64 > > Hardware: All > > OS: Linux > > Tree: Mainline > > Status: NEW > > Severity: blocking > > Priority: P1 > > Component: Slab Allocator > > Assignee: akpm@linux-foundation.org > > Reporter: hsinhuiwu@gmail.com > > Regression: No > > > > With a machine with 3 TB (more than 2 TB memory). If you use vmalloc to > > allocate > 2 TB memory, the array_size below will be overflowed. > > How was this observed? > > Is there any know userspace operation which causes the kernel to try to > vmalloc such a large hunk of memory? > > > The array_size is an unsigned int and can only be used to allocate less > than 2 > > TB memory. If you pass 2*1028*1028*1024*1024 = 2 * 2^40 in the argument > of > > vmalloc. The array_size will become 2*2^31 = 2^32. The 2^32 cannot be > store > > with a 32 bit integer. > > > > The fix is to change the type of array_size to unsigned long. > > > > vmalloc.c > > > > 1762 void *vmalloc(unsigned long size) > > 1763 { > > 1764 return __vmalloc_node_flags(size, NUMA_NO_NODE, > > 1765 GFP_KERNEL | __GFP_HIGHMEM); > > 1766 } > > OK, thanks. Against current mainline your proposed change would look > like this, yes? > > --- a/mm/vmalloc.c~a > +++ a/mm/vmalloc.c > @@ -2461,9 +2461,11 @@ static void *__vmalloc_area_node(struct > { > const gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | > __GFP_ZERO; > unsigned int nr_pages = get_vm_area_size(area) >> PAGE_SHIFT; > - unsigned int array_size = nr_pages * sizeof(struct page *), i; > + unsigned long array_size > + unsigned int i; > struct page **pages; > > + array_size = (unsigned long)nr_pages * sizeof(struct page *); > gfp_mask |= __GFP_NOWARN; > if (!(gfp_mask & (GFP_DMA | GFP_DMA32))) > gfp_mask |= __GFP_HIGHMEM; > _ > >