From owner-p4-projects@FreeBSD.ORG Fri Aug 11 10:33:13 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 01FF416A4DF; Fri, 11 Aug 2006 10:33:13 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id B70BC16A4E1 for ; Fri, 11 Aug 2006 10:33:12 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5E7A843D55 for ; Fri, 11 Aug 2006 10:33:12 +0000 (GMT) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k7BAXCEE055975 for ; Fri, 11 Aug 2006 10:33:12 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7BAXBDf055963 for perforce@freebsd.org; Fri, 11 Aug 2006 10:33:11 GMT (envelope-from rdivacky@FreeBSD.org) Date: Fri, 11 Aug 2006 10:33:11 GMT Message-Id: <200608111033.k7BAXBDf055963@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 103631 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Aug 2006 10:33:13 -0000 http://perforce.freebsd.org/chv.cgi?CH=103631 Change 103631 by rdivacky@rdivacky_witten on 2006/08/11 10:33:01 A bunch of bugs fixed from run with INVARIANTS/WITNESS o in linux_proc_init shuffle the code to never malloc with locks held o in linux_proc_exit unlock before doing futex stuff o in linux_proc_exit move free-ing of shared after removing thread from list there o the same in linux_proc_exec + addition of thread removal from list o in linux_schedtail unlock before copyout o in linux_set_tid_address change the exit_group -> set_tid_address in debug o in linux_exit_group remove the debuging code whicih let only 10 threads to be killed also change that to use psignal() instead of kill() Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#38 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#38 (text+ko) ==== @@ -1167,6 +1167,18 @@ /* non-exec call */ MALLOC(em, struct linux_emuldata *, sizeof *em, M_LINUX, M_WAITOK | M_ZERO); em->pid = child; + if (flags & CLONE_VM) { + /* handled later */ + } else { + struct linux_emuldata_shared *s; + + MALLOC(s, struct linux_emuldata_shared *, sizeof *s, M_LINUX, M_WAITOK | M_ZERO); + em->shared = s; + s->refs = 1; + s->group_pid = child; + + LIST_INIT(&s->threads); + } EMUL_WLOCK(&emul_lock); SLIST_INSERT_HEAD(&emuldata_head, em, emuldatas); } else { @@ -1190,7 +1202,6 @@ * the newly created proc */ if (child != 0) { - em->shared = NULL; if (flags & CLONE_VM) { /* lookup the parent */ p_em = em_find(td->td_proc->p_pid, EMUL_LOCKED); @@ -1204,14 +1215,7 @@ em->shared->refs++; } } else { - struct linux_emuldata_shared *s; - - MALLOC(s, struct linux_emuldata_shared *, sizeof *s, M_LINUX, M_WAITOK | M_ZERO); - em->shared = s; - s->refs = 1; - s->group_pid = child; - - LIST_INIT(&s->threads); + /* handled earlier to avoid malloc(M_WAITOK) with rwlock held */ } } @@ -1236,6 +1240,7 @@ struct linux_emuldata *em; int error; struct thread *td = FIRST_THREAD_IN_PROC(p); + int *child_clear_tid; if (p->p_sysent != &elf_linux_sysvec) return; @@ -1249,18 +1254,36 @@ #endif return; } - if (em->child_clear_tid != NULL) { + + child_clear_tid = em->child_clear_tid; + + EMUL_RUNLOCK(&emul_lock); + /* XXX: there is a race but I think we can ommit that + * because its not very possible that the same process + * will exit on different cpus etc. + */ + EMUL_WLOCK(&emul_lock); + LIST_REMOVE(em, threads); + SLIST_REMOVE(&emuldata_head, em, linux_emuldata, emuldatas); + + em->shared->refs--; + if (em->shared->refs == 0) + FREE(em->shared, M_LINUX); + EMUL_WUNLOCK(&emul_lock); + + if (child_clear_tid != NULL) { struct linux_sys_futex_args cup; int null = 0; - error = copyout(&null, em->child_clear_tid, sizeof(null)); + /* XXX: doesnt futex use the addr? */ + error = copyout(&null, child_clear_tid, sizeof(null)); if (error) { EMUL_RUNLOCK(&emul_lock); return; } /* futexes stuff */ - cup.uaddr = em->child_clear_tid; + cup.uaddr = child_clear_tid; cup.op = LINUX_FUTEX_WAKE; cup.val = 0x7fffffff; /* Awake everyone */ cup.timeout = NULL; @@ -1271,20 +1294,6 @@ printf(LMSG("futex stuff in proc_exit failed.\n")); } - em->shared->refs--; - if (em->shared->refs == 0) - FREE(em->shared, M_LINUX); - - EMUL_RUNLOCK(&emul_lock); - /* XXX: there is a race but I think we can ommit that - * because its not very possible that the same process - * will exit on different cpus etc. - */ - EMUL_WLOCK(&emul_lock); - LIST_REMOVE(em, threads); - SLIST_REMOVE(&emuldata_head, em, linux_emuldata, emuldatas); - EMUL_WUNLOCK(&emul_lock); - /* clean the stuff up */ FREE(em, M_LINUX); } @@ -1311,10 +1320,6 @@ #endif return; } - - em->shared->refs--; - if (em->shared->refs == 0) - FREE(em->shared, M_LINUX); EMUL_RUNLOCK(&emul_lock); /* XXX: there is a race but I think we can ommit that @@ -1322,7 +1327,12 @@ * will exit on different cpus etc. */ EMUL_WLOCK(&emul_lock); + LIST_REMOVE(em, threads); SLIST_REMOVE(&emuldata_head, em, linux_emuldata, emuldatas); + + em->shared->refs--; + if (em->shared->refs == 0) + FREE(em->shared, M_LINUX); EMUL_WUNLOCK(&emul_lock); FREE(em, M_LINUX); @@ -1339,6 +1349,7 @@ #ifdef DEBUG struct thread *td = FIRST_THREAD_IN_PROC(p); #endif + int *child_set_tid; if (p->p_sysent != &elf_linux_sysvec) return; @@ -1360,11 +1371,12 @@ #endif return; } + child_set_tid = em->child_set_tid; + EMUL_RUNLOCK(&emul_lock); - if (em->child_set_tid != NULL) - error = copyout(&p->p_pid, em->child_set_tid, sizeof(p->p_pid)); + if (child_set_tid != NULL) + error = copyout(&p->p_pid, (int *) child_set_tid, sizeof(p->p_pid)); - EMUL_RUNLOCK(&emul_lock); return; } @@ -1374,7 +1386,7 @@ struct linux_emuldata *em; #ifdef DEBUG - if (ldebug(exit_group)) + if (ldebug(set_tid_address)) printf(ARGS(set_tid_address, "%p"), args->tidptr); #endif @@ -1398,10 +1410,8 @@ int linux_exit_group(struct thread *td, struct linux_exit_group_args *args) { - struct linux_emuldata *em, *td_em; + struct linux_emuldata *em, *td_em, *tmp_em; struct proc *sp; - struct kill_args ka; - int i = 0; #ifdef DEBUG if (ldebug(exit_group)) @@ -1417,23 +1427,16 @@ return (0); } - LIST_FOREACH(em, &td_em->shared->threads, threads) { - if (i++ > 10) - break; - + LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { if (em->pid == td_em->pid) continue; sp = pfind(em->pid); + psignal(sp, SIGKILL); PROC_UNLOCK(sp); #ifdef DEBUG printf(LMSG("linux_sys_exit_group: kill PID %d\n"), em->pid); #endif - ka.pid = em->pid; - ka.signum = SIGKILL; - /* XXX: ehm? */ - kill(FIRST_THREAD_IN_PROC(sp), &ka); - } EMUL_RUNLOCK(&emul_lock);