diff options
author | netchild <netchild@FreeBSD.org> | 2006-08-27 18:51:32 +0000 |
---|---|---|
committer | netchild <netchild@FreeBSD.org> | 2006-08-27 18:51:32 +0000 |
commit | c1c941b5f55fad34accb7005a7f57157947a29dc (patch) | |
tree | 670e63e8fa958647d9c7f20ca4d2224e245962c5 /sys/i386/linux | |
parent | ebafba10576cf8fa6a453a0e5e8a3f309917d6d5 (diff) | |
download | FreeBSD-src-c1c941b5f55fad34accb7005a7f57157947a29dc.zip FreeBSD-src-c1c941b5f55fad34accb7005a7f57157947a29dc.tar.gz |
Fix video playing and network connections in realplayer (and most likely
other stuff) in the osrelease=2.6.16 case:
- implement CLONE_PARENT semantic
- fix TLS loading in clone CLONE_SETTLS
- lock proc in the currently disabled part of CLONE_THREAD
I suggest to not unload the linux module after testing this, there are
some "<defunct>" processes hanging around after exiting (they aren't
with osrelease=2.4.2) and they may panic your kernel when unloading the
linux module. They are in state Z and some of them consume CPU according
to ps. But I don't trust the CPU part, the idle threads gets too much CPU
that this may be possible (accumulating idle, X and 2 defunct processes
results in 104.7%, this looks to much to be a rounding error).
Noticed by: Intron <mag@intron.ac>
Submitted by: rdivacky (in collaboration with Intron)
Tested by: Intron, netchild
Reviewed by: jhb (previous version)
Diffstat (limited to 'sys/i386/linux')
-rw-r--r-- | sys/i386/linux/linux_machdep.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index 4bb457b..73fa345 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -414,24 +414,24 @@ linux_clone(struct thread *td, struct linux_clone_args *args) } } - if (args->flags & CLONE_PARENT) { -#ifdef DEBUG - printf("linux_clone: CLONE_PARENT\n"); -#endif + if (args->flags & (CLONE_PARENT|CLONE_THREAD)) { + sx_xlock(&proctree_lock); + PROC_LOCK(p2); + proc_reparent(p2, td->td_proc->p_pptr); + PROC_UNLOCK(p2); + sx_xunlock(&proctree_lock); } - + if (args->flags & CLONE_THREAD) { /* XXX: linux mangles pgrp and pptr somehow * I think it might be this but I am not sure. */ #ifdef notyet + PROC_LOCK(p2); p2->p_pgrp = td->td_proc->p_pgrp; - p2->p_pptr = td->td_proc->p_pptr; + PROC_UNLOCK(p2); #endif exit_signal = 0; -#ifdef DEBUG - printf("linux_clone: CLONE_THREADS\n"); -#endif } if (args->flags & CLONE_CHILD_SETTID) @@ -443,6 +443,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args) em->child_clear_tid = args->child_tidptr; else em->child_clear_tid = NULL; + EMUL_UNLOCK(&emul_lock); PROC_LOCK(p2); @@ -502,13 +503,9 @@ linux_clone(struct thread *td, struct linux_clone_args *args) sd.sd_gran); #endif - /* this is taken from i386 version of cpu_set_user_tls() */ - critical_enter(); /* set %gs */ td2->td_pcb->pcb_gsd = sd; - PCPU_GET(fsgs_gdt)[1] = sd; - load_gs(GSEL(GUGS_SEL, SEL_UPL)); - critical_exit(); + td2->td_pcb->pcb_gs = GSEL(GUGS_SEL, SEL_UPL); } #ifdef DEBUG |