changeset 8571:d3cc20285653

8181055: PPC64: "mbind: Invalid argument" still seen after 8175813 Summary: Use numa_interleave_memory v2 api when available Reviewed-by: dholmes, shade, gromero
author zgu
date Wed, 07 Jun 2017 13:59:35 -0400
parents f04097176542
children 6bc9abf210fd 3b5410755ebd
files src/os/linux/vm/os_linux.cpp src/os/linux/vm/os_linux.hpp
diffstat 2 files changed, 21 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/os/linux/vm/os_linux.cpp	Mon Jun 26 02:04:40 2017 -0700
+++ b/src/os/linux/vm/os_linux.cpp	Wed Jun 07 13:59:35 2017 -0400
@@ -2819,11 +2819,8 @@
 extern "C" JNIEXPORT void numa_error(char *where) { }
 extern "C" JNIEXPORT int fork1() { return fork(); }
 
-
-// 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) {
@@ -2832,6 +2829,12 @@
   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,
@@ -2856,6 +2859,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,
@@ -2975,6 +2980,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;
--- a/src/os/linux/vm/os_linux.hpp	Mon Jun 26 02:04:40 2017 -0700
+++ b/src/os/linux/vm/os_linux.hpp	Wed Jun 07 13:59:35 2017 -0400
@@ -190,6 +190,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);
   // Minimum stack size a thread can be created with (allowing
   // the VM to completely create the thread and enter user code)
   static size_t min_stack_allowed;
@@ -250,6 +252,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);
@@ -261,6 +265,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;
@@ -275,6 +280,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; }
@@ -296,7 +302,10 @@
     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) {
+    // 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);
     }
   }