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.
  */

Reply via email to