tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: _lwp_create change



In article <20170420044801.GA3505%mail.duskware.de@localhost>,
Martin Husemann  <martin%duskware.de@localhost> wrote:
>On Thu, Apr 20, 2017 at 02:29:26AM +0200, Joerg Sonnenberger wrote:
>> As discussed previously, I think the patch makes the behavior worse and
>> the Go implementation is kind of stupid as well.
>
>No comment on the patch of the go implementation, but I think that the
>code should actually do what the documentation says:
>
>	The context argument specifies the
>     initial execution context for the new LWP including signal mask, stack,
>     and machine registers.
>
>Specifying the signal stack in the create call does make sense to me.
>
>Your "makes the behaviour worse" comment was on the patch specifically?
>Can you explain?

This is a program that demonstrates that _lwp_create(2) does not behave
like the documentation states, and a patch that fixes it. Note that things
behave exactly like they did before since _lwp_makecontext() loads the
same values from the parent lwp and the current kernel version currently
ignores them...

#include <stdio.h>
#include <signal.h>
#include <lwp.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ucontext.h>

void
child(void *arg)
{
	sigset_t oset;
	sigprocmask(SIG_BLOCK, NULL, &oset);
	printf("%p arg %#x\n", arg, oset.__bits[0]);
}
int
main(int argc, char *argv[])
{
	ucontext_t uc;
	size_t ss = 32768;
	lwpid_t lid;
	void *sp = malloc(ss);
	_lwp_makecontext(&uc, child, argv, NULL, sp, ss);
	sigfillset(&uc.uc_sigmask);
	uc.uc_flags |= _UC_SIGMASK;
	_lwp_create(&uc, 0, &lid);
	printf("lid %d %#x\n", lid, uc.uc_flags);
	sleep(10000);
}

And finally the patch... I am planning to commit this soon unless someone
objects.

christos

Index: compat/linux/common/linux_sched.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_sched.c,v
retrieving revision 1.68
diff -u -u -r1.68 linux_sched.c
--- compat/linux/common/linux_sched.c	3 Jul 2015 02:24:28 -0000	1.68
+++ compat/linux/common/linux_sched.c	20 Apr 2017 10:30:57 -0000
@@ -207,7 +207,8 @@
 	}
 
 	error = lwp_create(l, p, uaddr, LWP_DETACHED | LWP_PIDLID,
-	    SCARG(uap, stack), 0, child_return, NULL, &l2, l->l_class);
+	    SCARG(uap, stack), 0, child_return, NULL, &l2, l->l_class,
+	    &l->l_sigmask, &l->l_sigstk);
 	if (__predict_false(error)) {
 		DPRINTF(("%s: lwp_create error=%d\n", __func__, error));
 		atomic_dec_uint(&nprocs);
Index: compat/netbsd32/netbsd32_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_lwp.c,v
retrieving revision 1.18
diff -u -u -r1.18 netbsd32_lwp.c
--- compat/netbsd32/netbsd32_lwp.c	15 May 2015 07:56:25 -0000	1.18
+++ compat/netbsd32/netbsd32_lwp.c	20 Apr 2017 10:30:57 -0000
@@ -55,6 +55,7 @@
 	} */
 	struct proc *p = l->l_proc;
 	ucontext32_t *newuc = NULL;
+	stack_t ss;
 	lwpid_t lid;
 	int error;
 
@@ -74,7 +75,19 @@
 	if (error)
 		goto fail;
 
