Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Aug 2006 15:18:51 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 103449 for review
Message-ID:  <200608081518.k78FIpCi006066@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103449

Change 103449 by rdivacky@rdivacky_witten on 2006/08/08 15:18:25

	Introduce poor-mans synchronization. This ensures that linux_proc_init() is always
	called before linux_schedtail. Sometimes it happened that linux_schedtail was called
	before proc_init which caused em_find() to return NULL. Now it should be fixed (this
	and the memleak it caused).
	
	Tested by: /glibc-2.3.6/configure --disable-sanity-checks

Affected files ...

.. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#35 edit

Differences ...

==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#35 (text+ko) ====

@@ -1160,6 +1160,7 @@
 linux_proc_init(struct thread *td, pid_t child, int flags)
 {
 	struct linux_emuldata *em, *p_em;
+	struct proc *p;
 
 	/* XXX: locking? */
 	if (child != 0) {
@@ -1218,10 +1219,14 @@
 	if (child != 0) {
    	   	LIST_INSERT_HEAD(&em->shared->threads, em, threads);
 	   	EMUL_WUNLOCK(&emul_lock);
+
+		p = pfind(child);
+		PROC_UNLOCK(p);
+		/* we might have a sleeping linux_schedtail */
+		wakeup(p->p_emuldata);
 	} else
 	   	EMUL_RUNLOCK(&emul_lock);
 
-
    	return (0);
 }
 
@@ -1324,6 +1329,8 @@
 	}
 }
 
+extern int hz;		/* in subr_param.c */
+
 void
 linux_schedtail(void *arg __unused, struct proc *p)
 {
@@ -1336,10 +1343,18 @@
 	if (p->p_sysent != &elf_linux_sysvec)
 	   	return;
 
+retry:	
 	/* find the emuldata */
 	em = em_find(p->p_pid, EMUL_UNLOCKED);
 
 	if (em == NULL) {
+	   	/* We might have been called before proc_init for this process so
+		 * tsleep and be woken up by it. We use p->p_emuldata for this
+		 */
+
+	   	error = tsleep(p->p_emuldata, PLOCK, "linux_schedtail", hz);
+		if (error == 0)
+		   	goto retry;
 #ifdef	DEBUG
 	   	printf(LMSG("we didnt find emuldata for the userreting process.\n"));
 #endif



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