Wed, 07 Jun 2017 13:59:35 -0400
8181055: PPC64: "mbind: Invalid argument" still seen after 8175813
Summary: Use numa_interleave_memory v2 api when available
Reviewed-by: dholmes, shade, gromero
src/os/linux/vm/os_linux.cpp | file | annotate | diff | comparison | revisions | |
src/os/linux/vm/os_linux.hpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/os/linux/vm/os_linux.cpp Mon Jun 26 02:04:40 2017 -0700 1.2 +++ b/src/os/linux/vm/os_linux.cpp Wed Jun 07 13:59:35 2017 -0400 1.3 @@ -2819,11 +2819,8 @@ 1.4 extern "C" JNIEXPORT void numa_error(char *where) { } 1.5 extern "C" JNIEXPORT int fork1() { return fork(); } 1.6 1.7 - 1.8 -// If we are running with libnuma version > 2, then we should 1.9 -// be trying to use symbols with versions 1.1 1.10 -// If we are running with earlier version, which did not have symbol versions, 1.11 -// we should use the base version. 1.12 +// Handle request to load libnuma symbol version 1.1 (API v1). If it fails 1.13 +// load symbol from base version instead. 1.14 void* os::Linux::libnuma_dlsym(void* handle, const char *name) { 1.15 void *f = dlvsym(handle, name, "libnuma_1.1"); 1.16 if (f == NULL) { 1.17 @@ -2832,6 +2829,12 @@ 1.18 return f; 1.19 } 1.20 1.21 +// Handle request to load libnuma symbol version 1.2 (API v2) only. 1.22 +// Return NULL if the symbol is not defined in this particular version. 1.23 +void* os::Linux::libnuma_v2_dlsym(void* handle, const char* name) { 1.24 + return dlvsym(handle, name, "libnuma_1.2"); 1.25 +} 1.26 + 1.27 bool os::Linux::libnuma_init() { 1.28 // sched_getcpu() should be in libc. 1.29 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, 1.30 @@ -2856,6 +2859,8 @@ 1.31 libnuma_dlsym(handle, "numa_tonode_memory"))); 1.32 set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t, 1.33 libnuma_dlsym(handle, "numa_interleave_memory"))); 1.34 + set_numa_interleave_memory_v2(CAST_TO_FN_PTR(numa_interleave_memory_v2_func_t, 1.35 + libnuma_v2_dlsym(handle, "numa_interleave_memory"))); 1.36 set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t, 1.37 libnuma_dlsym(handle, "numa_set_bind_policy"))); 1.38 set_numa_bitmask_isbitset(CAST_TO_FN_PTR(numa_bitmask_isbitset_func_t, 1.39 @@ -2975,6 +2980,7 @@ 1.40 os::Linux::numa_available_func_t os::Linux::_numa_available; 1.41 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; 1.42 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; 1.43 +os::Linux::numa_interleave_memory_v2_func_t os::Linux::_numa_interleave_memory_v2; 1.44 os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy; 1.45 os::Linux::numa_bitmask_isbitset_func_t os::Linux::_numa_bitmask_isbitset; 1.46 os::Linux::numa_distance_func_t os::Linux::_numa_distance;
2.1 --- a/src/os/linux/vm/os_linux.hpp Mon Jun 26 02:04:40 2017 -0700 2.2 +++ b/src/os/linux/vm/os_linux.hpp Wed Jun 07 13:59:35 2017 -0400 2.3 @@ -190,6 +190,8 @@ 2.4 static void libpthread_init(); 2.5 static bool libnuma_init(); 2.6 static void* libnuma_dlsym(void* handle, const char* name); 2.7 + // libnuma v2 (libnuma_1.2) symbols 2.8 + static void* libnuma_v2_dlsym(void* handle, const char* name); 2.9 // Minimum stack size a thread can be created with (allowing 2.10 // the VM to completely create the thread and enter user code) 2.11 static size_t min_stack_allowed; 2.12 @@ -250,6 +252,8 @@ 2.13 typedef int (*numa_available_func_t)(void); 2.14 typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); 2.15 typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask); 2.16 + typedef void (*numa_interleave_memory_v2_func_t)(void *start, size_t size, struct bitmask* mask); 2.17 + 2.18 typedef void (*numa_set_bind_policy_func_t)(int policy); 2.19 typedef int (*numa_bitmask_isbitset_func_t)(struct bitmask *bmp, unsigned int n); 2.20 typedef int (*numa_distance_func_t)(int node1, int node2); 2.21 @@ -261,6 +265,7 @@ 2.22 static numa_available_func_t _numa_available; 2.23 static numa_tonode_memory_func_t _numa_tonode_memory; 2.24 static numa_interleave_memory_func_t _numa_interleave_memory; 2.25 + static numa_interleave_memory_v2_func_t _numa_interleave_memory_v2; 2.26 static numa_set_bind_policy_func_t _numa_set_bind_policy; 2.27 static numa_bitmask_isbitset_func_t _numa_bitmask_isbitset; 2.28 static numa_distance_func_t _numa_distance; 2.29 @@ -275,6 +280,7 @@ 2.30 static void set_numa_available(numa_available_func_t func) { _numa_available = func; } 2.31 static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } 2.32 static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } 2.33 + static void set_numa_interleave_memory_v2(numa_interleave_memory_v2_func_t func) { _numa_interleave_memory_v2 = func; } 2.34 static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; } 2.35 static void set_numa_bitmask_isbitset(numa_bitmask_isbitset_func_t func) { _numa_bitmask_isbitset = func; } 2.36 static void set_numa_distance(numa_distance_func_t func) { _numa_distance = func; } 2.37 @@ -296,7 +302,10 @@ 2.38 return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1; 2.39 } 2.40 static void numa_interleave_memory(void *start, size_t size) { 2.41 - if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { 2.42 + // Use v2 api if available 2.43 + if (_numa_interleave_memory_v2 != NULL && _numa_all_nodes_ptr != NULL) { 2.44 + _numa_interleave_memory_v2(start, size, _numa_all_nodes_ptr); 2.45 + } else if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { 2.46 _numa_interleave_memory(start, size, _numa_all_nodes); 2.47 } 2.48 }