-	error = do_lwp_create(l, newuc, SCARG(uap, flags), &lid);
+	const sigset_t *sigmask = newuc->uc_flags & _UC_SIGMASK ?
+	    &newuc->uc_sigmask : &l->l_sigmask;
+
+	const stack_t *sigstk;
+	if (newuc->uc_flags & _UC_STACK) {
+		ss.ss_flags = newuc->uc_stack.ss_flags;
+		ss.ss_size = newuc->uc_stack.ss_size;
+		ss.ss_sp = NETBSD32IPTR64(newuc->uc_stack.ss_sp);
+		sigstk = &ss;
+	} else
+		sigstk = &l->l_sigstk;
+
+	error = do_lwp_create(l, newuc, SCARG(uap, flags), &lid, sigmask, sigstk);
 	if (error)
 		goto fail;
 
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.441
diff -u -u -r1.441 kern_exec.c
--- kern/kern_exec.c	25 Jan 2017 17:57:14 -0000	1.441
+++ kern/kern_exec.c	20 Apr 2017 10:31:05 -0000
@@ -2531,7 +2531,7 @@
 
 	/* create LWP */
 	lwp_create(l1, p2, uaddr, 0, NULL, 0, spawn_return, spawn_data,
-	    &l2, l1->l_class);
+	    &l2, l1->l_class, &l1->l_sigmask, &l1->l_sigstk);
 	l2->l_ctxlink = NULL;	/* reset ucontext link */
 
 	/*
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_fork.c,v
retrieving revision 1.201
diff -u -u -r1.201 kern_fork.c
--- kern/kern_fork.c	31 Mar 2017 08:50:54 -0000	1.201
+++ kern/kern_fork.c	20 Apr 2017 10:31:05 -0000
@@ -434,7 +434,7 @@
 	 */
 	lwp_create(l1, p2, uaddr, (flags & FORK_PPWAIT) ? LWP_VFORK : 0,
 	    stack, stacksize, (func != NULL) ? func : child_return, arg, &l2,
-	    l1->l_class);
+	    l1->l_class, &l1->l_sigmask, &l1->l_sigstk);
 
 	/*
 	 * Inherit l_private from the parent.
Index: kern/kern_kthread.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_kthread.c,v
retrieving revision 1.41
diff -u -u -r1.41 kern_kthread.c
--- kern/kern_kthread.c	21 Apr 2015 11:10:29 -0000	1.41
+++ kern/kern_kthread.c	20 Apr 2017 10:31:05 -0000
@@ -82,7 +82,7 @@
 	}
 
 	error = lwp_create(&lwp0, &proc0, uaddr, LWP_DETACHED, NULL,
-	    0, func, arg, &l, lc);
+	    0, func, arg, &l, lc, &lwp0.l_sigmask, &lwp0.l_sigstk);
 	if (error) {
 		uvm_uarea_system_free(uaddr);
 		return error;
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.187
diff -u -u -r1.187 kern_lwp.c
--- kern/kern_lwp.c	14 Jan 2017 19:32:10 -0000	1.187
+++ kern/kern_lwp.c	20 Apr 2017 10:31:05 -0000
@@ -760,8 +760,9 @@
  */
 int
 lwp_create(lwp_t *l1, proc_t *p2, vaddr_t uaddr, int flags,
-	   void *stack, size_t stacksize, void (*func)(void *), void *arg,
-	   lwp_t **rnewlwpp, int sclass)
+    void *stack, size_t stacksize, void (*func)(void *), void *arg,
+    lwp_t **rnewlwpp, int sclass, const sigset_t *sigmask,
+    const stack_t *sigstk)
 {
 	struct lwp *l2, *isfree;
 	turnstile_t *ts;
@@ -904,8 +905,8 @@
 	} else
 		l2->l_prflag = 0;
 
-	l2->l_sigstk = l1->l_sigstk;
-	l2->l_sigmask = l1->l_sigmask;
+	l2->l_sigstk = *sigstk;
+	l2->l_sigmask = *sigmask;
 	TAILQ_INIT(&l2->l_sigpend.sp_info);
 	sigemptyset(&l2->l_sigpend.sp_set);
 
Index: kern/sys_aio.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_aio.c,v
retrieving revision 1.41
diff -u -u -r1.41 sys_aio.c
--- kern/sys_aio.c	7 Jul 2016 06:55:43 -0000	1.41
+++ kern/sys_aio.c	20 Apr 2017 10:31:05 -0000
@@ -211,7 +211,7 @@
 		return EAGAIN;
 	}
 	error = lwp_create(curlwp, p, uaddr, 0, NULL, 0, aio_worker,
-	    NULL, &l, curlwp->l_class);
+	    NULL, &l, curlwp->l_class, &curlwp->l_sigmask, &curlwp->l_sigstk);
 	if (error != 0) {
 		uvm_uarea_free(uaddr);
 		aio_exit(p, aio);
Index: kern/sys_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_lwp.c,v
retrieving revision 1.58
diff -u -u -r1.58 sys_lwp.c
--- kern/sys_lwp.c	15 Jan 2017 01:28:14 -0000	1.58
+++ kern/sys_lwp.c	20 Apr 2017 10:31:05 -0000
@@ -70,7 +70,8 @@
 }
 
 int
