On Thu, 12 Jul 2018 16:37:26 -0400 Pavel Tatashin <pasha.tatashin@xxxxxxxxxx> wrote: > When struct pages are allocated for sparse-vmemmap VA layout, we first > try to allocate one large buffer, and than if that fails allocate struct > pages for each section as we go. > > The code that allocates buffer is uses global variables and is spread > across several call sites. > > Cleanup the code by introducing three functions to handle the global > buffer: > > sparse_buffer_init() initialize the buffer > sparse_buffer_fini() free the remaining part of the buffer > sparse_buffer_alloc() alloc from the buffer, and if buffer is empty > return NULL > > Define these functions in sparse.c instead of sparse-vmemmap.c because > later we will use them for non-vmemmap sparse allocations as well. > > ... > > +void * __meminit sparse_buffer_alloc(unsigned long size) > +{ > + void *ptr = NULL; > + > + if (sparsemap_buf) { > + ptr = (void *)ALIGN((unsigned long)sparsemap_buf, size); > + if (ptr + size > sparsemap_buf_end) > + ptr = NULL; > + else > + sparsemap_buf = ptr + size; > + } > + return ptr; > +} tweak... diff -puN mm/sparse.c~mm-sparse-abstract-sparse-buffer-allocations-fix mm/sparse.c --- a/mm/sparse.c~mm-sparse-abstract-sparse-buffer-allocations-fix +++ a/mm/sparse.c @@ -491,7 +491,7 @@ void * __meminit sparse_buffer_alloc(uns void *ptr = NULL; if (sparsemap_buf) { - ptr = (void *)ALIGN((unsigned long)sparsemap_buf, size); + ptr = PTR_ALIGN(sparsemap_buf, size); if (ptr + size > sparsemap_buf_end) ptr = NULL; else