[PATCH 1/4] um: Add the pthread-based helper support
Tiwei Bie
tiwei.btw at antgroup.com
Fri Feb 21 00:40:46 PST 2025
Introduce a new set of utility functions that can be used to create
pthread-based helpers. Helper threads created in this way will ensure
thread safety for errno while sharing memory address space.
Signed-off-by: Tiwei Bie <tiwei.btw at antgroup.com>
---
arch/um/include/shared/os.h | 3 ++
arch/um/os-Linux/helper.c | 60 +++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 5babad8c5f75..1f62e793bce3 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -225,6 +225,9 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
unsigned int flags, unsigned long *stack_out);
extern int helper_wait(int pid);
+int os_run_helper_thread(void *(*routine)(void *), void *arg, void **handle_out);
+void os_kill_helper_thread(void *);
+void os_fix_helper_thread_signals(void);
/* umid.c */
extern int umid_file_name(char *name, char *buf, int len);
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index 3cb8ac63be6e..c6a0ef8beb29 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -8,6 +8,7 @@
#include <unistd.h>
#include <errno.h>
#include <sched.h>
+#include <pthread.h>
#include <linux/limits.h>
#include <sys/socket.h>
#include <sys/wait.h>
@@ -167,3 +168,62 @@ int helper_wait(int pid)
} else
return 0;
}
+
+int os_run_helper_thread(void *(*routine)(void *), void *arg, void **handle_out)
+{
+ pthread_t *td;
+ sigset_t sigset, oset;
+ int err, flags;
+
+ flags = __uml_cant_sleep() ? UM_GFP_ATOMIC : UM_GFP_KERNEL;
+ td = uml_kmalloc(sizeof(*td), flags);
+ if (!td)
+ return -ENOMEM;
+
+ sigfillset(&sigset);
+ if (sigprocmask(SIG_SETMASK, &sigset, &oset) < 0) {
+ err = -errno;
+ kfree(td);
+ return err;
+ }
+
+ err = pthread_create(td, NULL, routine, arg);
+
+ if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
+ panic("Failed to restore the signal mask: %d", errno);
+
+ if (err != 0)
+ kfree(td);
+ else
+ *handle_out = td;
+
+ return -err;
+}
+
+void os_kill_helper_thread(void *handle)
+{
+ pthread_t *td = handle;
+
+ pthread_kill(*td, SIGKILL);
+ CATCH_EINTR(pthread_join(*td, NULL));
+ kfree(td);
+}
+
+void os_fix_helper_thread_signals(void)
+{
+ sigset_t sigset;
+
+ sigemptyset(&sigset);
+
+ sigaddset(&sigset, SIGWINCH);
+ sigaddset(&sigset, SIGPIPE);
+ sigaddset(&sigset, SIGPROF);
+ sigaddset(&sigset, SIGINT);
+ sigaddset(&sigset, SIGTERM);
+ sigaddset(&sigset, SIGCHLD);
+ sigaddset(&sigset, SIGALRM);
+ sigaddset(&sigset, SIGIO);
+ sigaddset(&sigset, SIGUSR1);
+
+ pthread_sigmask(SIG_SETMASK, &sigset, NULL);
+}
--
2.34.1
More information about the linux-um
mailing list