From owner-p4-projects@FreeBSD.ORG Sat Aug 12 10:31:28 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 D5CF016A4E0; Sat, 12 Aug 2006 10:31:27 +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 956D116A4DD for ; Sat, 12 Aug 2006 10:31:27 +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 3BBD743D46 for ; Sat, 12 Aug 2006 10:31:27 +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 k7CAVRa0013673 for ; Sat, 12 Aug 2006 10:31:27 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7CAVQvH013670 for perforce@freebsd.org; Sat, 12 Aug 2006 10:31:26 GMT (envelope-from rdivacky@FreeBSD.org) Date: Sat, 12 Aug 2006 10:31:26 GMT Message-Id: <200608121031.k7CAVQvH013670@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 103698 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: Sat, 12 Aug 2006 10:31:28 -0000 http://perforce.freebsd.org/chv.cgi?CH=103698 Change 103698 by rdivacky@rdivacky_witten on 2006/08/12 10:31:23 o remove SLIST of linux processes emuldata and use proc->p_emuldata instead o change locking to use sx (because its sleepable) so we are LOR-less o split locking of shared->threads and p->p_emuldata o change em_find() prototype to take proc instead of pid Affected files ... .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#9 edit .. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_signal.c#4 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux.h#15 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#40 edit .. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#14 edit Differences ... ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_misc.c#9 (text+ko) ==== @@ -93,8 +93,8 @@ #define BSD_TO_LINUX_SIGNAL(sig) \ (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) -struct linux_emuldata *em_find(pid_t pid, int locked); -extern struct rwlock emul_lock; +extern struct sx emul_shared_lock; +extern struct sx emul_lock; static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = { RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, @@ -1335,7 +1335,7 @@ { struct linux_emuldata *em; - em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + em = em_find(td->td_proc, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG @@ -1345,7 +1345,7 @@ } td->td_retval[0] = em->shared->group_pid; - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return (0); } @@ -1355,7 +1355,7 @@ struct linux_emuldata *em; struct proc *p, *pp; - em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + em = em_find(td->td_proc, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG @@ -1380,7 +1380,7 @@ /* if its also linux process */ if (pp->p_sysent == &elf_linux_sysvec) { - em = em_find(pp->p_pid, EMUL_LOCKED); + em = em_find(pp, EMUL_LOCKED); if (em == NULL) { #ifdef DEBUG printf(LMSG("emuldata for parent process not found in getppid.\n")); @@ -1392,7 +1392,7 @@ } else td->td_retval[0] = pp->p_pid; - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); PROC_UNLOCK(pp); return (0); ==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_signal.c#4 (text+ko) ==== @@ -50,8 +50,8 @@ #include #include -struct linux_emuldata *em_find(pid_t pid, int locked); -extern struct rwlock emul_lock; +extern struct sx emul_shared_lock; +extern struct sx emul_lock; void linux_to_bsd_sigset(l_sigset_t *lss, sigset_t *bss) @@ -477,7 +477,7 @@ PROC_UNLOCK(p); - em = em_find(args->pid, EMUL_UNLOCKED); + em = em_find(p, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG @@ -489,7 +489,7 @@ if (em->shared->group_pid != args->tgid) return ESRCH; - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return linux_kill(td, &ka); } ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux.h#15 (text+ko) ==== @@ -34,7 +34,8 @@ #include /* for sigval union */ #include #include -#include +#include +#include #include @@ -798,15 +799,18 @@ struct linux_emuldata_shared *shared; - SLIST_ENTRY(linux_emuldata) emuldatas; - LIST_ENTRY(linux_emuldata) threads; /* list of linux threads */ }; -#define EMUL_RLOCK(l) rw_rlock(l) -#define EMUL_RUNLOCK(l) rw_runlock(l) -#define EMUL_WLOCK(l) rw_wlock(l) -#define EMUL_WUNLOCK(l) rw_wunlock(l) +struct linux_emuldata *em_find(struct proc *, int locked); + +#define EMUL_LOCK(l) sx_xlock(l) +#define EMUL_UNLOCK(l) sx_xunlock(l) + +#define EMUL_SHARED_RLOCK(l) sx_slock(l) +#define EMUL_SHARED_RUNLOCK(l) sx_sunlock(l) +#define EMUL_SHARED_WLOCK(l) sx_xlock(l) +#define EMUL_SHARED_WUNLOCK(l) sx_xunlock(l) /* for em_find use */ #define EMUL_LOCKED 1 ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#40 (text+ko) ==== @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -64,16 +65,13 @@ #include /* needed for pcb definition in linux_set_thread_area */ -SLIST_HEAD(emuldata_head, linux_emuldata) emuldata_head = - SLIST_HEAD_INITIALIZER(emuldata_head); -struct linux_emuldata *emuldata_headp; /* where we store the emulation data */ -struct rwlock emul_lock; - static int linux_proc_init(struct thread *, pid_t, int); void linux_proc_exit(void *, struct proc *); void linux_schedtail(void *, struct proc *); void linux_proc_exec(void *, struct proc *, struct image_params *); -struct linux_emuldata *em_find(pid_t pid, int locked); + +struct sx emul_shared_lock; +struct sx emul_lock; extern struct sysentvec elf32_freebsd_sysvec; /* defined in i386/i386/elf_machdep.c */ @@ -294,19 +292,17 @@ /* this returns locked reference to the emuldata entry (if found) */ struct linux_emuldata * -em_find(pid_t pid, int locked) +em_find(struct proc *p, int locked) { struct linux_emuldata *em; if (locked == EMUL_UNLOCKED) - EMUL_RLOCK(&emul_lock); + EMUL_LOCK(&emul_lock); - SLIST_FOREACH(em, &emuldata_head, emuldatas) - if (em->pid == pid) - break; + em = p->p_emuldata; if (em == NULL && locked == EMUL_UNLOCKED) - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return (em); } @@ -425,17 +421,17 @@ /* create the emuldata */ error = linux_proc_init(td, p2->p_pid, args->flags); /* reference it - no need to check this */ - em = em_find(p2->p_pid, EMUL_UNLOCKED); + em = em_find(p2, EMUL_UNLOCKED); KASSERT(em != NULL, ("no emuldata after proc_init()!\n")); /* and adjust it */ if (args->flags & CLONE_PARENT_SETTID) { if (args->parent_tidptr == NULL) { - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return (EINVAL); } error = copyout(&p2->p_pid, args->parent_tidptr, sizeof(p2->p_pid)); if (error) { - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return (error); } } @@ -459,7 +455,7 @@ em->child_clear_tid = args->child_tidptr; else em->child_clear_tid = NULL; - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); PROC_LOCK(p2); p2->p_sigparent = exit_signal; @@ -1179,11 +1175,14 @@ LIST_INIT(&s->threads); } - EMUL_WLOCK(&emul_lock); - SLIST_INSERT_HEAD(&emuldata_head, em, emuldatas); + p = pfind(child); + if (p == NULL) + panic("process not found in proc_init\n"); + p->p_emuldata = em; + PROC_UNLOCK(p); } else { /* lookup the old one */ - em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + em = em_find(td->td_proc, EMUL_UNLOCKED); /* XXX: this might be turned into KASSERT once its tested enough */ if (em == NULL) { /* this should not happen */ @@ -1204,7 +1203,7 @@ if (child != 0) { if (flags & CLONE_VM) { /* lookup the parent */ - p_em = em_find(td->td_proc->p_pid, EMUL_LOCKED); + p_em = em_find(td->td_proc, EMUL_LOCKED); if (p_em == NULL) { #ifdef DEBUG #endif @@ -1221,15 +1220,16 @@ if (child != 0) { + EMUL_SHARED_WLOCK(&emul_shared_lock); LIST_INSERT_HEAD(&em->shared->threads, em, threads); - EMUL_WUNLOCK(&emul_lock); + EMUL_SHARED_WUNLOCK(&emul_shared_lock); p = pfind(child); PROC_UNLOCK(p); /* we might have a sleeping linux_schedtail */ wakeup(&p->p_emuldata); } else - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return (0); } @@ -1246,7 +1246,7 @@ return; /* find the emuldata */ - em = em_find(p->p_pid, EMUL_UNLOCKED); + em = em_find(p, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG @@ -1257,19 +1257,19 @@ 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); + EMUL_UNLOCK(&emul_lock); + + EMUL_SHARED_WLOCK(&emul_shared_lock); LIST_REMOVE(em, threads); - SLIST_REMOVE(&emuldata_head, em, linux_emuldata, emuldatas); + + PROC_LOCK(p); + p->p_emuldata = NULL; + PROC_UNLOCK(p); em->shared->refs--; if (em->shared->refs == 0) FREE(em->shared, M_LINUX); - EMUL_WUNLOCK(&emul_lock); + EMUL_SHARED_WUNLOCK(&emul_shared_lock); if (child_clear_tid != NULL) { struct linux_sys_futex_args cup; @@ -1277,10 +1277,8 @@ /* XXX: doesnt futex use the addr? */ error = copyout(&null, child_clear_tid, sizeof(null)); - if (error) { - EMUL_RUNLOCK(&emul_lock); + if (error) return; - } /* futexes stuff */ cup.uaddr = child_clear_tid; @@ -1311,7 +1309,7 @@ && p->p_sysent == &elf_linux_sysvec)) { struct linux_emuldata *em; - em = em_find(p->p_pid, EMUL_UNLOCKED); + em = em_find(p, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG @@ -1321,19 +1319,19 @@ return; } - 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); + EMUL_UNLOCK(&emul_lock); + + EMUL_SHARED_WLOCK(&emul_shared_lock); LIST_REMOVE(em, threads); - SLIST_REMOVE(&emuldata_head, em, linux_emuldata, emuldatas); + + PROC_LOCK(p); + p->p_emuldata = NULL; + PROC_UNLOCK(p); em->shared->refs--; if (em->shared->refs == 0) FREE(em->shared, M_LINUX); - EMUL_WUNLOCK(&emul_lock); + EMUL_SHARED_WUNLOCK(&emul_shared_lock); FREE(em, M_LINUX); } @@ -1356,7 +1354,7 @@ retry: /* find the emuldata */ - em = em_find(p->p_pid, EMUL_UNLOCKED); + em = em_find(p, EMUL_UNLOCKED); if (em == NULL) { /* We might have been called before proc_init for this process so @@ -1372,7 +1370,7 @@ return; } child_set_tid = em->child_set_tid; - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); if (child_set_tid != NULL) error = copyout(&p->p_pid, (int *) child_set_tid, sizeof(p->p_pid)); @@ -1391,7 +1389,7 @@ #endif /* find the emuldata */ - em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + em = em_find(td->td_proc, EMUL_UNLOCKED); if (em == NULL) { #ifdef DEBUG @@ -1403,7 +1401,7 @@ em->child_clear_tid = args->tidptr; td->td_retval[0] = td->td_proc->p_pid; - EMUL_RUNLOCK(&emul_lock); + EMUL_UNLOCK(&emul_lock); return 0; } @@ -1418,7 +1416,7 @@ printf(ARGS(exit_group, "%i"), args->error_code); #endif - td_em = em_find(td->td_proc->p_pid, EMUL_UNLOCKED); + td_em = em_find(td->td_proc, EMUL_UNLOCKED); if (td_em == NULL) { #ifdef DEBUG @@ -1427,6 +1425,7 @@ return (0); } + EMUL_SHARED_RLOCK(&emul_shared_lock); LIST_FOREACH_SAFE(em, &td_em->shared->threads, threads, tmp_em) { if (em->pid == td_em->pid) continue; @@ -1439,7 +1438,8 @@ #endif } - EMUL_RUNLOCK(&emul_lock); + EMUL_SHARED_RUNLOCK(&emul_shared_lock); + EMUL_UNLOCK(&emul_lock); exit1(td, W_EXITCODE(args->error_code,0)); ==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_sysvec.c#14 (text+ko) ==== @@ -92,7 +92,6 @@ extern int linux_szsigcode; extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; -extern SLIST_HEAD(emuldata_head, linux_emuldata) emuldata_head; SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler); SET_DECLARE(linux_device_handler_set, struct linux_device_handler); @@ -110,8 +109,9 @@ extern void linux_proc_exit(void *, struct proc *, struct image_params *); extern void linux_proc_exec(void *, struct proc *, struct image_params *); extern void linux_schedtail(void *, struct proc *); -extern struct rwlock emul_lock; extern LIST_HEAD(futex_list, futex) futex_list; +extern struct sx emul_shared_lock; +extern struct sx emul_lock; extern struct mtx futex_mtx; static eventhandler_tag linux_exit_tag; @@ -921,8 +921,8 @@ linux_ioctl_register_handler(*lihp); SET_FOREACH(ldhp, linux_device_handler_set) linux_device_register_handler(*ldhp); - SLIST_INIT(&emuldata_head); - rw_init(&emul_lock, "emuldata lock"); + sx_init(&emul_lock, "emuldata lock"); + sx_init(&emul_shared_lock, "emuldata->shared lock"); LIST_INIT(&futex_list); mtx_init(&futex_mtx, "futex protection lock", NULL, MTX_DEF); linux_exit_tag = EVENTHANDLER_REGISTER(process_exit, linux_proc_exit, @@ -952,13 +952,12 @@ linux_ioctl_unregister_handler(*lihp); SET_FOREACH(ldhp, linux_device_handler_set) linux_device_unregister_handler(*ldhp); - rw_destroy(&emul_lock); + sx_destroy(&emul_lock); + sx_destroy(&emul_shared_lock); mtx_destroy(&futex_mtx); EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); - printf("Emuldata slist empty: %i\n", SLIST_EMPTY(&emuldata_head)); - printf("Futex slist empty: %i\n", LIST_EMPTY(&futex_list)); if (bootverbose) printf("Linux ELF exec handler removed\n"); } else