Large page use crashes the JVM on some Linux systems
B. Blaser
bsrbnd at gmail.com
Wed May 2 08:38:36 UTC 2018
Hi Claes,
On 24 April 2018 at 21:39, Claes Redestad <claes.redestad at oracle.com> wrote:
> The root issue here could very well be that the SHM sanity test is
> insufficient. Adding the same test as we already do for TLBFS seems like the
> wrong approach.
>
> I'm not the most knowledgeable about SHM, though, in fact not knowledgeable
> at all, so let's try and get you subscribed to hotspot-dev and spark a
> discussion on the list.
>
> /Claes
As suggested, I've added a SHM sanity test (derived from the TLBFS
one) which ensure that the allocated memory is using huge pages in
'/proc/self/maps'.
Does the following patch look better (tier1 seems OK)?
Thanks,
Bernard
diff --git a/src/hotspot/os/linux/os_linux.cpp
b/src/hotspot/os/linux/os_linux.cpp
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -3317,6 +3317,28 @@
return result;
}
+static bool check_hugepage(void* p) {
+ bool result = false;
+ FILE *fp = fopen("/proc/self/maps", "r");
+ if (fp) {
+ while (!feof(fp)) {
+ char chars[257];
+ long x = 0;
+ if (fgets(chars, sizeof(chars), fp)) {
+ if (sscanf(chars, "%lx-%*x", &x) == 1
+ && x == (long)p) {
+ if (strstr (chars, "hugepage")) {
+ result = true;
+ break;
+ }
+ }
+ }
+ }
+ fclose(fp);
+ }
+ return result;
+}
+
bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
bool result = false;
void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
@@ -3325,23 +3347,7 @@
if (p != MAP_FAILED) {
// We don't know if this really is a huge page or not.
- FILE *fp = fopen("/proc/self/maps", "r");
- if (fp) {
- while (!feof(fp)) {
- char chars[257];
- long x = 0;
- if (fgets(chars, sizeof(chars), fp)) {
- if (sscanf(chars, "%lx-%*x", &x) == 1
- && x == (long)p) {
- if (strstr (chars, "hugepage")) {
- result = true;
- break;
- }
- }
- }
- }
- fclose(fp);
- }
+ result = check_hugepage(p);
munmap(p, page_size);
}
@@ -3352,6 +3358,27 @@
return result;
}
+bool os::Linux::shm_sanity_check(bool warn, size_t page_size) {
+ bool result = false;
+ int shmid = shmget(IPC_PRIVATE, page_size,
SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
+ if (shmid != -1) {
+ void* p = shmat(shmid, NULL, 0);
+ shmctl(shmid, IPC_RMID, NULL);
+
+ if (p != (void*) -1) {
+ // We don't know if this really is a huge page or not.
+ result = check_hugepage(p);
+ shmdt(p);
+ }
+ }
+
+ if (warn && !result) {
+ warning("SHM is not supported by the operating system.");
+ }
+
+ return result;
+}
+
// Set the coredump_filter bits to include largepages in core dump (bit 6)
//
// From the coredump_filter documentation:
@@ -3506,6 +3533,14 @@
UseHugeTLBFS = false;
}
+ if (UseSHM) {
+ bool warn_on_failure = !FLAG_IS_DEFAULT(UseSHM);
+ if (shm_sanity_check(warn_on_failure, page_size)) {
+ return true;
+ }
+ UseSHM = false;
+ }
+
return UseSHM;
}
diff --git a/src/hotspot/os/linux/os_linux.hpp
b/src/hotspot/os/linux/os_linux.hpp
--- a/src/hotspot/os/linux/os_linux.hpp
+++ b/src/hotspot/os/linux/os_linux.hpp
@@ -99,6 +99,7 @@
static bool setup_large_page_type(size_t page_size);
static bool transparent_huge_pages_sanity_check(bool warn, size_t
pages_size);
static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
+ static bool shm_sanity_check(bool warn, size_t page_size);
static char* reserve_memory_special_shm(size_t bytes, size_t
alignment, char* req_addr, bool exec);
static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t
alignment, char* req_addr, bool exec);
diff --git a/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java
b/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java
--- a/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java
+++ b/test/hotspot/jtreg/gc/g1/TestLargePageUseForAuxMemory.java
@@ -60,7 +60,8 @@
}
long size = parseMemoryString(pageSizeStr);
- if (size != expectedSize) {
+ // Small pages may be used if no large pages are available.
+ if (size != expectedSize && size != smallPageSize) {
output.reportDiagnosticSummary();
throw new RuntimeException("Match from '" + pattern + "'
got " + size + " expected: " + expectedSize);
}
More information about the hotspot-dev
mailing list