diff --git a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp index d0c06e2ebf1..3acaa9ab8f9 100644 --- a/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp +++ b/src/hotspot/os/bsd/gc/z/zNUMA_bsd.cpp @@ -46,3 +46,7 @@ uint32_t ZNUMA::memory_id(uintptr_t addr) { // NUMA support not enabled, assume everything belongs to node zero return 0; } + +int ZNUMA::numa_id_to_node(uint32_t numa_id) { + ShouldNotCallThis(); +} diff --git a/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp b/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp index 74e69655940..ab7498b313c 100644 --- a/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp @@ -32,12 +32,35 @@ #include "runtime/os.hpp" #include "utilities/debug.hpp" +static uint* z_numa_id_to_node = nullptr; +static uint32_t* z_node_to_numa_id = nullptr; + void ZNUMA::pd_initialize() { _enabled = UseNUMA; + size_t configured_nodes = 0; + + if (UseNUMA) { + const size_t max_nodes = os::Linux::numa_num_configured_nodes(); + z_numa_id_to_node = NEW_C_HEAP_ARRAY(uint, max_nodes, mtGC); + configured_nodes = os::numa_get_leaf_groups(z_numa_id_to_node, 0); + + z_node_to_numa_id = NEW_C_HEAP_ARRAY(uint32_t, max_nodes, mtGC); + + // Fill the array with invalid NUMA ids + for (uint32_t i = 0; i < max_nodes; i++) { + z_node_to_numa_id[i] = (uint32_t)-1; + } + + // Fill the reverse mappings + for (uint32_t i = 0; i < configured_nodes; i++) { + z_node_to_numa_id[z_numa_id_to_node[i]] = i; + } + } + // UseNUMA and is_faked() are mutually excluded in zArguments.cpp. _count = UseNUMA - ? os::Linux::numa_max_node() + 1 + ? configured_nodes : !FLAG_IS_DEFAULT(ZFakeNUMA) ? ZFakeNUMA : 1; // No NUMA nodes @@ -54,7 +77,7 @@ uint32_t ZNUMA::id() { return 0; } - return os::Linux::get_node_by_cpu(ZCPU::id()); + return z_node_to_numa_id[os::Linux::get_node_by_cpu(ZCPU::id())]; } uint32_t ZNUMA::memory_id(uintptr_t addr) { @@ -63,14 +86,21 @@ uint32_t ZNUMA::memory_id(uintptr_t addr) { return 0; } - uint32_t id = (uint32_t)-1; + int node = -1; - if (ZSyscall::get_mempolicy((int*)&id, nullptr, 0, (void*)addr, MPOL_F_NODE | MPOL_F_ADDR) == -1) { + if (ZSyscall::get_mempolicy(&node, nullptr, 0, (void*)addr, MPOL_F_NODE | MPOL_F_ADDR) == -1) { ZErrno err; fatal("Failed to get NUMA id for memory at " PTR_FORMAT " (%s)", addr, err.to_string()); } - assert(id < _count, "Invalid NUMA id"); + DEBUG_ONLY(const int max_nodes = os::Linux::numa_num_configured_nodes();) + assert(node < max_nodes, "NUMA node is out of bounds node=%d, max=%d", node, max_nodes); - return id; + return z_node_to_numa_id[node]; +} + +int ZNUMA::numa_id_to_node(uint32_t numa_id) { + assert(numa_id < _count, "NUMA id out of range 0 <= %ud <= %ud", numa_id, _count); + + return (int)z_numa_id_to_node[numa_id]; } diff --git a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp index 84dfcbd6614..25ffd0b8078 100644 --- a/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp +++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp @@ -629,7 +629,7 @@ retry: size_t ZPhysicalMemoryBacking::commit_numa_preferred(zbacking_offset offset, size_t length, uint32_t numa_id) const { // Setup NUMA policy to allocate memory from a preferred node - os::Linux::numa_set_preferred((int)numa_id); + os::Linux::numa_set_preferred(ZNUMA::numa_id_to_node(numa_id)); const size_t committed = commit_default(offset, length); diff --git a/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp b/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp index dc7521dde56..e2bd6803584 100644 --- a/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp +++ b/src/hotspot/os/windows/gc/z/zNUMA_windows.cpp @@ -46,3 +46,7 @@ uint32_t ZNUMA::memory_id(uintptr_t addr) { // NUMA support not enabled, assume everything belongs to node zero return 0; } + +int ZNUMA::numa_id_to_node(uint32_t numa_id) { + ShouldNotCallThis(); +} diff --git a/src/hotspot/share/gc/z/zNUMA.hpp b/src/hotspot/share/gc/z/zNUMA.hpp index de74086b10a..838a114c210 100644 --- a/src/hotspot/share/gc/z/zNUMA.hpp +++ b/src/hotspot/share/gc/z/zNUMA.hpp @@ -53,6 +53,8 @@ public: static size_t calculate_share(uint32_t numa_id, size_t total, size_t granule = ZGranuleSize, uint32_t ignore_count = 0); static const char* to_string(); + + static int numa_id_to_node(uint32_t numa_id); }; #endif // SHARE_GC_Z_ZNUMA_HPP diff --git a/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp b/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp index 1a38efb89fd..2e7a97028ff 100644 --- a/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp +++ b/src/hotspot/share/gc/z/zPhysicalMemoryManager.cpp @@ -108,7 +108,7 @@ void ZPhysicalMemoryManager::try_enable_uncommit(size_t min_capacity, size_t max // Test if uncommit is supported by the operating system by committing // and then uncommitting a granule. const ZVirtualMemory vmem(zoffset(0), ZGranuleSize); - if (!commit(vmem, (uint32_t)-1) || !uncommit(vmem)) { + if (!commit(vmem, 0) || !uncommit(vmem)) { log_info_p(gc, init)("Uncommit: Implicitly Disabled (Not supported by operating system)"); FLAG_SET_ERGO(ZUncommit, false); return; @@ -293,7 +293,7 @@ void ZPhysicalMemoryManager::map(const ZVirtualMemory& vmem, uint32_t numa_id) c // Setup NUMA preferred for large pages if (ZNUMA::is_enabled() && ZLargePages::is_explicit()) { - os::numa_make_local((char*)addr, size, (int)numa_id); + os::numa_make_local((char*)addr, size, ZNUMA::numa_id_to_node(numa_id)); } }