[RFC] Stack allocation, hugepages and RSS implications

Florian Weimer fweimer@redhat.com
Thu Mar 9 10:54:42 GMT 2023


* Cupertino Miranda via Libc-alpha:

> Hi everyone,
>
> For performance purposes, one of ours in-house applications requires to enable
> TRANSPARENT_HUGEPAGES_ALWAYS option in linux kernel, actually making the
> kernel to force all of the big enough and alligned memory allocations to
> reside in hugepages.  I believe the reason behind this decision is to
> have more control on data location.
>
> For stack allocation, it seems that hugepages make resident set size
> (RSS) increase significantly, and without any apparent benefit, as the
> huge page will be split in small pages even before leaving glibc stack
> allocation code.
>
> As an example, this is what happens in case of a pthread_create with 2MB
> stack size:
>  1. mmap request for the 2MB allocation with PROT_NONE;
>       a huge page is "registered" by the kernel
>  2. the thread descriptor is writen in the end of the stack.
>       this will trigger a page exception in the kernel which will make the actual
>       memory allocation of the 2MB.
>  3. an mprotect changes protection on the guard (one of the small pages of the
>     allocated space):
>       at this point the kernel needs to break the 2MB page into many small pages
>       in order to change the protection on that memory region.
>       This will eliminate any benefit of having small pages for stack allocation,
>       but also makes RSS to be increaded by 2MB even though nothing was
>       written to most of the small pages.
>
> As an exercise I added __madvise(..., MADV_NOHUGEPAGE) right after the
> __mmap in nptl/allocatestack.c. As expected, RSS was significantly
> reduced for the application.

Interesting.  I did not expect to get hugepages right out of mmap.  I
would have expected subsequent coalescing by khugepaged, taking actual
stack usage into account.  But over-allocating memory might be
beneficial, see below.

(Something must be happening between step 1 & 2 to make the writes
possible.)

> In any case, I wonder if there is an actual use case where an hugepage would
> survive glibc stack allocation and will bring an actual benefit.

It can reduce TLB misses.  The first-level TLB might only have 64
entries for 4K pages, for example.  If the working set on the stack
(including the TCB) needs more than a couple of pages, it might
beneficial to use a 2M page and use just one TLB entry.

In your case, if your stacks are quite small, maybe you can just
allocate slightly less than 2 MiB?

The other question is whether the reported RSS is real, or if the kernel
will recover zero stack pages on memory pressure.

Thanks,
Florian



More information about the Libc-alpha mailing list