git: 7db7118976b5 - stable/14 - libthr/amd64: do not set THR_C_RUNTIME for thr_new() if the main thread did used AMD64_SET_TLSBASE
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 29 Jun 2025 00:30:01 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=7db7118976b5d8a8d981a801c0e5e5fcbccad462
commit 7db7118976b5d8a8d981a801c0e5e5fcbccad462
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-06-01 07:00:18 +0000
Commit: Konstantin Belousov <kib@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.
*/