--- old/src/os/linux/vm/os_linux.cpp 2017-05-30 07:54:42.803846675 -0400 +++ new/src/os/linux/vm/os_linux.cpp 2017-05-30 07:54:42.717846858 -0400 @@ -2833,11 +2833,8 @@ extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } extern "C" JNIEXPORT void numa_error(char *where) { } - -// If we are running with libnuma version > 2, then we should -// be trying to use symbols with versions 1.1 -// If we are running with earlier version, which did not have symbol versions, -// we should use the base version. +// Handle request to load libnuma symbol version 1.1 (API v1). If it fails +// load symbol from base version instead. void* os::Linux::libnuma_dlsym(void* handle, const char *name) { void *f = dlvsym(handle, name, "libnuma_1.1"); if (f == NULL) { @@ -2846,6 +2843,13 @@ return f; } +// Handle request to load libnuma symbol version 1.2 (API v2) only. +// Return NULL if the symbol is not defined in this particular version. +void* os::Linux::libnuma_v2_dlsym(void* handle, const char* name) { + return dlvsym(handle, name, "libnuma_1.2"); +} + + bool os::Linux::libnuma_init() { // sched_getcpu() should be in libc. set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, @@ -2872,6 +2876,8 @@ libnuma_dlsym(handle, "numa_tonode_memory"))); set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t, libnuma_dlsym(handle, "numa_interleave_memory"))); + set_numa_interleave_memory_v2(CAST_TO_FN_PTR(numa_interleave_memory_v2_func_t, + libnuma_v2_dlsym(handle, "numa_interleave_memory"))); set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t, libnuma_dlsym(handle, "numa_set_bind_policy"))); set_numa_bitmask_isbitset(CAST_TO_FN_PTR(numa_bitmask_isbitset_func_t, @@ -2998,6 +3004,7 @@ os::Linux::numa_available_func_t os::Linux::_numa_available; os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; +os::Linux::numa_interleave_memory_v2_func_t os::Linux::_numa_interleave_memory_v2; os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy; os::Linux::numa_bitmask_isbitset_func_t os::Linux::_numa_bitmask_isbitset; os::Linux::numa_distance_func_t os::Linux::_numa_distance; --- old/src/os/linux/vm/os_linux.hpp 2017-05-30 07:54:43.090846064 -0400 +++ new/src/os/linux/vm/os_linux.hpp 2017-05-30 07:54:43.012846230 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,6 +173,8 @@ static void libpthread_init(); static bool libnuma_init(); static void* libnuma_dlsym(void* handle, const char* name); + // libnuma v2 (libnuma_1.2) symbols + static void* libnuma_v2_dlsym(void* handle, const char* name); // Return default guard size for the specified thread type static size_t default_guard_size(os::ThreadType thr_type); @@ -226,6 +228,8 @@ typedef int (*numa_available_func_t)(void); typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask); + typedef void (*numa_interleave_memory_v2_func_t)(void *start, size_t size, struct bitmask* mask); + typedef void (*numa_set_bind_policy_func_t)(int policy); typedef int (*numa_bitmask_isbitset_func_t)(struct bitmask *bmp, unsigned int n); typedef int (*numa_distance_func_t)(int node1, int node2); @@ -237,6 +241,7 @@ static numa_available_func_t _numa_available; static numa_tonode_memory_func_t _numa_tonode_memory; static numa_interleave_memory_func_t _numa_interleave_memory; + static numa_interleave_memory_v2_func_t _numa_interleave_memory_v2; static numa_set_bind_policy_func_t _numa_set_bind_policy; static numa_bitmask_isbitset_func_t _numa_bitmask_isbitset; static numa_distance_func_t _numa_distance; @@ -251,6 +256,7 @@ static void set_numa_available(numa_available_func_t func) { _numa_available = func; } static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } + static void set_numa_interleave_memory_v2(numa_interleave_memory_v2_func_t func) { _numa_interleave_memory_v2 = func; } static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; } static void set_numa_bitmask_isbitset(numa_bitmask_isbitset_func_t func) { _numa_bitmask_isbitset = func; } static void set_numa_distance(numa_distance_func_t func) { _numa_distance = func; } @@ -272,8 +278,11 @@ return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1; } static void numa_interleave_memory(void *start, size_t size) { - if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { - _numa_interleave_memory(start, size, _numa_all_nodes); + // Use v2 api if available + if (_numa_interleave_memory_v2 != NULL && _numa_all_nodes_ptr != NULL) { + _numa_interleave_memory_v2(start, size, _numa_all_nodes_ptr); + } else if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { + _numa_interleave_memory(start, size, _numa_all_nodes); } } static void numa_set_bind_policy(int policy) {