RFR: JDK-8310233: Linux: THP initialization is incorrect

Thomas Stuefe stuefe at openjdk.org
Sat Jul 1 19:30:06 UTC 2023


Today, if we use UseTransparentHugePages, we assume that the static hugepage detection we do is valid for THPs:
- that THPs use the page size (in hotspot used as "default large page size") found in /proc/memlimit Hugepagesize)
- that THPs are enabled if that page size is >0.

Both assumptions are incorrect. THPs are enabled depending on the mode in `/sys/kernel/mm/transparent_hugepage/enabled` (tri-state). And the pagesize used by khugepaged is the one set in `/sys/kernel/mm/transparent_hugepage/hpage_pmd_size`. The latter can differ from the default large page size on the system (e.g. static hugepage default size could be 1g, whereas THP hugepage size is 2m).

------

About the patch:

This is a limited, minimally invasive patch to fix THP detection. The patch aims to be easy to downport. There is more work to do, which I will do in subsequent RFEs.

The patch cleanly splits off the OS-side feature detection (see hugepages.hpp) from the layer that bases decisions on that detection (os::large_page_init()).

Functionally, for *static* (non-THP) pages nothing changes. THP-mode now correctly detects THP support in the OS, and uses the correct page size (see examples below).

-------------

Example 1: System has THPs disabled, but static hugepages (1g, 2m) configured:


thomas at starfish $ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
thomas at starfish $ cat /proc/meminfo | grep Hugepage
Hugepagesize:    1048576 kB


Without patch, we incorrectly assume THPs are enabled, and that THP page size is 1G (!), which we then proceed and use as heap page size, causing the heap size to be rounded up from 512m -> 1G:


thomas at starfish $ ./images/jdk/bin/java -Xmx512m -XX:+UseLargePages -XX:+UseTransparentHugePages -Xlog:pagesize -version
[0.001s][info][pagesize] Using the default large page size: 1G
[0.001s][info][pagesize] Usable page sizes: 4k, 2M, 1G
...
[0.016s][info][pagesize] Heap:  min=1G max=1G base=0x00000000c0000000 size=1G page_size=1G


With patch, we correctly refuse to use large pages (and we log more info):


thomas at starfish $ ./images/jdk/bin/java -Xmx512m -XX:+UseLargePages -XX:+UseTransparentHugePages -Xlog:pagesize -version
[0.001s][info][pagesize] Static hugepage support: 2M, 1G (default)
[0.001s][info][pagesize]   default pagesize: 1G
[0.001s][info][pagesize] Transparent hugepage (THP) support:
[0.001s][info][pagesize]   mode: never
[0.001s][warning][pagesize] UseLargePages disabled, no large pages configured and available on the system.


----------

Example 2: System has THPs enabled, but THP page size is just *2M*, whereas the system uses a static default hugepage size of *1G*:


thomas at starfish $ cat /sys/kernel/mm/transparent_hugepage/enabled
always [madvise] never
thomas at starfish $ cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size 
2097152
thomas at starfish $ cat /proc/meminfo | grep Hugepage
Hugepagesize:    1048576 kB


Without patch, THP page size is not correctly recognized as 2M. Instead, we again use 1G as page size for the heap:


thomas at starfish $ ./images/jdk/bin/java -Xmx512m -XX:+UseLargePages -XX:+UseTransparentHugePages -Xlog:pagesize -version
[0.001s][info][pagesize] Using the default large page size: 1G
[0.001s][info][pagesize] Usable page sizes: 4k, 2M, 1G
...
[0.010s][info][pagesize] Heap:  min=1G max=1G base=0x00000000c0000000 size=1G page_size=1G


With patch, we correctly identify the THP page size as 2M, and use that for the heap:


thomas at starfish $ ./images/jdk/bin/java -Xmx512m -XX:+UseLargePages -XX:+UseTransparentHugePages -Xlog:pagesize -version
[0.001s][info][pagesize] Static hugepage support: 2M, 1G (default)
[0.001s][info][pagesize]   default pagesize: 1G
[0.001s][info][pagesize] Transparent hugepage (THP) support:
[0.001s][info][pagesize]   mode: madvise
[0.001s][info][pagesize]   pagesize: 2M
[0.001s][info][pagesize] Large page support enabled. Usable page sizes: 4k, 2M
[0.001s][info][pagesize]  Default: 2M
...
[0.010s][info][pagesize] Heap:  min=8M max=512M base=0x00000000e0000000 size=512M page_size=2M

------------

Tests: GHAs all green. Local experiments on x64 Linux on machines with 1G pages succeeded.

-------------

Commit messages:
 - remove whitespaces
 - Improve comments
 - JDK-8310233-Linux-THP-initialization-incorrect

Changes: https://git.openjdk.org/jdk/pull/14739/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=14739&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8310233
  Stats: 518 lines in 5 files changed: 387 ins; 100 del; 31 mod
  Patch: https://git.openjdk.org/jdk/pull/14739.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/14739/head:pull/14739

PR: https://git.openjdk.org/jdk/pull/14739


More information about the hotspot-dev mailing list