8206316: ZGC: Preferred tmpfs mount point not found on Debian

Reviewed-by: kbarrett, tschatzl, ehelin
This commit is contained in:
Per Lidén 2018-07-04 12:04:02 +02:00
parent e0399f6060
commit 657e35019d
3 changed files with 68 additions and 40 deletions

View File

@ -46,10 +46,6 @@
// Sysfs file for transparent huge page on tmpfs // Sysfs file for transparent huge page on tmpfs
#define ZFILENAME_SHMEM_ENABLED "/sys/kernel/mm/transparent_hugepage/shmem_enabled" #define ZFILENAME_SHMEM_ENABLED "/sys/kernel/mm/transparent_hugepage/shmem_enabled"
// Default mount points
#define ZMOUNTPOINT_TMPFS "/dev/shm"
#define ZMOUNTPOINT_HUGETLBFS "/hugepages"
// Java heap filename // Java heap filename
#define ZFILENAME_HEAP "java_heap" #define ZFILENAME_HEAP "java_heap"
@ -78,6 +74,20 @@
#define HUGETLBFS_MAGIC 0x958458f6 #define HUGETLBFS_MAGIC 0x958458f6
#endif #endif
// Preferred tmpfs mount points, ordered by priority
static const char* z_preferred_tmpfs_mountpoints[] = {
"/dev/shm",
"/run/shm",
NULL
};
// Preferred hugetlbfs mount points, ordered by priority
static const char* z_preferred_hugetlbfs_mountpoints[] = {
"/dev/hugepages",
"/hugepages",
NULL
};
static int z_memfd_create(const char *name, unsigned int flags) { static int z_memfd_create(const char *name, unsigned int flags) {
return syscall(__NR_memfd_create, name, flags); return syscall(__NR_memfd_create, name, flags);
} }
@ -165,11 +175,15 @@ int ZBackingFile::create_mem_fd(const char* name) const {
} }
int ZBackingFile::create_file_fd(const char* name) const { int ZBackingFile::create_file_fd(const char* name) const {
const char* const filesystem = ZLargePages::is_explicit() ? ZFILESYSTEM_HUGETLBFS : ZFILESYSTEM_TMPFS; const char* const filesystem = ZLargePages::is_explicit()
const char* const mountpoint = ZLargePages::is_explicit() ? ZMOUNTPOINT_HUGETLBFS : ZMOUNTPOINT_TMPFS; ? ZFILESYSTEM_HUGETLBFS
: ZFILESYSTEM_TMPFS;
const char** const preferred_mountpoints = ZLargePages::is_explicit()
? z_preferred_hugetlbfs_mountpoints
: z_preferred_tmpfs_mountpoints;
// Find mountpoint // Find mountpoint
ZBackingPath path(filesystem, mountpoint); ZBackingPath path(filesystem, preferred_mountpoints);
if (path.get() == NULL) { if (path.get() == NULL) {
log_error(gc, init)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem); log_error(gc, init)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
return -1; return -1;

View File

@ -33,13 +33,13 @@
// Mount information, see proc(5) for more details. // Mount information, see proc(5) for more details.
#define PROC_SELF_MOUNTINFO "/proc/self/mountinfo" #define PROC_SELF_MOUNTINFO "/proc/self/mountinfo"
ZBackingPath::ZBackingPath(const char* filesystem, const char* preferred_path) { ZBackingPath::ZBackingPath(const char* filesystem, const char** preferred_mountpoints) {
if (ZPath != NULL) { if (ZPath != NULL) {
// Use specified path // Use specified path
_path = strdup(ZPath); _path = strdup(ZPath);
} else { } else {
// Find suitable path // Find suitable path
_path = find_mountpoint(filesystem, preferred_path); _path = find_mountpoint(filesystem, preferred_mountpoints);
} }
} }
@ -52,8 +52,8 @@ char* ZBackingPath::get_mountpoint(const char* line, const char* filesystem) con
char* line_mountpoint = NULL; char* line_mountpoint = NULL;
char* line_filesystem = NULL; char* line_filesystem = NULL;
// Parse line and return a newly allocated string containing the mountpoint if // Parse line and return a newly allocated string containing the mount point if
// the line contains a matching filesystem and the mountpoint is accessible by // the line contains a matching filesystem and the mount point is accessible by
// the current user. // the current user.
if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 || if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
strcmp(line_filesystem, filesystem) != 0 || strcmp(line_filesystem, filesystem) != 0 ||
@ -68,7 +68,7 @@ char* ZBackingPath::get_mountpoint(const char* line, const char* filesystem) con
return line_mountpoint; return line_mountpoint;
} }
void ZBackingPath::get_mountpoints(ZArray<char*>* mountpoints, const char* filesystem) const { void ZBackingPath::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {
FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r"); FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
if (fd == NULL) { if (fd == NULL) {
ZErrno err; ZErrno err;
@ -98,37 +98,45 @@ void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
mountpoints->clear(); mountpoints->clear();
} }
char* ZBackingPath::find_mountpoint(const char* filesystem, const char* preferred_mountpoint) const { char* ZBackingPath::find_preferred_mountpoint(const char* filesystem,
char* path = NULL; ZArray<char*>* mountpoints,
ZArray<char*> mountpoints; const char** preferred_mountpoints) const {
// Find preferred mount point
get_mountpoints(&mountpoints, filesystem); ZArrayIterator<char*> iter1(mountpoints);
for (char* mountpoint; iter1.next(&mountpoint);) {
if (mountpoints.size() == 0) { for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {
// No filesystem found if (!strcmp(mountpoint, *preferred)) {
log_error(gc, init)("Failed to find an accessible %s filesystem", filesystem);
} else if (mountpoints.size() == 1) {
// One filesystem found
path = strdup(mountpoints.at(0));
} else if (mountpoints.size() > 1) {
// More than one filesystem found
ZArrayIterator<char*> iter(&mountpoints);
for (char* mountpoint; iter.next(&mountpoint);) {
if (!strcmp(mountpoint, preferred_mountpoint)) {
// Preferred mount point found // Preferred mount point found
path = strdup(mountpoint); return strdup(mountpoint);
break; }
} }
} }
if (path == NULL) {
// Preferred mount point not found // Preferred mount point not found
log_error(gc, init)("More than one %s filesystem found:", filesystem); log_error(gc, init)("More than one %s filesystem found:", filesystem);
ZArrayIterator<char*> iter2(&mountpoints); ZArrayIterator<char*> iter2(mountpoints);
for (char* mountpoint; iter2.next(&mountpoint);) { for (char* mountpoint; iter2.next(&mountpoint);) {
log_error(gc, init)(" %s", mountpoint); log_error(gc, init)(" %s", mountpoint);
} }
}
return NULL;
}
char* ZBackingPath::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {
char* path = NULL;
ZArray<char*> mountpoints;
get_mountpoints(filesystem, &mountpoints);
if (mountpoints.size() == 0) {
// No mount point found
log_error(gc, init)("Failed to find an accessible %s filesystem", filesystem);
} else if (mountpoints.size() == 1) {
// One mount point found
path = strdup(mountpoints.at(0));
} else {
// More than one mount point found
path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);
} }
free_mountpoints(&mountpoints); free_mountpoints(&mountpoints);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,13 +31,19 @@ class ZBackingPath : public StackObj {
private: private:
char* _path; char* _path;
char* get_mountpoint(const char* line, const char* filesystem) const; char* get_mountpoint(const char* line,
void get_mountpoints(ZArray<char*>* mountpoints, const char* filesystem) const; const char* filesystem) const;
void get_mountpoints(const char* filesystem,
ZArray<char*>* mountpoints) const;
void free_mountpoints(ZArray<char*>* mountpoints) const; void free_mountpoints(ZArray<char*>* mountpoints) const;
char* find_mountpoint(const char* filesystem, const char* preferred_mountpoint) const; char* find_preferred_mountpoint(const char* filesystem,
ZArray<char*>* mountpoints,
const char** preferred_mountpoints) const;
char* find_mountpoint(const char* filesystem,
const char** preferred_mountpoints) const;
public: public:
ZBackingPath(const char* filesystem, const char* preferred_path); ZBackingPath(const char* filesystem, const char** preferred_mountpoints);
~ZBackingPath(); ~ZBackingPath();
const char* get() const; const char* get() const;