summary refs log tree commit diff
path: root/elf/dl-tls.c
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2020-06-10 13:40:40 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2020-07-08 17:32:56 +0100
commitffb17e7ba3a5ba9632cee97330b325072fbe41dd (patch)
treebf6865a3ec36c6a818a73bee954b06568154a90f /elf/dl-tls.c
parent17796419b5fd694348cceb65c3f77601faae082c (diff)
downloadglibc-ffb17e7ba3a5ba9632cee97330b325072fbe41dd.tar.gz
glibc-ffb17e7ba3a5ba9632cee97330b325072fbe41dd.tar.xz
glibc-ffb17e7ba3a5ba9632cee97330b325072fbe41dd.zip
rtld: Avoid using up static TLS surplus for optimizations [BZ #25051]
On some targets static TLS surplus area can be used opportunistically
for dynamically loaded modules such that the TLS access then becomes
faster (TLSDESC and powerpc TLS optimization). However we don't want
all surplus TLS to be used for this optimization because dynamically
loaded modules with initial-exec model TLS can only use surplus TLS.

The new contract for surplus static TLS use is:

- libc.so can have up to 192 bytes of IE TLS,
- other system libraries together can have up to 144 bytes of IE TLS.
- Some "optional" static TLS is available for opportunistic use.

The optional TLS is now tunable: rtld.optional_static_tls, so users
can directly affect the allocated static TLS size. (Note that module
unloading with dlclose does not reclaim static TLS. After the optional
TLS runs out, TLS access is no longer optimized to use static TLS.)

The default setting of rtld.optional_static_tls is 512 so the surplus
TLS is 3*192 + 4*144 + 512 = 1664 by default, the same as before.

Fixes BZ #25051.

Tested on aarch64-linux-gnu and x86_64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'elf/dl-tls.c')
-rw-r--r--elf/dl-tls.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c
index 4e7b10edd8..772e70d0f6 100644
--- a/elf/dl-tls.c
+++ b/elf/dl-tls.c
@@ -60,8 +60,6 @@
    This should be large enough to cover runtime libraries of the
    compiler such as libgomp and libraries in libc other than libc.so.  */
 #define OTHER_IE_TLS 144
-/* Size of additional surplus TLS, placeholder for TLS optimizations.  */
-#define OPT_SURPLUS_TLS 512
 
 /* Calculate the size of the static TLS surplus, when the given
    number of audit modules are loaded.  Must be called after the
@@ -69,13 +67,15 @@
 void
 _dl_tls_static_surplus_init (size_t naudit)
 {
-  size_t nns;
+  size_t nns, opt_tls;
 
 #if HAVE_TUNABLES
   nns = TUNABLE_GET (nns, size_t, NULL);
+  opt_tls = TUNABLE_GET (optional_static_tls, size_t, NULL);
 #else
   /* Default values of the tunables.  */
   nns = 4;
+  opt_tls = 512;
 #endif
   if (nns > DL_NNS)
     nns = DL_NNS;
@@ -84,9 +84,10 @@ _dl_tls_static_surplus_init (size_t naudit)
 		      (unsigned long) naudit, (unsigned long) (DL_NNS - nns));
   nns += naudit;
 
+  GL(dl_tls_static_optional) = opt_tls;
   GLRO(dl_tls_static_surplus) = ((nns - 1) * LIBC_IE_TLS
 				 + nns * OTHER_IE_TLS
-				 + OPT_SURPLUS_TLS);
+				 + opt_tls);
 }
 
 /* Out-of-memory handler.  */