The branch stable/14 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=7db7118976b5d8a8d981a801c0e5e5fcbccad462
commit 7db7118976b5d8a8d981a801c0e5e5fcbccad462 Author: Konstantin Belousov <k...@freebsd.org> AuthorDate: 2025-06-01 07:00:18 +0000 Commit: Konstantin Belousov <k...@freebsd.org> CommitDate: 2025-06-29 00:29:12 +0000 libthr/amd64: do not set THR_C_RUNTIME for thr_new() if the main thread did used AMD64_SET_TLSBASE (cherry picked from commit 6b96e7a5731795e76fe33df5a23edfb136f2e508) --- lib/libthr/arch/aarch64/include/pthread_md.h | 2 ++ lib/libthr/arch/amd64/Makefile.inc | 2 ++ lib/libthr/arch/amd64/amd64/thr_machdep.c | 48 ++++++++++++++++++++++++++++ lib/libthr/arch/amd64/include/pthread_md.h | 2 ++ lib/libthr/arch/arm/include/pthread_md.h | 2 ++ lib/libthr/arch/i386/include/pthread_md.h | 2 ++ lib/libthr/arch/powerpc/include/pthread_md.h | 2 ++ lib/libthr/arch/riscv/include/pthread_md.h | 2 ++ lib/libthr/thread/thr_create.c | 4 ++- lib/libthr/thread/thr_init.c | 2 +- lib/libthr/thread/thr_private.h | 2 ++ 11 files changed, 68 insertions(+), 2 deletions(-) diff --git a/lib/libthr/arch/aarch64/include/pthread_md.h b/lib/libthr/arch/aarch64/include/pthread_md.h index 305abed55d3c..4316955f1d3d 100644 --- a/lib/libthr/arch/aarch64/include/pthread_md.h +++ b/lib/libthr/arch/aarch64/include/pthread_md.h @@ -54,4 +54,6 @@ _thr_resolve_machdep(void) { } +#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb) + #endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libthr/arch/amd64/Makefile.inc b/lib/libthr/arch/amd64/Makefile.inc index 24e5dd7c9b03..9b8d21e5f880 100644 --- a/lib/libthr/arch/amd64/Makefile.inc +++ b/lib/libthr/arch/amd64/Makefile.inc @@ -6,3 +6,5 @@ SRCS+= _umtx_op_err.S # the extra context switch cost. This can measurably impact # performance when the application also does not use enough SSE. CFLAGS+=${CFLAGS_NO_SIMD} + +SRCS+= thr_machdep.c diff --git a/lib/libthr/arch/amd64/amd64/thr_machdep.c b/lib/libthr/arch/amd64/amd64/thr_machdep.c new file mode 100644 index 000000000000..d23e1689779c --- /dev/null +++ b/lib/libthr/arch/amd64/amd64/thr_machdep.c @@ -0,0 +1,48 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. + * + */ + +#define _WANT_P_OSREL +#include <sys/param.h> +#include <errno.h> +#include <machine/sysarch.h> + +#include "libc_private.h" +#include "thr_private.h" + +void +__thr_setup_tsd(struct pthread *thread) +{ + void *base; + int error; + + if (__getosreldate() < P_OSREL_TLSBASE) { + amd64_set_tlsbase(thread->tcb); + return; + } + + /* + * Make tlsbase handling more compatible with code, like Go + * runtime, which wants to manage fsbase itself, and which do + * not need assistance in setting fsbase for signal handlers. + * + * If the main thread did not used amd64_set_tlsbase(), which + * means that rtld/libc was not utilized, do not use + * amd64_set_tlsbase() either. Also do not mark new threads + * as using C runtime with the THR_C_RUNTIME flag. + */ + error = sysarch(AMD64_GET_TLSBASE, &base); + if (error != 0 && errno == ESRCH) { + __thr_new_flags &= ~THR_C_RUNTIME; + amd64_set_fsbase(thread->tcb); + } else { + amd64_set_tlsbase(thread->tcb); + } +} diff --git a/lib/libthr/arch/amd64/include/pthread_md.h b/lib/libthr/arch/amd64/include/pthread_md.h index 5b1486b151c0..ff0dd218516f 100644 --- a/lib/libthr/arch/amd64/include/pthread_md.h +++ b/lib/libthr/arch/amd64/include/pthread_md.h @@ -59,4 +59,6 @@ _thr_resolve_machdep(void) { } +void __thr_setup_tsd(struct pthread *thread); + #endif diff --git a/lib/libthr/arch/arm/include/pthread_md.h b/lib/libthr/arch/arm/include/pthread_md.h index d616868bdee4..b90568e249ee 100644 --- a/lib/libthr/arch/arm/include/pthread_md.h +++ b/lib/libthr/arch/arm/include/pthread_md.h @@ -48,4 +48,6 @@ _get_curthread(void) return (NULL); } +#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb) + #endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libthr/arch/i386/include/pthread_md.h b/lib/libthr/arch/i386/include/pthread_md.h index cb9af559db32..2bddea3d7f16 100644 --- a/lib/libthr/arch/i386/include/pthread_md.h +++ b/lib/libthr/arch/i386/include/pthread_md.h @@ -59,4 +59,6 @@ _thr_resolve_machdep(void) { } +#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb) + #endif diff --git a/lib/libthr/arch/powerpc/include/pthread_md.h b/lib/libthr/arch/powerpc/include/pthread_md.h index 31fa9820b26a..262c27858beb 100644 --- a/lib/libthr/arch/powerpc/include/pthread_md.h +++ b/lib/libthr/arch/powerpc/include/pthread_md.h @@ -56,4 +56,6 @@ _thr_resolve_machdep(void) { } +#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb) + #endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libthr/arch/riscv/include/pthread_md.h b/lib/libthr/arch/riscv/include/pthread_md.h index baddfe3ecb22..01dcc9c02b8c 100644 --- a/lib/libthr/arch/riscv/include/pthread_md.h +++ b/lib/libthr/arch/riscv/include/pthread_md.h @@ -61,4 +61,6 @@ _thr_resolve_machdep(void) { } +#define __thr_setup_tsd(thread) _tcb_set((thread)->tcb) + #endif /* _PTHREAD_MD_H_ */ diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c index 84bbd36ed28d..d8d590ed02b7 100644 --- a/lib/libthr/thread/thr_create.c +++ b/lib/libthr/thread/thr_create.c @@ -46,6 +46,8 @@ static int create_stack(struct pthread_attr *pattr); static void thread_start(struct pthread *curthread); +int __thr_new_flags = THR_C_RUNTIME; + __weak_reference(_pthread_create, pthread_create); int @@ -160,7 +162,7 @@ _pthread_create(pthread_t * __restrict thread, param.tls_size = sizeof(struct tcb); param.child_tid = &new_thread->tid; param.parent_tid = &new_thread->tid; - param.flags = THR_C_RUNTIME; + param.flags = __thr_new_flags; if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) param.flags |= THR_SYSTEM_SCOPE; if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c index 80f7c05ee5ce..13a2e403af3b 100644 --- a/lib/libthr/thread/thr_init.c +++ b/lib/libthr/thread/thr_init.c @@ -350,7 +350,7 @@ _libpthread_init(struct pthread *curthread) _thread_active_threads = 1; /* Setup the thread specific data */ - _tcb_set(curthread->tcb); + __thr_setup_tsd(curthread); if (first) { _thr_initial = curthread; diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h index a81452e2a251..508328482f80 100644 --- a/lib/libthr/thread/thr_private.h +++ b/lib/libthr/thread/thr_private.h @@ -776,6 +776,8 @@ extern struct pthread *_single_thread __hidden; extern bool _thr_after_fork __hidden; +extern int __thr_new_flags; + /* * Function prototype definitions. */