PERFORCE change 103449 for review
Roman Divacky
rdivacky at FreeBSD.org
Tue Aug 8 15:19:50 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103449
Change 103449 by rdivacky at 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
More information about the p4-projects
mailing list