Skip to content

Commit

Permalink
8319969: os::large_page_init() turns off THPs for ZGC
Browse files Browse the repository at this point in the history
Reviewed-by: stuefe, aboldtch
  • Loading branch information
stefank committed Dec 6, 2023
1 parent 3edc24a commit f482260
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 47 deletions.
22 changes: 15 additions & 7 deletions src/hotspot/os/linux/gc/z/zLargePages_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,24 @@

#include "precompiled.hpp"
#include "gc/z/zLargePages.hpp"
#include "hugepages.hpp"
#include "os_linux.hpp"
#include "runtime/globals.hpp"

void ZLargePages::pd_initialize() {
if (os::Linux::thp_requested()) {
// Check if the OS config turned off transparent huge pages for shmem.
_os_enforced_transparent_mode = HugePages::shmem_thp_info().is_disabled();
_state = _os_enforced_transparent_mode ? Disabled : Transparent;
return;
}

if (UseLargePages) {
if (UseTransparentHugePages) {
_state = Transparent;
} else {
_state = Explicit;
}
} else {
_state = Disabled;
_state = Explicit;
return;
}

// Check if the OS config turned on transparent huge pages for shmem.
_os_enforced_transparent_mode = HugePages::shmem_thp_info().is_forced();
_state = _os_enforced_transparent_mode ? Transparent : Disabled;
}
7 changes: 5 additions & 2 deletions src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "gc/z/zNUMA.inline.hpp"
#include "gc/z/zPhysicalMemoryBacking_linux.hpp"
#include "gc/z/zSyscall_linux.hpp"
#include "hugepages.hpp"
#include "logging/log.hpp"
#include "os_linux.hpp"
#include "runtime/init.hpp"
Expand Down Expand Up @@ -446,8 +447,10 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_tmpfs(zoffset offset, size_
return errno;
}

// Advise mapping to use transparent huge pages
os::realign_memory((char*)addr, length, ZGranuleSize);
// Maybe madvise the mapping to use transparent huge pages
if (os::Linux::should_madvise_shmem_thps()) {
os::Linux::madvise_transparent_huge_pages(addr, length);
}

// Touch the mapping (safely) to make sure it's backed by memory
const bool backed = safe_touch_mapping(addr, length, _block_size);
Expand Down
83 changes: 83 additions & 0 deletions src/hotspot/os/linux/hugepages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
Expand Down Expand Up @@ -227,15 +228,97 @@ void THPSupport::print_on(outputStream* os) {
}
}

ShmemTHPSupport::ShmemTHPSupport() :
_initialized(false), _mode(ShmemTHPMode::unknown) {}

ShmemTHPMode ShmemTHPSupport::mode() const {
assert(_initialized, "Not initialized");
return _mode;
}

bool ShmemTHPSupport::is_forced() const {
return _mode == ShmemTHPMode::always || _mode == ShmemTHPMode::force || _mode == ShmemTHPMode::within_size;
}

bool ShmemTHPSupport::is_enabled() const {
return is_forced() || _mode == ShmemTHPMode::advise;
}

bool ShmemTHPSupport::is_disabled() const {
return _mode == ShmemTHPMode::never || _mode == ShmemTHPMode::deny || _mode == ShmemTHPMode::unknown;
}

void ShmemTHPSupport::scan_os() {
// Scan /sys/kernel/mm/transparent_hugepage/shmem_enabled
// see mm/huge_memory.c
_mode = ShmemTHPMode::unknown;
const char* filename = "/sys/kernel/mm/transparent_hugepage/shmem_enabled";
FILE* f = ::fopen(filename, "r");
if (f != nullptr) {
char buf[64];
char* s = fgets(buf, sizeof(buf), f);
assert(s == buf, "Should have worked");
if (::strstr(buf, "[always]") != nullptr) {
_mode = ShmemTHPMode::always;
} else if (::strstr(buf, "[within_size]") != nullptr) {
_mode = ShmemTHPMode::within_size;
} else if (::strstr(buf, "[advise]") != nullptr) {
_mode = ShmemTHPMode::advise;
} else if (::strstr(buf, "[never]") != nullptr) {
_mode = ShmemTHPMode::never;
} else if (::strstr(buf, "[deny]") != nullptr) {
_mode = ShmemTHPMode::deny;
} else if (::strstr(buf, "[force]") != nullptr) {
_mode = ShmemTHPMode::force;
} else {
assert(false, "Weird content of %s: %s", filename, buf);
}
fclose(f);
}

_initialized = true;

LogTarget(Info, pagesize) lt;
if (lt.is_enabled()) {
LogStream ls(lt);
print_on(&ls);
}
}

