diff options
Diffstat (limited to 'elf/dl-tls.c')
-rw-r--r-- | elf/dl-tls.c | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/elf/dl-tls.c b/elf/dl-tls.c index ca13778ca9..924ee5d989 100644 --- a/elf/dl-tls.c +++ b/elf/dl-tls.c @@ -29,10 +29,54 @@ #include <dl-tls.h> #include <ldsodefs.h> -/* Amount of excess space to allocate in the static TLS area - to allow dynamic loading of modules defining IE-model TLS data. */ -#define TLS_STATIC_SURPLUS 64 + DL_NNS * 176 +#define TUNABLE_NAMESPACE rtld +#include <dl-tunables.h> + +/* Surplus static TLS, GLRO(dl_tls_static_surplus), is used for + + - IE TLS in libc.so for all dlmopen namespaces except in the initial + one where libc.so is not loaded dynamically but at startup time, + - IE TLS in other libraries which may be dynamically loaded even in the + initial namespace, + - and optionally for optimizing dynamic TLS access. + + The maximum number of namespaces is DL_NNS, but to support that many + namespaces correctly the static TLS allocation should be significantly + increased, which may cause problems with small thread stacks due to the + way static TLS is accounted (bug 11787). + + So there is a rtld.nns tunable limit on the number of supported namespaces + that affects the size of the static TLS and by default it's small enough + not to cause problems with existing applications. The limit is not + enforced or checked: it is the user's responsibility to increase rtld.nns + if more dlmopen namespaces are used. */ + +/* Size of initial-exec TLS in libc.so. */ +#define LIBC_IE_TLS 192 +/* Size of initial-exec TLS in libraries other than libc.so. + 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 +void +_dl_tls_static_surplus_init (void) +{ + size_t nns; + +#if HAVE_TUNABLES + nns = TUNABLE_GET (nns, size_t, NULL); +#else + /* Default values of the tunables. */ + nns = 4; +#endif + if (nns > DL_NNS) + nns = DL_NNS; + GLRO(dl_tls_static_surplus) = ((nns - 1) * LIBC_IE_TLS + + nns * OTHER_IE_TLS + + OPT_SURPLUS_TLS); +} /* Out-of-memory handler. */ static void @@ -224,7 +268,8 @@ _dl_determine_tlsoffset (void) } GL(dl_tls_static_used) = offset; - GL(dl_tls_static_size) = (roundup (offset + TLS_STATIC_SURPLUS, max_align) + GL(dl_tls_static_size) = (roundup (offset + GLRO(dl_tls_static_surplus), + max_align) + TLS_TCB_SIZE); #elif TLS_DTV_AT_TP /* The TLS blocks start right after the TCB. */ @@ -268,7 +313,7 @@ _dl_determine_tlsoffset (void) } GL(dl_tls_static_used) = offset; - GL(dl_tls_static_size) = roundup (offset + TLS_STATIC_SURPLUS, + GL(dl_tls_static_size) = roundup (offset + GLRO(dl_tls_static_surplus), TLS_TCB_ALIGN); #else # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" |