RFR: 8261401: Add sanity check for UseSHM large pages similar to the one used with hugetlb large pages [v5]

Thomas Schatzl tschatzl at openjdk.java.net
Wed Feb 17 10:21:42 UTC 2021


On Mon, 15 Feb 2021 13:44:58 GMT, Stefan Johansson <sjohanss at openjdk.org> wrote:

>> When large pages are enabled on Linux (using -XX:+UseLargePages), both UseHugeTLBFS and UseSHM can be used. We prefer to use HugeTLBFS and first do a sanity check to see if this kind of large pages are available and if so we disable UseSHM.
>> 
>> The problematic part is when HugeTLBFS pages are not available, then we disable this flag and without doing any sanity check for UseSHM, we mark large pages as enabled using SHM. One big problem with this is that SHM also requires the same type of explicitly allocated huge pages as HugeTLBFS and also privileges to lock memory. So it is likely that in the case of not being able to use HugeTLBFS we probably can't use SHM either.
>> 
>> A fix for this would be to do a similar sanity check as currently done for HugeTLBFS and if it fails disable UseLargePages since we will always fail such allocation attempts anyways. 
>> 
>> The proposed sanity check consist of two part, where the first is just trying create a shared memory segment using `shmget()` with SHM_HUGETLB to use large pages. If this fails there is no idea in trying to use SHM to get large pages.
>> 
>> The second part checks if the process has privileges to lock memory or if there will be a limit for the SHM usage. I think this would be a nice addition since it will notify the user about the limit and explain why large page mappings fail. The implementation parses `/proc/self/status` to make sure the needed capability is available.
>> 
>> This change needs two tests to be updated to handle that large pages not can be disabled even when run with +UseLargePages. One of these tests are also updated in [PR#2486](https://github.com/openjdk/jdk/pull/2486) and I plan to get that integrated before this one.
>
> Stefan Johansson has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Clean up test after merge

Changes requested by tschatzl (Reviewer).

src/hotspot/os/linux/os_linux.cpp line 3574:

> 3572:     // 1. shmmax is too small for the request.
> 3573:     //    > check shmmax value: cat /proc/sys/kernel/shmmax
> 3574:     //    > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax

I'd avoid using a 32 bit constant on potentially 64 bit systems. According to that same man page, the limit on 64 bits is 127 TB which is more than the suggested 4 GB :)

The man page talks about `ULONG_MAX - 2^24` as default (for 64 bit systems?).

src/hotspot/os/linux/os_linux.cpp line 3570:

> 3568:   // Try to create a large shared memory segment.
> 3569:   int shmid = shmget(IPC_PRIVATE, page_size, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
> 3570:   if (shmid == -1) {

I think the flags should contain the `SHM_HUGE_*` flags (considering large pages) similar to hugetlbfs for proper checking to avoid the failure like in [JDK-8261636](https://bugs.openjdk.java.net/browse/JDK-8261636) reported just recently for the same reason.

According to the [man pages](https://man7.org/linux/man-pages/man2/shmget.2.html)] such flags exist.

src/hotspot/os/linux/os_linux.cpp line 3578:

> 3576:     //    > check available large pages: cat /proc/meminfo
> 3577:     //    > increase amount of large pages:
> 3578:     //          echo new_value > /proc/sys/vm/nr_hugepages

This is just my opinion, but I would prefer to refer to some generic documentation about these options (and use the "new" locations in `/sys/kernel/mm/hugepages/hugepages-*/` instead of the "legacy" /proc/sys, e.g. `https://lwn.net/Articles/376606/` - yes this is not official documentation, but the best I could find on the spot)

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

PR: https://git.openjdk.java.net/jdk/pull/2488


More information about the hotspot-dev mailing list