Mesa (main): Use initial-exec TLS for glibc only, enable TLS elsewhere

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Nov 20 18:20:07 UTC 2021


Module: Mesa
Branch: main
Commit: 8570a2a280587a1e43ac11ad46ad62dfdd6c7b39
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8570a2a280587a1e43ac11ad46ad62dfdd6c7b39

Author: Alex Xu (Hello71) <alex_y_xu at yahoo.ca>
Date:   Thu Sep  2 11:58:32 2021 -0400

Use initial-exec TLS for glibc only, enable TLS elsewhere

It is not portable to use initial-exec TLS in dlopened libraries. glibc
and FreeBSD allocate extra memory for extra initial-exec variables
specifically for libGL, but other libcs including musl do not.

Keep initial-exec disabled on FreeBSD since it is apparently broken for
some reason:

https://gitlab.freedesktop.org/mesa/mesa/-/issues/966#note_394512
https://github.com/jbeich/mesa/commit/81dbdb15d55054242eded0eb2f32621d583c1aaf

Enable TLS on OpenBSD and Haiku based on the u_thread.h comment that
emutls is better than pthread_getspecific, which seems plausible given
that emutls has strictly more information to work with.

Fixes #966.

Acked-by: Tapani Pälli <tapani.palli at intel.com>
Acked-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12722>

---

 meson.build         |  7 ++-----
 src/mapi/entry.c    | 28 ++++++++++++++--------------
 src/util/u_thread.h | 16 ++++++----------
 3 files changed, 22 insertions(+), 29 deletions(-)

diff --git a/meson.build b/meson.build
index cf2b5f4b939..a7ace23677c 100644
--- a/meson.build
+++ b/meson.build
@@ -508,15 +508,12 @@ foreach platform : _platforms
   pre_args += '-DHAVE_ at 0@_PLATFORM'.format(platform.to_upper())
 endforeach
 
-# Android uses emutls for versions <= P/28. For USE_ELF_TLS we need ELF TLS.
 use_elf_tls = false
-if (not ['freebsd', 'openbsd', 'haiku'].contains(host_machine.system()) and
-    (not with_platform_android or get_option('platform-sdk-version') >= 29) and
-    (not with_platform_windows or not with_shared_glapi))
+if not with_platform_windows or not with_shared_glapi
   pre_args += '-DUSE_ELF_TLS'
   use_elf_tls = true
 
-  if with_platform_android
+  if with_platform_android and get_option('platform-sdk-version') >= 29
     # By default the NDK compiler, at least, emits emutls references instead of
     # ELF TLS, even when building targeting newer API levels.  Make it actually do
     # ELF TLS instead.
diff --git a/src/mapi/entry.c b/src/mapi/entry.c
index 7ff3c8f8c8c..b120eae31a1 100644
--- a/src/mapi/entry.c
+++ b/src/mapi/entry.c
@@ -31,6 +31,7 @@
 #include "entry.h"
 #include "u_current.h"
 #include "util/u_endian.h"
+#include "util/u_thread.h"
 
 #define _U_STRINGIFY(x) #x
 #define U_STRINGIFY(x) _U_STRINGIFY(x)
@@ -45,20 +46,19 @@
 #define ENTRY_CURRENT_TABLE_GET U_STRINGIFY(u_current_get_table_internal)
 #endif
 
-#if defined(USE_X86_ASM) && defined(__GNUC__)
-#   ifdef USE_ELF_TLS
-#      include "entry_x86_tls.h"
-#   else                 
-#      include "entry_x86_tsd.h"
-#   endif
-#elif defined(USE_X86_64_ASM) && defined(__GNUC__) && defined(USE_ELF_TLS)
-#   include "entry_x86-64_tls.h"
-#elif defined(USE_PPC64LE_ASM) && defined(__GNUC__) && UTIL_ARCH_LITTLE_ENDIAN
-#   ifdef USE_ELF_TLS
-#      include "entry_ppc64le_tls.h"
-#   else
-#      include "entry_ppc64le_tsd.h"
-#   endif
+/* REALLY_INITIAL_EXEC implies USE_ELF_TLS and __GNUC__ */
+/* Use TSD stubs for non-IE ELF TLS even though first access is slower because
+ * future accesses will be patched */
+#if defined(USE_X86_ASM) && defined(REALLY_INITIAL_EXEC)
+#include "entry_x86_tls.h"
+#elif defined(USE_X86_ASM) && !defined(GLX_X86_READONLY_TEXT) && defined(__GNUC__)
+#include "entry_x86_tsd.h"
+#elif defined(USE_X86_64_ASM) && defined(REALLY_INITIAL_EXEC)
+#include "entry_x86-64_tls.h"
+#elif defined(USE_PPC64LE_ASM) && UTIL_ARCH_LITTLE_ENDIAN && defined(REALLY_INITIAL_EXEC)
+#include "entry_ppc64le_tls.h"
+#elif defined(USE_PPC64LE_ASM) && UTIL_ARCH_LITTLE_ENDIAN && defined(__GNUC__)
+#include "entry_ppc64le_tsd.h"
 #else
 
 static inline const struct _glapi_table *
diff --git a/src/util/u_thread.h b/src/util/u_thread.h
index 0fb474f32ba..a4215452d35 100644
--- a/src/util/u_thread.h
+++ b/src/util/u_thread.h
@@ -75,19 +75,15 @@
  * still want to use normal TLS (which involves a function call, but not the
  * expensive pthread_getspecific() or its equivalent).
  */
+#ifdef USE_ELF_TLS
 #ifdef _MSC_VER
 #define __THREAD_INITIAL_EXEC __declspec(thread)
-#elif defined(ANDROID)
-/* Android 29 gained ELF TLS support, but it doesn't support initial-exec and
- * it will throw:
- *
- *     dlopen failed: TLS symbol "(null)" in dlopened
- *     "/vendor/lib64/egl/libEGL_mesa.so" referenced from
- *     "/vendor/lib64/egl/libEGL_mesa.so" using IE access model.
- */
-#define __THREAD_INITIAL_EXEC __thread
-#else
+#elif defined(__GLIBC__)
 #define __THREAD_INITIAL_EXEC __thread __attribute__((tls_model("initial-exec")))
+#define REALLY_INITIAL_EXEC
+#else
+#define __THREAD_INITIAL_EXEC __thread
+#endif
 #endif
 
 static inline int



More information about the mesa-commit mailing list