Skip to content

Commit 4f087ea

Browse files
btw616jmberg-intel
authored andcommitted
um: Add pthread-based helper support
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 the same memory space. Signed-off-by: Tiwei Bie <tiwei.btw@antgroup.com> Link: https://patch.msgid.link/20250319135523.97050-2-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 16a0ca5 commit 4f087ea

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

arch/um/include/shared/os.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ extern int run_helper_thread(int (*proc)(void *), void *arg,
224224
unsigned int flags, unsigned long *stack_out);
225225
extern int helper_wait(int pid);
226226

227+
struct os_helper_thread;
228+
int os_run_helper_thread(struct os_helper_thread **td_out,
229+
void *(*routine)(void *), void *arg);
230+
void os_kill_helper_thread(struct os_helper_thread *td);
231+
void os_fix_helper_thread_signals(void);
227232

228233
/* umid.c */
229234
extern int umid_file_name(char *name, char *buf, int len);

arch/um/os-Linux/helper.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <unistd.h>
99
#include <errno.h>
1010
#include <sched.h>
11+
#include <pthread.h>
1112
#include <linux/limits.h>
1213
#include <sys/socket.h>
1314
#include <sys/wait.h>
@@ -167,3 +168,65 @@ int helper_wait(int pid)
167168
} else
168169
return 0;
169170
}
171+
172+
struct os_helper_thread {
173+
pthread_t handle;
174+
};
175+
176+
int os_run_helper_thread(struct os_helper_thread **td_out,
177+
void *(*routine)(void *), void *arg)
178+
{
179+
struct os_helper_thread *td;
180+
sigset_t sigset, oset;
181+
int err, flags;
182+
183+
flags = __uml_cant_sleep() ? UM_GFP_ATOMIC : UM_GFP_KERNEL;
184+
td = uml_kmalloc(sizeof(*td), flags);
185+
if (!td)
186+
return -ENOMEM;
187+
188+
sigfillset(&sigset);
189+
if (sigprocmask(SIG_SETMASK, &sigset, &oset) < 0) {
190+
err = -errno;
191+
kfree(td);
192+
return err;
193+
}
194+
195+
err = pthread_create(&td->handle, NULL, routine, arg);
196+
197+
if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0)
198+
panic("Failed to restore the signal mask: %d", errno);
199+
200+
if (err != 0)
201+
kfree(td);
202+
else
203+
*td_out = td;
204+
205+
return -err;
206+
}
207+
208+
void os_kill_helper_thread(struct os_helper_thread *td)
209+
{
210+
pthread_cancel(td->handle);
211+
pthread_join(td->handle, NULL);
212+
kfree(td);
213+
}
214+
215+
void os_fix_helper_thread_signals(void)
216+
{
217+
sigset_t sigset;
218+
219+
sigemptyset(&sigset);
220+
221+
sigaddset(&sigset, SIGWINCH);
222+
sigaddset(&sigset, SIGPIPE);
223+
sigaddset(&sigset, SIGPROF);
224+
sigaddset(&sigset, SIGINT);
225+
sigaddset(&sigset, SIGTERM);
226+
sigaddset(&sigset, SIGCHLD);
227+
sigaddset(&sigset, SIGALRM);
228+
sigaddset(&sigset, SIGIO);
229+
sigaddset(&sigset, SIGUSR1);
230+
231+
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
232+
}

0 commit comments

Comments
 (0)