const char* ShmemTHPSupport::mode_to_string(ShmemTHPMode mode) {
switch (mode) {
case ShmemTHPMode::always: return "always";
case ShmemTHPMode::advise: return "advise";
case ShmemTHPMode::within_size: return "within_size";
case ShmemTHPMode::never: return "never";
case ShmemTHPMode::deny: return "deny";
case ShmemTHPMode::force: return "force";
case ShmemTHPMode::unknown: // Fallthrough
default: return "unknown";
};
}

void ShmemTHPSupport::print_on(outputStream* os) {
if (_initialized) {
os->print_cr("Shared memory transparent hugepage (THP) support:");
os->print_cr(" Shared memory THP mode: %s", mode_to_string(_mode));
} else {
os->print_cr(" unknown.");
}
}

StaticHugePageSupport HugePages::_static_hugepage_support;
THPSupport HugePages::_thp_support;
ShmemTHPSupport HugePages::_shmem_thp_support;

void HugePages::initialize() {
_static_hugepage_support.scan_os();
_thp_support.scan_os();
_shmem_thp_support.scan_os();
}

void HugePages::print_on(outputStream* os) {
_static_hugepage_support.print_on(os);
_thp_support.print_on(os);
_shmem_thp_support.print_on(os);
}
37 changes: 36 additions & 1 deletion src/hotspot/os/linux/hugepages.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,58 @@ class THPSupport {
void print_on(outputStream* os);
};

enum class ShmemTHPMode { always, within_size, advise, never, deny, force, unknown };

// for transparent shmem hugepages
class ShmemTHPSupport {
bool _initialized;

// See /sys/kernel/mm/transparent_hugepage/shmem_enabled
ShmemTHPMode _mode;

static const char* mode_to_string(ShmemTHPMode mode);

public:

ShmemTHPSupport();

// Queries the OS, fills in object
void scan_os();

ShmemTHPMode mode() const;

bool is_forced() const;
bool is_enabled() const;
bool is_disabled() const;

// Printing
void print_on(outputStream* os);
};

// Umbrella static interface
class HugePages : public AllStatic {

static StaticHugePageSupport _static_hugepage_support;
static THPSupport _thp_support;
static ShmemTHPSupport _shmem_thp_support;

public:

static const StaticHugePageSupport& static_info() { return _static_hugepage_support; }
static const THPSupport& thp_info() { return _thp_support; }
static const ShmemTHPSupport& shmem_thp_info() { return _shmem_thp_support; }

static size_t default_static_hugepage_size() { return _static_hugepage_support.default_hugepage_size(); }
static bool supports_static_hugepages() { return default_static_hugepage_size() > 0 && !_static_hugepage_support.inconsistent(); }
static THPMode thp_mode() { return _thp_support.mode(); }

static bool supports_thp() { return thp_mode() == THPMode::madvise || thp_mode() == THPMode::always; }
static THPMode thp_mode() { return _thp_support.mode(); }
static size_t thp_pagesize() { return _thp_support.pagesize(); }

static bool supports_shmem_thp() { return _shmem_thp_support.is_enabled(); }
static ShmemTHPMode shmem_thp_mode() { return _shmem_thp_support.mode(); }
static bool forced_shmem_thp() { return _shmem_thp_support.is_forced(); }

static void initialize();
static void print_on(outputStream* os);
};
Expand Down

1 comment on commit f482260

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.