Skip to content

Commit f482260

Browse files
committed
8319969: os::large_page_init() turns off THPs for ZGC
Reviewed-by: stuefe, aboldtch
1 parent 3edc24a commit f482260

File tree

10 files changed

+325
-47
lines changed

10 files changed

+325
-47
lines changed

src/hotspot/os/linux/gc/z/zLargePages_linux.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,24 @@
2323

2424
#include "precompiled.hpp"
2525
#include "gc/z/zLargePages.hpp"
26+
#include "hugepages.hpp"
27+
#include "os_linux.hpp"
2628
#include "runtime/globals.hpp"
2729

2830
void ZLargePages::pd_initialize() {
31+
if (os::Linux::thp_requested()) {
32+
// Check if the OS config turned off transparent huge pages for shmem.
33+
_os_enforced_transparent_mode = HugePages::shmem_thp_info().is_disabled();
34+
_state = _os_enforced_transparent_mode ? Disabled : Transparent;
35+
return;
36+
}
37+
2938
if (UseLargePages) {
30-
if (UseTransparentHugePages) {
31-
_state = Transparent;
32-
} else {
33-
_state = Explicit;
34-
}
35-
} else {
36-
_state = Disabled;
39+
_state = Explicit;
40+
return;
3741
}
42+
43+
// Check if the OS config turned on transparent huge pages for shmem.
44+
_os_enforced_transparent_mode = HugePages::shmem_thp_info().is_forced();
45+
_state = _os_enforced_transparent_mode ? Transparent : Disabled;
3846
}

src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "gc/z/zNUMA.inline.hpp"
3333
#include "gc/z/zPhysicalMemoryBacking_linux.hpp"
3434
#include "gc/z/zSyscall_linux.hpp"
35+
#include "hugepages.hpp"
3536
#include "logging/log.hpp"
3637
#include "os_linux.hpp"
3738
#include "runtime/init.hpp"
@@ -446,8 +447,10 @@ ZErrno ZPhysicalMemoryBacking::fallocate_compat_mmap_tmpfs(zoffset offset, size_
446447
return errno;
447448
}
448449

449-
// Advise mapping to use transparent huge pages
450-
os::realign_memory((char*)addr, length, ZGranuleSize);
450+
// Maybe madvise the mapping to use transparent huge pages
451+
if (os::Linux::should_madvise_shmem_thps()) {
452+
os::Linux::madvise_transparent_huge_pages(addr, length);
453+
}
451454

452455
// Touch the mapping (safely) to make sure it's backed by memory
453456
const bool backed = safe_touch_mapping(addr, length, _block_size);

src/hotspot/os/linux/hugepages.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include "logging/log.hpp"
3030
#include "logging/logStream.hpp"
31+
#include "runtime/globals_extension.hpp"
3132
#include "runtime/os.hpp"
3233
#include "utilities/debug.hpp"
3334
#include "utilities/globalDefinitions.hpp"
@@ -227,15 +228,97 @@ void THPSupport::print_on(outputStream* os) {
227228
}
228229
}
229230

