Subject: Re: Mapping 2 compat linux32 syscalls on a single native one
To: Christos Zoulas <christos@zoulas.com>
From: Nicolas Joly <njoly@pasteur.fr>
List: tech-kern
Date: 02/01/2007 15:48:39
--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Jan 30, 2007 at 12:19:09PM -0500, Christos Zoulas wrote:
> 
> We want to advertise that we support NPTL (after we implement it). Each
> program can choose to use NPTL or old threads depending on $LD_ASSUME_KERNEL.
> If $LD_ASSUME_KERNEL is set to 2.6.x or not set at all then we use NPTL.
> If it is set to 2.4.x then we use the old clone based threads, like linux
> currently does.

I've been thinking about this, and tested the following.

I defined a new flag `LINUX_USE_NPTLTHREADS' which will be set in
linux_emuldata_shared flags field depending on NPTL vs. non-NPTL
needs. Syscalls that have different behaviour in both cases will check
for this flag to do their job.

For now, i set this flag in linux_sys_set_tid_address() syscall, as it
is done very early during NPTL libpthread loading (.init section), and
absent from old linux thread code. It works, but i'm not sure this is
the best way to proceed.

And, with this new behaviour, the compat linux32 emulation can
successfully use linux_sys_exit_group().

-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.

--ZGiS0Q5IWpPtfppv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="netbsd-linuxnptl.diff"

Index: sys/compat/linux/common/linux_emuldata.h
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_emuldata.h,v
retrieving revision 1.12
diff -u -r1.12 linux_emuldata.h
--- sys/compat/linux/common/linux_emuldata.h	23 Aug 2006 19:49:09 -0000	1.12
+++ sys/compat/linux/common/linux_emuldata.h	1 Feb 2007 14:18:34 -0000
@@ -58,6 +58,7 @@
 };
 
 #define LINUX_LES_INEXITGROUP	0x1	/* thread group doing exit_group() */
+#define LINUX_USE_NPTLTHREADS	0x2	/* Need to emulate NPTL threads */
 
 struct linux_emuldata {
 #if notyet
Index: sys/compat/linux/common/linux_sched.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_sched.c,v
retrieving revision 1.38
diff -u -r1.38 linux_sched.c
--- sys/compat/linux/common/linux_sched.c	5 Jan 2007 15:46:39 -0000	1.38
+++ sys/compat/linux/common/linux_sched.c	1 Feb 2007 14:18:34 -0000
@@ -366,6 +366,8 @@
 	struct linux_emuldata *led = p->p_emuldata;
 	struct linux_emuldata *e;
 
+	if (led->s->flags & LINUX_USE_NPTLTHREADS) {
+
 #ifdef DEBUG_LINUX
 	printf("%s:%d, led->s->refs = %d\n", __func__, __LINE__, led->s->refs);
 #endif
@@ -403,9 +405,11 @@
 	/* Now, kill ourselves */
 	psignal(p, SIGKILL);
 	return 0;
-#else /* LINUX_NPTL */
-	return sys_exit(l, v, retval);
+
+	}
 #endif /* LINUX_NPTL */
+
+	return sys_exit(l, v, retval);
 }
 #endif /* !__m68k__ */
 
@@ -424,6 +428,9 @@
 	led = (struct linux_emuldata *)l->l_proc->p_emuldata;
 	led->clear_tid = SCARG(uap, tid);
 
+	/* We are emulating NPTL threads */
+	led->s->flags |= LINUX_USE_NPTLTHREADS;
+
 	*retval = l->l_proc->p_pid;
 
 	return 0;

--ZGiS0Q5IWpPtfppv--