Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 22 Jun 2025 06:15:19 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 6b96e7a57317 - main - libthr/amd64: do not set THR_C_RUNTIME for thr_new() if the main thread did used AMD64_SET_TLSBASE
Message-ID:  <202506220615.55M6FJYl002960@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=6b96e7a5731795e76fe33df5a23edfb136f2e508

commit 6b96e7a5731795e76fe33df5a23edfb136f2e508
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-06-01 07:00:18 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-06-22 06:14:07 +0000

    libthr/amd64: do not set THR_C_RUNTIME for thr_new() if the main thread did used AMD64_SET_TLSBASE
    
    It is up to the code that organizes the runtime to properly set the
    signal handler, and to set %fsbase if libthr signal handler is to be
    called. The change should leave the CPU state on the signal handler
    entry identical to what it was before introduction of TLSBASE, for code
    that provides its own startup and thread pointer, but still calls into
    libthr as a hack.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 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 f8013ea914ed..fe80e1a73cc9 100644
--- a/lib/libthr/arch/amd64/Makefile.inc
+++ b/lib/libthr/arch/amd64/Makefile.inc
@@ -3,3 +3,5 @@
 # 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 85517c1aee70..02b73d90f006 100644
--- a/lib/libthr/arch/amd64/include/pthread_md.h
+++ b/lib/libthr/arch/amd64/include/pthread_md.h
@@ -57,4 +57,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 7e2c8d7330fc..43f84c3d0393 100644
--- a/lib/libthr/arch/i386/include/pthread_md.h
+++ b/lib/libthr/arch/i386/include/pthread_md.h
@@ -57,4 +57,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 a5bc0265ed3a..291f2d9350d9 100644
--- a/lib/libthr/arch/powerpc/include/pthread_md.h
+++ b/lib/libthr/arch/powerpc/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/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 c66a5bb3bd21..e56dbcfe30e1 100644
--- a/lib/libthr/thread/thr_create.c
+++ b/lib/libthr/thread/thr_create.c
@@ -50,6 +50,8 @@ int __getosreldate(void);
 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
@@ -164,7 +166,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 bd1474a7c6e8..64cf7d004070 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -354,7 +354,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 11afd74eea16..bca890829057 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -779,6 +779,8 @@ extern struct pthread	*_single_thread __hidden;
 
 extern bool		_thr_after_fork __hidden;
 
+extern int	__thr_new_flags;
+
 /*
  * Function prototype definitions.
  */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202506220615.55M6FJYl002960>