231+
ShmemTHPSupport::ShmemTHPSupport() :
232+
_initialized(false), _mode(ShmemTHPMode::unknown) {}
233+
234+
ShmemTHPMode ShmemTHPSupport::mode() const {
235+
assert(_initialized, "Not initialized");
236+
return _mode;
237+
}
238+
239+
bool ShmemTHPSupport::is_forced() const {
240+
return _mode == ShmemTHPMode::always || _mode == ShmemTHPMode::force || _mode == ShmemTHPMode::within_size;
241+
}
242+
243+
bool ShmemTHPSupport::is_enabled() const {
244+
return is_forced() || _mode == ShmemTHPMode::advise;
245+
}
246+
247+
bool ShmemTHPSupport::is_disabled() const {
248+
return _mode == ShmemTHPMode::never || _mode == ShmemTHPMode::deny || _mode == ShmemTHPMode::unknown;
249+
}
250+
251+
void ShmemTHPSupport::scan_os() {
252+
// Scan /sys/kernel/mm/transparent_hugepage/shmem_enabled
253+
// see mm/huge_memory.c
254+
_mode = ShmemTHPMode::unknown;
255+
const char* filename = "/sys/kernel/mm/transparent_hugepage/shmem_enabled";
256+
FILE* f = ::fopen(filename, "r");
257+
if (f != nullptr) {
258+
char buf[64];
259+
char* s = fgets(buf, sizeof(buf), f);
260+
assert(s == buf, "Should have worked");
261+
if (::strstr(buf, "[always]") != nullptr) {
262+
_mode = ShmemTHPMode::always;
263+
} else if (::strstr(buf, "[within_size]") != nullptr) {
264+
_mode = ShmemTHPMode::within_size;
265+
} else if (::strstr(buf, "[advise]") != nullptr) {
266+
_mode = ShmemTHPMode::advise;
267+
} else if (::strstr(buf, "[never]") != nullptr) {
268+
_mode = ShmemTHPMode::never;
269+
} else if (::strstr(buf, "[deny]") != nullptr) {
270+
_mode = ShmemTHPMode::deny;
271+
} else if (::strstr(buf, "[force]") != nullptr) {
272+
_mode = ShmemTHPMode::force;
273+
} else {
274+
assert(false, "Weird content of %s: %s", filename, buf);
275+
}
276+
fclose(f);
277+
}
278+
279+
_initialized = true;
280+
281+
LogTarget(Info, pagesize) lt;
282+
if (lt.is_enabled()) {
283+
LogStream ls(lt);
284+
print_on(&ls);
285+
}
286+
}
287+
288+
const char* ShmemTHPSupport::mode_to_string(ShmemTHPMode mode) {
289+
switch (mode) {
290+
case ShmemTHPMode::always: return "always";
291+
case ShmemTHPMode::advise: return "advise";
292+
case ShmemTHPMode::within_size: return "within_size";
293+
case ShmemTHPMode::never: return "never";
294+
case ShmemTHPMode::deny: return "deny";
295+
case ShmemTHPMode::force: return "force";
296+
case ShmemTHPMode::unknown: // Fallthrough
297+
default: return "unknown";
298+
};
299+
}
300+
301+
void ShmemTHPSupport::print_on(outputStream* os) {
302+
if (_initialized) {
303+
os->print_cr("Shared memory transparent hugepage (THP) support:");
304+
os->print_cr(" Shared memory THP mode: %s", mode_to_string(_mode));
305+
} else {
306+
os->print_cr(" unknown.");
307+
}
308+
}
309+
230310
StaticHugePageSupport HugePages::_static_hugepage_support;
231311
THPSupport HugePages::_thp_support;
312+
ShmemTHPSupport HugePages::_shmem_thp_support;
232313

233314
void HugePages::initialize() {
234315
_static_hugepage_support.scan_os();
235316
_thp_support.scan_os();
317+
_shmem_thp_support.scan_os();
236318
}
237319

238320
void HugePages::print_on(outputStream* os) {
239321
_static_hugepage_support.print_on(os);
240322
_thp_support.print_on(os);
323+
_shmem_thp_support.print_on(os);
241324
}

src/hotspot/os/linux/hugepages.hpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,58 @@ class THPSupport {
9191
void print_on(outputStream* os);
9292
};
9393

94+
enum class ShmemTHPMode { always, within_size, advise, never, deny, force, unknown };
95+
96+
// for transparent shmem hugepages
97+
class ShmemTHPSupport {
98+
bool _initialized;
99+
100+
// See /sys/kernel/mm/transparent_hugepage/shmem_enabled
101+
ShmemTHPMode _mode;
102+
103+
static const char* mode_to_string(ShmemTHPMode mode);
104+
105+
public:
106+
107+
ShmemTHPSupport();
108+
109+
// Queries the OS, fills in object
110+
void scan_os();
111+
112+
ShmemTHPMode mode() const;
113+
114+
bool is_forced() const;
115+
bool is_enabled() const;
116+
bool is_disabled() const;
117+
118+
// Printing
119+
void print_on(outputStream* os);
120+
};
121+
94122
// Umbrella static interface
95123
class HugePages : public AllStatic {
96124

97125
static StaticHugePageSupport _static_hugepage_support;
98126
static THPSupport _thp_support;
127+
static ShmemTHPSupport _shmem_thp_support;
99128

100129
public:
101130

102131
static const StaticHugePageSupport& static_info() { return _static_hugepage_support; }
103132
static const THPSupport& thp_info() { return _thp_support; }
133+
static const ShmemTHPSupport& shmem_thp_info() { return _shmem_thp_support; }
104134

105135
static size_t default_static_hugepage_size() { return _static_hugepage_support.default_hugepage_size(); }
106136
static bool supports_static_hugepages() { return default_static_hugepage_size() > 0 && !_static_hugepage_support.inconsistent(); }
107-
static THPMode thp_mode() { return _thp_support.mode(); }
137+
108138
static bool supports_thp() { return thp_mode() == THPMode::madvise || thp_mode() == THPMode::always; }
139+
static THPMode thp_mode() { return _thp_support.mode(); }
109140
static size_t thp_pagesize() { return _thp_support.pagesize(); }
110141

142+
static bool supports_shmem_thp() { return _shmem_thp_support.is_enabled(); }
143+
static ShmemTHPMode shmem_thp_mode() { return _shmem_thp_support.mode(); }
144+
static bool forced_shmem_thp() { return _shmem_thp_support.is_forced(); }
145+
111146
static void initialize();
112147
static void print_on(outputStream* os);
113148
};

0 commit comments

Comments
 (0)