diff mbox series

[committed] libgomp: call numa_available first when using libnuma

Message ID 9cb0b7cb-1049-68c7-e38c-c02553aae7d7@codesourcery.com
State New
Headers show
Series [committed] libgomp: call numa_available first when using libnuma | expand

Commit Message

Tobias Burnus Aug. 17, 2023, 1:32 p.m. UTC
Found when looking at libnuma/libmemkind test issues discussing
in https://gcc.gnu.org/PR111024
[The fails of the PR are not fully understood but point towards a
  buggy libmemkind or combination or libmemkind + other libraries;
  they only show up recently as before no libgomp testcase checked
  for interleaved allocation - and on newer Linux systems it does
  pass.]


Calling numa_available() just ensures that the get_mempolicy syscall
is available in the Linux kernel, which is likely the case for Linux
distros in use, but still it makes sense to play be the rules and to
check that that's indeed the case - as recommended/demanded by the
(lib)numa manpage. The call is only done once and also only when
libnuma is supposed to get used.

Committed to mainline as Rev. r14-3287-g8f3c4517b1fff9

Tobias

PS: Crossref - some more doc + libmemkind improvements could/should
eventually be done. See https://gcc.gnu.org/PR111044 for details.
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
diff mbox series

Patch

commit 8f3c4517b1fff965f2bdedcf376dcfd91cda422b
Author: Tobias Burnus <tobias@codesourcery.com>
Date:   Thu Aug 17 15:20:55 2023 +0200

    libgomp: call numa_available first when using libnuma
    
    The documentation requires that numa_available() is called and only
    when successful, other libnuma function may be called. Internally,
    it does a syscall to get_mempolicy with flag=0 (which would return
    the default policy if mode were not NULL). If this returns -1 (and
    not 0) and errno == ENOSYS, the Linux kernel does not have the
    get_mempolicy syscall function; if so, numa_available() returns -1
    (otherwise: 0).
    
    libgomp/
    
            PR libgomp/111024
            * allocator.c (gomp_init_libnuma): Call numa_available; if
            not available or not returning 0, disable libnuma usage.
---
 libgomp/allocator.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/libgomp/allocator.c b/libgomp/allocator.c
index 90f2dcb60d6..b4e50e2ad72 100644
--- a/libgomp/allocator.c
+++ b/libgomp/allocator.c
@@ -107,28 +107,39 @@  static pthread_once_t libnuma_data_once = PTHREAD_ONCE_INIT;
 
 static void
 gomp_init_libnuma (void)
 {
   void *handle = dlopen ("libnuma.so.1", RTLD_LAZY);
   struct gomp_libnuma_data *data;
 
   data = calloc (1, sizeof (struct gomp_libnuma_data));
   if (data == NULL)
     {
       if (handle)
 	dlclose (handle);
       return;
     }
+  if (handle)
+    {
+      int (*numa_available) (void);
+      numa_available
+	= (__typeof (numa_available)) dlsym (handle, "numa_available");
+      if (!numa_available || numa_available () != 0)
+	{
+	  dlclose (handle);
+	  handle = NULL;
+	}
+    }
   if (!handle)
     {
       __atomic_store_n (&libnuma_data, data, MEMMODEL_RELEASE);
       return;
     }
   data->numa_handle = handle;
   data->numa_alloc_local
     = (__typeof (data->numa_alloc_local)) dlsym (handle, "numa_alloc_local");
   data->numa_realloc
     = (__typeof (data->numa_realloc)) dlsym (handle, "numa_realloc");
   data->numa_free
     = (__typeof (data->numa_free)) dlsym (handle, "numa_free");
   __atomic_store_n (&libnuma_data, data, MEMMODEL_RELEASE);
 }