Date: Mon, 18 Feb 2002 12:09:28 -0800 (PST) From: Matthew Dillon <dillon@apollo.backplane.com> To: current@freebsd.org Subject: Patch sets to date and timing tests with Giant out of userret. Message-ID: <200202182009.g1IK9Sh36025@apollo.backplane.com>
next in thread | raw e-mail | index | archive | help
Here are my giant related patches to date. These are NOT all commit candidates. Some are just hacks to test Giant removal. Julian is responsible for the td_ucred persistance stuff. The hack in userret() is just a hack to remove Giant when no signals are present in order to test performance. Note that Julian hasn't updated persistent support for other cpu's so this patch only operates on i386. userret() appears to be the last major Giant-contention point in the syscall management path. getuid() performance, calls per second. current, SMP build, 2xCPU, invariants (+ patches below). unpatched userret, kern.giant.ucred=1 (default) 1 process: 683K 2 processes: 427K per process unpatched userret, kern.giant.ucred=0 1 process: 770K 2 processes: 460K per process patched userret, kern.giant.ucred=1 (default) 1 process: 739K 2 processes: 480K per process patched userret, kern.giant.ucred=0 1 process: 855K 2 processes: 706K per process The 1 process vs 2 process numbers are getting a lot closer, but they are still not perfect. -Matt Index: i386/i386/trap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/trap.c,v retrieving revision 1.212 diff -u -r1.212 trap.c --- i386/i386/trap.c 17 Feb 2002 01:09:54 -0000 1.212 +++ i386/i386/trap.c 18 Feb 2002 19:46:50 -0000 @@ -255,7 +255,9 @@ sticks = td->td_kse->ke_sticks; td->td_frame = &frame; +#if 0 KASSERT(td->td_ucred == NULL, ("already have a ucred")); +#endif if (td->td_ucred != p->p_ucred) cred_update_thread(td); @@ -643,7 +645,7 @@ userret(td, &frame, sticks); mtx_assert(&Giant, MA_NOTOWNED); userout: -#ifdef INVARIANTS +#if 0 mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); @@ -954,7 +956,9 @@ sticks = td->td_kse->ke_sticks; td->td_frame = &frame; +#if 0 KASSERT(td->td_ucred == NULL, ("already have a ucred")); +#endif if (td->td_ucred != p->p_ucred) cred_update_thread(td); params = (caddr_t)frame.tf_esp + sizeof(int); @@ -1099,7 +1103,7 @@ */ STOPEVENT(p, S_SCX, code); -#ifdef INVARIANTS +#if 0 mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); Index: kern/kern_fork.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.131 diff -u -r1.131 kern_fork.c --- kern/kern_fork.c 17 Feb 2002 01:09:55 -0000 1.131 +++ kern/kern_fork.c 18 Feb 2002 19:46:51 -0000 @@ -799,7 +799,7 @@ kthread_exit(0); } PROC_UNLOCK(p); -#ifdef INVARIANTS +#if 0 mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); Index: kern/kern_mutex.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_mutex.c,v retrieving revision 1.80 diff -u -r1.80 kern_mutex.c --- kern/kern_mutex.c 18 Feb 2002 17:51:47 -0000 1.80 +++ kern/kern_mutex.c 18 Feb 2002 19:46:51 -0000 @@ -287,7 +287,9 @@ _mtx_lock_sleep(struct mtx *m, int opts, const char *file, int line) { struct thread *td = curthread; +#if 0 struct ksegrp *kg = td->td_ksegrp; +#endif if ((m->mtx_lock & MTX_FLAGMASK) == (uintptr_t)td) { m->mtx_recurse++; @@ -312,6 +314,22 @@ * the sched_lock. */ if ((v = m->mtx_lock) == MTX_UNOWNED) { + mtx_unlock_spin(&sched_lock); + continue; + } + + /* + * Check to see if there are any runnable processes. If + * there aren't and nobody is contesting the mutex (to avoid + * starving a contester) and interrupts are enabled, then + * we can safely spin. + * + * This prevents a silly-sleep-flip-flop situation on SMP + * systems where two running processes need Giant (or any + * other sleep mutex). + */ + if (td->td_critnest == 0 && (v & MTX_CONTESTED) == 0 && + procrunnable() == 0) { mtx_unlock_spin(&sched_lock); continue; } Index: kern/kern_prot.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v retrieving revision 1.135 diff -u -r1.135 kern_prot.c --- kern/kern_prot.c 17 Feb 2002 07:30:34 -0000 1.135 +++ kern/kern_prot.c 18 Feb 2002 19:46:51 -0000 @@ -228,14 +228,14 @@ struct thread *td; struct getuid_args *uap; { - struct proc *p = td->td_proc; + int s; - mtx_lock(&Giant); - td->td_retval[0] = p->p_ucred->cr_ruid; + s = mtx_lock_giant(kern_giant_ucred); + td->td_retval[0] = td->td_ucred->cr_ruid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) - td->td_retval[1] = p->p_ucred->cr_uid; + td->td_retval[1] = td->td_ucred->cr_uid; #endif - mtx_unlock(&Giant); + mtx_unlock_giant(s); return (0); } @@ -253,9 +253,11 @@ struct thread *td; struct geteuid_args *uap; { - mtx_lock(&Giant); - td->td_retval[0] = td->td_proc->p_ucred->cr_uid; - mtx_unlock(&Giant); + int s; + + s = mtx_lock_giant(kern_giant_ucred); + td->td_retval[0] = td->td_ucred->cr_uid; + mtx_unlock_giant(s); return (0); } @@ -273,14 +275,14 @@ struct thread *td; struct getgid_args *uap; { - struct proc *p = td->td_proc; + int s; - mtx_lock(&Giant); - td->td_retval[0] = p->p_ucred->cr_rgid; + s = mtx_lock_giant(kern_giant_ucred); + td->td_retval[0] = td->td_ucred->cr_rgid; #if defined(COMPAT_43) || defined(COMPAT_SUNOS) - td->td_retval[1] = p->p_ucred->cr_groups[0]; + td->td_retval[1] = td->td_ucred->cr_groups[0]; #endif - mtx_unlock(&Giant); + mtx_unlock_giant(s); return (0); } @@ -303,11 +305,11 @@ struct thread *td; struct getegid_args *uap; { - struct proc *p = td->td_proc; + int s; - mtx_lock(&Giant); - td->td_retval[0] = p->p_ucred->cr_groups[0]; - mtx_unlock(&Giant); + s = mtx_lock_giant(kern_giant_ucred); + td->td_retval[0] = td->td_ucred->cr_groups[0]; + mtx_unlock_giant(s); return (0); } @@ -326,13 +328,13 @@ register struct getgroups_args *uap; { struct ucred *cred; - struct proc *p = td->td_proc; u_int ngrp; int error; + int s; - mtx_lock(&Giant); + s = mtx_lock_giant(kern_giant_ucred); error = 0; - cred = p->p_ucred; + cred = td->td_ucred; if ((ngrp = uap->gidsetsize) == 0) { td->td_retval[0] = cred->cr_ngroups; goto done2; @@ -347,7 +349,7 @@ goto done2; td->td_retval[0] = ngrp; done2: - mtx_unlock(&Giant); + mtx_unlock_giant(s); return (error); } @@ -1057,11 +1059,11 @@ struct getresuid_args *uap; { struct ucred *cred; - struct proc *p = td->td_proc; int error1 = 0, error2 = 0, error3 = 0; + int s; - mtx_lock(&Giant); - cred = p->p_ucred; + s = mtx_lock_giant(kern_giant_ucred); + cred = td->td_ucred; if (uap->ruid) error1 = copyout((caddr_t)&cred->cr_ruid, (caddr_t)uap->ruid, sizeof(cred->cr_ruid)); @@ -1071,7 +1073,7 @@ if (uap->suid) error3 = copyout((caddr_t)&cred->cr_svuid, (caddr_t)uap->suid, sizeof(cred->cr_svuid)); - mtx_unlock(&Giant); + mtx_unlock_giant(s); return (error1 ? error1 : error2 ? error2 : error3); } @@ -1092,11 +1094,11 @@ struct getresgid_args *uap; { struct ucred *cred; - struct proc *p = td->td_proc; int error1 = 0, error2 = 0, error3 = 0; + int s; - mtx_lock(&Giant); - cred = p->p_ucred; + s = mtx_lock_giant(kern_giant_ucred); + cred = td->td_ucred; if (uap->rgid) error1 = copyout((caddr_t)&cred->cr_rgid, (caddr_t)uap->rgid, sizeof(cred->cr_rgid)); @@ -1106,7 +1108,7 @@ if (uap->sgid) error3 = copyout((caddr_t)&cred->cr_svgid, (caddr_t)uap->sgid, sizeof(cred->cr_svgid)); - mtx_unlock(&Giant); + mtx_unlock_giant(s); return (error1 ? error1 : error2 ? error2 : error3); } @@ -1172,6 +1174,8 @@ /* * Check if gid is a member of the group set. + * + * MPSAFE (cred must be held) */ int groupmember(gid, cred) @@ -1228,6 +1232,8 @@ /* * wrapper to use if you have the thread on hand but not the proc. + * + * MPSAFE (cred must be held) */ int suser_xxx_td(cred, td, flag) @@ -1269,6 +1275,8 @@ * existing securelevel checks that occurred without a process/credential * context. In the future this will be disallowed, so a kernel message * is displayed. + * + * MPSAFE */ int securelevel_gt(struct ucred *cr, int level) Index: kern/subr_trap.c =================================================================== RCS file: /home/ncvs/src/sys/kern/subr_trap.c,v retrieving revision 1.208 diff -u -r1.208 subr_trap.c --- kern/subr_trap.c 17 Feb 2002 01:09:55 -0000 1.208 +++ kern/subr_trap.c 18 Feb 2002 19:46:51 -0000 @@ -72,12 +72,18 @@ struct ksegrp *kg = td->td_ksegrp; int sig; - mtx_lock(&Giant); PROC_LOCK(p); - while ((sig = CURSIG(p)) != 0) - postsig(sig); - PROC_UNLOCK(p); - mtx_unlock(&Giant); + if (!SIGISEMPTY(p->p_siglist)) { + PROC_UNLOCK(p); + mtx_lock(&Giant); + PROC_LOCK(p); + while ((sig = CURSIG(p)) != 0) + postsig(sig); + PROC_UNLOCK(p); + mtx_unlock(&Giant); + } else { + PROC_UNLOCK(p); + } mtx_lock_spin(&sched_lock); td->td_priority = kg->kg_user_pri; @@ -131,7 +137,9 @@ #endif KASSERT(TRAPF_USERMODE(framep), ("ast in kernel mode")); +#if 0 KASSERT(td->td_ucred == NULL, ("leaked ucred")); +#endif #ifdef WITNESS if (witness_list(td)) panic("Returning to user mode with mutex(s) held"); @@ -187,7 +195,7 @@ } userret(td, framep, sticks); -#ifdef INVARIANTS +#if 0 mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202182009.g1IK9Sh36025>