-do_lwp_create(lwp_t *l, void *arg, u_long flags, lwpid_t *new_lwp)
+do_lwp_create(lwp_t *l, void *arg, u_long flags, lwpid_t *new_lwp,
+    const sigset_t *sigmask, const stack_t *sigstk)
 {
 	struct proc *p = l->l_proc;
 	struct lwp *l2;
@@ -84,8 +85,8 @@
 	if (__predict_false(uaddr == 0))
 		return ENOMEM;
 
-	error = lwp_create(l, p, uaddr, flags & LWP_DETACHED,
-	    NULL, 0, p->p_emul->e_startlwp, arg, &l2, l->l_class);
+	error = lwp_create(l, p, uaddr, flags & LWP_DETACHED, NULL, 0,
+	    p->p_emul->e_startlwp, arg, &l2, l->l_class, sigmask, sigstk);
 	if (__predict_false(error)) {
 		uvm_uarea_free(uaddr);
 		return error;
@@ -152,7 +153,11 @@
 	if (error)
 		goto fail;
 
-	error = do_lwp_create(l, newuc, SCARG(uap, flags), &lid);
+	const sigset_t *sigmask = newuc->uc_flags & _UC_SIGMASK ?
+	    &newuc->uc_sigmask : &l->l_sigmask;
+	const stack_t *sigstk = newuc->uc_flags & _UC_STACK ?
+	    &newuc->uc_stack : &l->l_sigstk;
+	error = do_lwp_create(l, newuc, SCARG(uap, flags), &lid, sigmask, sigstk);
 	if (error)
 		goto fail;
 
Index: rump/librump/rumpkern/threads.c
===================================================================
RCS file: /cvsroot/src/sys/rump/librump/rumpkern/threads.c,v
retrieving revision 1.24
diff -u -u -r1.24 threads.c
--- rump/librump/rumpkern/threads.c	26 Jan 2016 23:12:18 -0000	1.24
+++ rump/librump/rumpkern/threads.c	20 Apr 2017 10:31:18 -0000
@@ -294,7 +294,8 @@
 int
 lwp_create(struct lwp *l1, struct proc *p2, vaddr_t uaddr, int flags,
            void *stack, size_t stacksize, void (*func)(void *), void *arg,
-           struct lwp **newlwpp, int sclass)
+           struct lwp **newlwpp, int sclass, const sigmask_t *sigmask,
+           const stack_t *sigstk)
 {
 	struct thrdesc *td;
 	struct lwp *l;
Index: sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.173
diff -u -u -r1.173 lwp.h
--- sys/lwp.h	8 Apr 2017 00:25:50 -0000	1.173
+++ sys/lwp.h	20 Apr 2017 10:31:23 -0000
@@ -341,7 +341,8 @@
 void	lwp_free(lwp_t *, bool, bool);
 uint64_t lwp_pctr(void);
 int	lwp_setprivate(lwp_t *, void *);
-int	do_lwp_create(lwp_t *, void *, u_long, lwpid_t *);
+int	do_lwp_create(lwp_t *, void *, u_long, lwpid_t *, const sigset_t *,
+    const stack_t *);
 
 void	lwpinit_specificdata(void);
 int	lwp_specific_key_create(specificdata_key_t *, specificdata_dtor_t);
@@ -422,8 +423,8 @@
 	return MAX(l->l_auxprio, pri);
 }
 
-int lwp_create(lwp_t *, struct proc *, vaddr_t, int,
-    void *, size_t, void (*)(void *), void *, lwp_t **, int);
+int lwp_create(lwp_t *, struct proc *, vaddr_t, int, void *, size_t,
+    void (*)(void *), void *, lwp_t **, int, const sigset_t *, const stack_t *);
 
 /*
  * XXX _MODULE



Home | Main Index | Thread Index | Old Index