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
commit 8f3c4517b1fff965f2bdedcf376dcfd91cda422b Author: Tobias Burnus <tob...@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); }