--- //depot/vendor/freebsd/src/sys/amd64/amd64/machdep.c 2007/06/06 07:37:03 +++ //depot/user/kris/contention/sys/amd64/amd64/machdep.c 2007/08/31 20:34:30 @@ -79,6 +79,7 @@ #include #include #include +#include #include #include #include @@ -263,7 +264,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -318,7 +319,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Copy the sigframe out to the user's stack. @@ -327,7 +328,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -335,7 +336,7 @@ regs->tf_rip = PS_STRINGS - *(p->p_sysent->sv_szsigcode); regs->tf_rflags &= ~PSL_T; regs->tf_cs = _ucodesel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -411,7 +412,7 @@ return (ret); bcopy(&ucp->uc_mcontext.mc_rdi, regs, sizeof(*regs)); - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -422,7 +423,7 @@ td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); td->td_pcb->pcb_flags |= PCB_FULLCTX; return (EJUSTRETURN); } @@ -1191,6 +1192,7 @@ */ mutex_init(); mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS); + rwlock_init(); /* exceptions */ for (x = 0; x < NIDT; x++) @@ -1534,9 +1536,7 @@ struct trapframe *tp; tp = td->td_frame; - PROC_LOCK(curthread->td_proc); mcp->mc_onstack = sigonstack(tp->tf_rsp); - PROC_UNLOCK(curthread->td_proc); mcp->mc_r15 = tp->tf_r15; mcp->mc_r14 = tp->tf_r14; mcp->mc_r13 = tp->tf_r13; --- //depot/vendor/freebsd/src/sys/amd64/amd64/mem.c 2004/08/07 06:25:14 +++ //depot/user/kris/contention/sys/amd64/amd64/mem.c 2007/07/26 22:46:10 @@ -77,8 +77,6 @@ int error = 0; vm_offset_t addr, eaddr; - GIANT_REQUIRED; - while (uio->uio_resid > 0 && error == 0) { iov = uio->uio_iov; if (iov->iov_len == 0) { --- //depot/vendor/freebsd/src/sys/amd64/amd64/trap.c 2007/07/26 15:36:47 +++ //depot/user/kris/contention/sys/amd64/amd64/trap.c 2007/08/31 20:34:30 @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -583,18 +584,18 @@ * Keep swapout from messing with us during this * critical time. */ - PROC_LOCK(p); + PROC_WLOCK(p); ++p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Fault in the user page: */ rv = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); - PROC_LOCK(p); + PROC_WLOCK(p); --p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * Don't have to worry about process locking or stacks in the --- //depot/vendor/freebsd/src/sys/amd64/ia32/ia32_signal.c 2006/10/05 02:02:27 +++ //depot/user/kris/contention/sys/amd64/ia32/ia32_signal.c 2007/08/31 20:34:30 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -131,9 +132,7 @@ tp = td->td_frame; - PROC_LOCK(curthread->td_proc); mcp->mc_onstack = sigonstack(tp->tf_rsp); - PROC_UNLOCK(curthread->td_proc); mcp->mc_gs = td->td_pcb->pcb_gs; mcp->mc_fs = td->td_pcb->pcb_fs; mcp->mc_es = td->td_pcb->pcb_es; @@ -223,9 +222,9 @@ ret = EINVAL; else { ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); ret = copyout(&uc, uap->ucp, UC_COPY_SIZE); } return (ret); @@ -245,9 +244,9 @@ ret = ia32_set_mcontext(td, &uc.uc_mcontext); if (ret == 0) { SIG_CANTMASK(uc.uc_sigmask); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); td->td_sigmask = uc.uc_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } } @@ -264,9 +263,9 @@ ret = EINVAL; else { ia32_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); ret = copyout(&uc, uap->oucp, UC_COPY_SIZE); if (ret == 0) { ret = copyin(uap->ucp, &uc, UC_COPY_SIZE); @@ -274,9 +273,9 @@ ret = ia32_set_mcontext(td, &uc.uc_mcontext); if (ret == 0) { SIG_CANTMASK(uc.uc_sigmask); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); td->td_sigmask = uc.uc_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } } @@ -311,7 +310,7 @@ p = td->td_proc; siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = siginfo.si_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -353,7 +352,7 @@ td->td_sigstk.ss_size - sizeof(sf)); } else sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Translate the signal if appropriate. */ if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) @@ -385,7 +384,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -399,7 +398,7 @@ load_es(_udatasel); td->td_pcb->pcb_es = _udatasel; /* leave user %fs and %gs untouched */ - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } #endif /* COMPAT_FREEBSD4 */ @@ -420,7 +419,7 @@ siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = siginfo.si_signo; psp = p->p_sigacts; #ifdef COMPAT_FREEBSD4 @@ -473,7 +472,7 @@ sp = (char *)regs->tf_rsp - sizeof(sf); /* Align to 16 bytes. */ sfp = (struct ia32_sigframe *)((uintptr_t)sp & ~0xF); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Translate the signal if appropriate. */ if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) @@ -505,7 +504,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -519,7 +518,7 @@ load_es(_udatasel); td->td_pcb->pcb_es = _udatasel; /* leave user %fs and %gs untouched */ - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -607,11 +606,11 @@ regs->tf_rsp = ucp->uc_mcontext.mc_esp; regs->tf_ss = ucp->uc_mcontext.mc_ss; - PROC_LOCK(p); + PROC_WLOCK(p); td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } #endif /* COMPAT_FREEBSD4 */ @@ -694,11 +693,11 @@ regs->tf_rsp = ucp->uc_mcontext.mc_esp; regs->tf_ss = ucp->uc_mcontext.mc_ss; - PROC_LOCK(p); + PROC_WLOCK(p); td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } --- //depot/vendor/freebsd/src/sys/amd64/ia32/ia32_syscall.c 2007/06/10 22:03:53 +++ //depot/user/kris/contention/sys/amd64/ia32/ia32_syscall.c 2007/08/31 20:34:30 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include --- //depot/vendor/freebsd/src/sys/amd64/include/pmc_mdep.h 2005/06/09 19:45:26 +++ //depot/user/kris/contention/sys/amd64/include/pmc_mdep.h 2007/09/08 18:21:40 @@ -33,10 +33,13 @@ #include #include +#include + union pmc_md_op_pmcallocate { struct pmc_md_amd_op_pmcallocate pm_amd; struct pmc_md_p4_op_pmcallocate pm_p4; + struct pmc_md_ppro_op_pmcallocate pm_ppro; uint64_t __pad[4]; }; @@ -49,6 +52,8 @@ union pmc_md_pmc { struct pmc_md_amd_pmc pm_amd; struct pmc_md_p4_pmc pm_p4; + struct pmc_md_ppro_pmc pm_ppro; + }; struct pmc; --- //depot/vendor/freebsd/src/sys/amd64/linux32/linux32_machdep.c 2007/07/04 23:13:08 +++ //depot/user/kris/contention/sys/amd64/linux32/linux32_machdep.c 2007/08/31 20:34:30 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -520,9 +521,9 @@ if (error) return (error); - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_flag |= P_PPWAIT; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); @@ -535,10 +536,10 @@ thread_unlock(td2); /* wait for the children to exit, ie. emulate vfork */ - PROC_LOCK(p2); + PROC_RLOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); - PROC_UNLOCK(p2); + rw_sleep(td->td_proc, &p2->p_rwlock, PWAIT, "ppwait", 0); + PROC_RUNLOCK(p2); return (0); } @@ -607,9 +608,9 @@ if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) { sx_xlock(&proctree_lock); - PROC_LOCK(p2); + PROC_WLOCK(p2); proc_reparent(p2, td->td_proc->p_pptr); - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); sx_xunlock(&proctree_lock); } @@ -622,9 +623,10 @@ if (args->flags & LINUX_CLONE_THREAD) { #ifdef notyet - PROC_LOCK(p2); + /* XXXPJD: Missing proctreee_lock? */ + PROC_WLOCK(p2); p2->p_pgrp = td->td_proc->p_pgrp; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); #endif exit_signal = 0; } @@ -648,9 +650,9 @@ printf(LMSG("copyout failed!")); } - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_sigparent = exit_signal; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); /* * In a case of stack = NULL, we are supposed to COW calling process @@ -707,9 +709,9 @@ exit_signal); #endif if (args->flags & LINUX_CLONE_VFORK) { - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_flag |= P_PPWAIT; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); } /* @@ -725,10 +727,10 @@ if (args->flags & LINUX_CLONE_VFORK) { /* wait for the children to exit, ie. emulate vfork */ - PROC_LOCK(p2); + PROC_RLOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); - PROC_UNLOCK(p2); + rw_sleep(td->td_proc, &p2->p_rwlock, PWAIT, "ppwait", 0); + PROC_RUNLOCK(p2); } return (0); @@ -901,10 +903,10 @@ * mmap'ed region, but some apps do not check * mmap's return value. */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK - lim_cur(p, RLIMIT_STACK); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } /* This gives us our maximum stack size */ @@ -1101,9 +1103,9 @@ printf(ARGS(pause, "")); #endif - PROC_LOCK(p); + PROC_RLOCK(p); sigmask = td->td_sigmask; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (kern_sigsuspend(td, sigmask)); } --- //depot/vendor/freebsd/src/sys/amd64/linux32/linux32_sysvec.c 2007/07/12 18:07:32 +++ //depot/user/kris/contention/sys/amd64/linux32/linux32_sysvec.c 2007/08/31 20:34:30 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -297,7 +298,7 @@ sig = ksi->ksi_signo; code = ksi->ksi_code; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); regs = td->td_frame; @@ -348,7 +349,7 @@ frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size; frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask); @@ -391,7 +392,7 @@ printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"), fp, oonstack); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -409,7 +410,7 @@ load_es(_udatasel); td->td_pcb->pcb_es = _udatasel; /* leave user %fs and %gs untouched */ - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -438,7 +439,7 @@ sig = ksi->ksi_signo; code = ksi->ksi_code; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); if (SIGISMEMBER(psp->ps_siginfo, sig)) { @@ -466,7 +467,7 @@ } else fp = (struct l_sigframe *)regs->tf_rsp - 1; mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Build the argument list for the signal handler. @@ -513,7 +514,7 @@ * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -530,7 +531,7 @@ load_es(_udatasel); td->td_pcb->pcb_es = _udatasel; /* leave user %fs and %gs untouched */ - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -605,11 +606,11 @@ lmask.__bits[0] = frame.sf_sc.sc_mask; for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) lmask.__bits[i+1] = frame.sf_extramask[i]; - PROC_LOCK(p); + PROC_WLOCK(p); linux_to_bsd_sigset(&lmask, &td->td_sigmask); SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Restore signal context. @@ -703,11 +704,11 @@ return(EINVAL); } - PROC_LOCK(p); + PROC_WLOCK(p); linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask); SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Restore signal context --- //depot/vendor/freebsd/src/sys/arm/arm/machdep.c 2007/05/31 22:58:09 +++ //depot/user/kris/contention/sys/arm/arm/machdep.c 2007/08/31 20:34:30 @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -118,7 +119,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; code = ksi->ksi_code; psp = p->p_sigacts; @@ -153,13 +154,13 @@ ? ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE; frame.sf_uc.uc_stack = td->td_sigstk; mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); /* Copy the sigframe out to the user's stack. */ if (copyout(&frame, fp, sizeof(*fp)) != 0) { /* Process has trashed its stack. Kill it. */ CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp); - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -187,7 +188,7 @@ CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_usr_lr, tf->tf_usr_sp); - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -380,7 +381,7 @@ struct iovec iov; struct uio uio; - PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED); + PROC_LOCK_ASSERT(td->td_proc, RA_UNLOCKED); iov.iov_base = (caddr_t) v; iov.iov_len = sizeof(u_int32_t); uio.uio_iov = &iov; @@ -399,7 +400,7 @@ struct iovec iov; struct uio uio; - PROC_LOCK_ASSERT(td->td_proc, MA_NOTOWNED); + PROC_LOCK_ASSERT(td->td_proc, RA_UNLOCKED); iov.iov_base = (caddr_t) &v; iov.iov_len = sizeof(u_int32_t); uio.uio_iov = &iov; @@ -421,7 +422,7 @@ KASSERT(td->td_md.md_ptrace_instr == 0, ("Didn't clear single step")); p = td->td_proc; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = ptrace_read_int(td, td->td_frame->tf_pc + 4, &td->td_md.md_ptrace_instr); if (error) @@ -432,7 +433,7 @@ td->td_md.md_ptrace_instr = 0; td->td_md.md_ptrace_addr = td->td_frame->tf_pc + 4; out: - PROC_LOCK(p); + PROC_WLOCK(p); return (error); } @@ -443,10 +444,10 @@ if (td->td_md.md_ptrace_instr) { p = td->td_proc; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); ptrace_write_int(td, td->td_md.md_ptrace_addr, td->td_md.md_ptrace_instr); - PROC_LOCK(p); + PROC_WLOCK(p); td->td_md.md_ptrace_instr = 0; } return (0); @@ -602,11 +603,11 @@ set_mcontext(td, &sf.sf_uc.uc_mcontext); /* Restore signal mask. */ - PROC_LOCK(p); + PROC_WLOCK(p); td->td_sigmask = sf.sf_uc.uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } --- //depot/vendor/freebsd/src/sys/arm/arm/mem.c 2007/02/13 15:41:28 +++ //depot/user/kris/contention/sys/arm/arm/mem.c 2007/07/26 22:46:10 @@ -80,8 +80,6 @@ int error = 0; vm_offset_t addr, eaddr; - GIANT_REQUIRED; - while (uio->uio_resid > 0 && error == 0) { iov = uio->uio_iov; if (iov->iov_len == 0) { --- //depot/vendor/freebsd/src/sys/arm/arm/trap.c 2007/07/31 17:11:38 +++ //depot/user/kris/contention/sys/arm/arm/trap.c 2007/08/31 20:34:30 @@ -425,18 +425,18 @@ onfault = pcb->pcb_onfault; pcb->pcb_onfault = NULL; if (map != kernel_map) { - PROC_LOCK(p); + PROC_WLOCK(p); p->p_lock++; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } error = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); pcb->pcb_onfault = onfault; if (map != kernel_map) { - PROC_LOCK(p); + PROC_WLOCK(p); p->p_lock--; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } if (__predict_true(error == 0)) goto out; @@ -787,17 +787,17 @@ goto out; if (map != kernel_map) { - PROC_LOCK(p); + PROC_WLOCK(p); p->p_lock++; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } error = vm_fault(map, va, VM_PROT_READ | VM_PROT_EXECUTE, VM_FAULT_NORMAL); if (map != kernel_map) { - PROC_LOCK(p); + PROC_WLOCK(p); p->p_lock--; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } if (__predict_true(error == 0)) --- //depot/vendor/freebsd/src/sys/arm/arm/undefined.c 2007/06/04 21:44:15 +++ //depot/user/kris/contention/sys/arm/arm/undefined.c 2007/08/31 20:34:30 @@ -260,11 +260,11 @@ break; if (fault_code & FAULT_USER && fault_instruction == PTRACE_BREAKPOINT) { - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); _PHOLD(td->td_proc); ptrace_clear_single_step(td); _PRELE(td->td_proc); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return; } --- //depot/vendor/freebsd/src/sys/cam/cam_periph.c 2007/05/14 21:52:47 +++ //depot/user/kris/contention/sys/cam/cam_periph.c 2007/08/31 20:34:30 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include --- //depot/vendor/freebsd/src/sys/compat/freebsd32/freebsd32_misc.c 2007/08/28 20:32:12 +++ //depot/user/kris/contention/sys/compat/freebsd32/freebsd32_misc.c 2007/09/14 21:34:44 @@ -48,10 +48,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include /* Must come after sys/selinfo.h */ #include /* Must come after sys/selinfo.h */ @@ -65,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -1881,7 +1885,7 @@ error = copyin(uap->name, name, uap->namelen * sizeof(int)); if (error) return (error); - mtx_lock(&Giant); + SYSCTL_TREE_SLOCK(); if (uap->oldlenp) oldlen = fuword32(uap->oldlenp); else @@ -1894,7 +1898,7 @@ if (uap->oldlenp) suword32(uap->oldlenp, j); done2: - mtx_unlock(&Giant); + SYSCTL_TREE_SUNLOCK(); return (error); } @@ -2023,10 +2027,10 @@ struct proc *p = td->td_proc; sigset_t siglist; - PROC_LOCK(p); + PROC_WLOCK(p); siglist = p->p_siglist; SIGSETOR(siglist, td->td_siglist); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); SIG2OSIG(siglist, td->td_retval[0]); return (0); } @@ -2080,10 +2084,10 @@ OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); - PROC_LOCK(p); + PROC_WLOCK(p); SIG2OSIG(td->td_sigmask, td->td_retval[0]); SIGSETOR(td->td_sigmask, set); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -2096,11 +2100,11 @@ OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); - PROC_LOCK(p); + PROC_WLOCK(p); SIG2OSIG(td->td_sigmask, td->td_retval[0]); SIGSETLO(td->td_sigmask, set); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -2111,16 +2115,16 @@ struct proc *p = td->td_proc; sigset_t mask; - PROC_LOCK(p); + PROC_WLOCK(p); td->td_oldsigmask = td->td_sigmask; td->td_pflags |= TDP_OLDMASK; OSIG2SIG(uap->mask, mask); SIG_CANTMASK(mask); SIGSETLO(td->td_sigmask, mask); signotify(td); - while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) + while (rw_sleep(&p->p_sigacts, &p->p_rwlock, PPAUSE|PCATCH, "opause", 0) == 0) /* void */; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* always return EINTR rather than ERESTART... */ return (EINTR); } --- //depot/vendor/freebsd/src/sys/compat/linprocfs/linprocfs.c 2007/06/05 00:07:29 +++ //depot/user/kris/contention/sys/compat/linprocfs/linprocfs.c 2007/08/31 20:34:30 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -522,7 +523,7 @@ char state; static int ratelimit = 0; - PROC_LOCK(p); + PROC_RLOCK(p); fill_kinfo_proc(p, &kp); sbuf_printf(sb, "%d", p->p_pid); #define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg) @@ -541,7 +542,7 @@ PS_ADD("ppid", "%d", p->p_pptr ? p->p_pptr->p_pid : 0); PS_ADD("pgrp", "%d", p->p_pgid); PS_ADD("session", "%d", p->p_session->s_sid); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); PS_ADD("tty", "%d", 0); /* XXX */ PS_ADD("tpgid", "%d", kp.ki_tpgid); PS_ADD("flags", "%u", 0); /* XXX */ @@ -595,9 +596,9 @@ struct kinfo_proc kp; segsz_t lsize; - PROC_LOCK(p); + PROC_RLOCK(p); fill_kinfo_proc(p, &kp); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * See comments in linprocfs_doprocstatus() regarding the @@ -630,7 +631,7 @@ struct sigacts *ps; int i; - PROC_LOCK(p); + PROC_RLOCK(p); td2 = FIRST_THREAD_IN_PROC(p); /* XXXKSE pretend only one thread */ if (P_SHOULDSTOP(p)) { @@ -692,7 +693,7 @@ sbuf_cat(sb, "Groups:\t"); for (i = 0; i < p->p_ucred->cr_ngroups; i++) sbuf_printf(sb, "%d ", p->p_ucred->cr_groups[i]); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sbuf_putc(sb, '\n'); /* @@ -727,7 +728,7 @@ * supports 64 signals, but this code is a long way from * running on anything but i386, so ignore that for now. */ - PROC_LOCK(p); + PROC_RLOCK(p); sbuf_printf(sb, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]); /* * I can't seem to find out where the signal mask is in @@ -739,7 +740,7 @@ sbuf_printf(sb, "SigIgn:\t%08x\n", ps->ps_sigignore.__bits[0]); sbuf_printf(sb, "SigCgt:\t%08x\n", ps->ps_sigcatch.__bits[0]); mtx_unlock(&ps->ps_mtx); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * Linux also prints the capability masks, but we don't have @@ -808,15 +809,15 @@ * Linux behaviour is to return zero-length in this case. */ - PROC_LOCK(p); + PROC_RLOCK(p); if (p->p_args && p_cansee(td, p) == 0) { sbuf_bcpy(sb, p->p_args->ar_args, p->p_args->ar_length); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } else if (p != td->td_proc) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sbuf_printf(sb, "%.*s", MAXCOMLEN, p->p_comm); } else { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = copyin((void *)p->p_sysent->sv_psstrings, &pstr, sizeof(pstr)); if (error) @@ -874,9 +875,9 @@ struct vattr vat; int locked; - PROC_LOCK(p); + PROC_RLOCK(p); error = p_candebug(td, p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error) return (error); --- //depot/vendor/freebsd/src/sys/compat/linux/linux_emul.c 2007/04/02 18:42:04 +++ //depot/user/kris/contention/sys/compat/linux/linux_emul.c 2007/08/31 20:34:30 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,7 @@ p = pfind(child); KASSERT(p != NULL, ("process not found in proc_init\n")); p->p_emuldata = em; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else EMUL_UNLOCK(&emul_lock); @@ -172,10 +173,10 @@ EMUL_UNLOCK(&emul_lock); sx_xlock(&proctree_lock); wakeup(initproc); - PROC_LOCK(p); + PROC_WLOCK(p); proc_reparent(p, initproc); p->p_sigparent = SIGCHLD; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sx_xunlock(&proctree_lock); } else { child_clear_tid = em->child_clear_tid; @@ -233,9 +234,9 @@ em = em_find(q, EMUL_DOLOCK); KASSERT(em != NULL, ("linux_reparent: emuldata not found: %i\n", q->p_pid)); if (em->pdeath_signal != 0) { - PROC_LOCK(q); + PROC_WLOCK(q); psignal(q, em->pdeath_signal); - PROC_UNLOCK(q); + PROC_WUNLOCK(q); } EMUL_UNLOCK(&emul_lock); } @@ -270,9 +271,9 @@ EMUL_SHARED_WLOCK(&emul_shared_lock); LIST_REMOVE(em, threads); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_emuldata = NULL; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); em->shared->refs--; if (em->shared->refs == 0) { --- //depot/vendor/freebsd/src/sys/compat/linux/linux_file.c 2007/07/04 23:13:08 +++ //depot/user/kris/contention/sys/compat/linux/linux_file.c 2007/08/31 20:34:30 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -141,16 +142,16 @@ error = fget(td, fd, &fp); if (!error) { sx_slock(&proctree_lock); - PROC_LOCK(p); + PROC_RLOCK(p); if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sx_unlock(&proctree_lock); if (fp->f_type == DTYPE_VNODE) (void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td->td_ucred, td); } else { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sx_sunlock(&proctree_lock); } if (l_flags & LINUX_O_DIRECTORY) { --- //depot/vendor/freebsd/src/sys/compat/linux/linux_misc.c 2007/08/28 12:32:01 +++ //depot/user/kris/contention/sys/compat/linux/linux_misc.c 2007/09/14 21:34:44 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -357,14 +358,14 @@ * XXX - this is not complete. it should check current usage PLUS * the resources needed by this library. */ - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (a_out->a_text > maxtsiz || a_out->a_data + bss_size > lim_cur(td->td_proc, RLIMIT_DATA)) { - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); error = ENOMEM; goto cleanup; } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); /* * Prevent more writers. @@ -669,12 +670,12 @@ if (args->buf != NULL) { p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); calcru(p, &utime, &stime); PROC_SUNLOCK(p); calccru(p, &cutime, &cstime); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); tms.tms_utime = CONVTCK(utime); tms.tms_stime = CONVTCK(stime); @@ -892,9 +893,9 @@ return error; p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); sigqueue_delete(&p->p_sigqueue, SIGCHLD); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (args->status) { tmpstat &= 0xffff; @@ -1070,7 +1071,7 @@ return (error); newcred = crget(); p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; /* @@ -1080,7 +1081,7 @@ */ if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -1100,7 +1101,7 @@ setsugid(p); p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); } @@ -1196,9 +1197,9 @@ if (which == -1) return (EINVAL); - PROC_LOCK(p); + PROC_RLOCK(p); lim_rlimit(p, which, &bsd_rlim); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); #ifdef COMPAT_LINUX32 rlim.rlim_cur = (unsigned int)bsd_rlim.rlim_cur; @@ -1239,9 +1240,9 @@ if (which == -1) return (EINVAL); - PROC_LOCK(p); + PROC_RLOCK(p); lim_rlimit(p, which, &bsd_rlim); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); rlim.rlim_cur = (l_ulong)bsd_rlim.rlim_cur; rlim.rlim_max = (l_ulong)bsd_rlim.rlim_max; @@ -1475,9 +1476,9 @@ #endif if (!linux_use26(td)) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); td->td_retval[0] = td->td_proc->p_pptr->p_pid; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); return (0); } @@ -1486,7 +1487,7 @@ KASSERT(em != NULL, ("getppid: process emuldata not found.\n")); /* find the group leader */ - p = pfind(em->shared->group_pid); + p = pfindr(em->shared->group_pid); if (p == NULL) { #ifdef DEBUG @@ -1496,8 +1497,8 @@ } pp = p->p_pptr; /* switch to parent */ - PROC_LOCK(pp); - PROC_UNLOCK(p); + PROC_RLOCK(pp); + PROC_RUNLOCK(p); /* if its also linux process */ if (pp->p_sysent == &elf_linux_sysvec) { @@ -1508,7 +1509,7 @@ } else td->td_retval[0] = pp->p_pid; - PROC_UNLOCK(pp); + PROC_RUNLOCK(pp); return (0); } @@ -1618,7 +1619,7 @@ sp = pfind(em->pid); psignal(sp, SIGKILL); - PROC_UNLOCK(sp); + PROC_WUNLOCK(sp); #ifdef DEBUG printf(LMSG("linux_sys_exit_group: kill PID %d\n"), em->pid); #endif @@ -1695,14 +1696,14 @@ if (error) return (error); - PROC_LOCK(p); + PROC_WLOCK(p); strlcpy(p->p_comm, comm, sizeof(p->p_comm)); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); break; case LINUX_PR_GET_NAME: - PROC_LOCK(p); + PROC_RLOCK(p); strlcpy(comm, p->p_comm, sizeof(comm)); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = copyout(comm, (void *)(register_t)args->arg2, strlen(comm) + 1); break; --- //depot/vendor/freebsd/src/sys/compat/linux/linux_signal.c 2007/01/10 16:24:35 +++ //depot/user/kris/contention/sys/compat/linux/linux_signal.c 2007/08/31 20:34:30 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -336,9 +337,9 @@ printf(ARGS(sgetmask, "")); #endif - PROC_LOCK(p); + PROC_RLOCK(p); bsd_to_linux_sigset(&td->td_sigmask, &mask); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); td->td_retval[0] = mask.__bits[0]; return (0); } @@ -355,7 +356,7 @@ printf(ARGS(ssetmask, "%08lx"), (unsigned long)args->mask); #endif - PROC_LOCK(p); + PROC_WLOCK(p); bsd_to_linux_sigset(&td->td_sigmask, &lset); td->td_retval[0] = lset.__bits[0]; LINUX_SIGEMPTYSET(lset); @@ -364,7 +365,7 @@ td->td_sigmask = bset; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -384,11 +385,11 @@ printf(ARGS(sigpending, "*")); #endif - PROC_LOCK(p); + PROC_RLOCK(p); bset = p->p_siglist; SIGSETOR(bset, td->td_siglist); SIGSETAND(bset, td->td_sigmask); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); bsd_to_linux_sigset(&bset, &lset); mask = lset.__bits[0]; return (copyout(&mask, args->mask, sizeof(mask))); @@ -413,11 +414,11 @@ printf(ARGS(rt_sigpending, "*")); #endif - PROC_LOCK(p); + PROC_RLOCK(p); bset = p->p_siglist; SIGSETOR(bset, td->td_siglist); SIGSETAND(bset, td->td_sigmask); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); bsd_to_linux_sigset(&bset, &lset); return (copyout(&lset, args->set, args->sigsetsize)); } @@ -498,9 +499,9 @@ /* Repost if we got an error. */ if (error && info.ksi_signo) { - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); tdsignal(td->td_proc, td, info.ksi_signo, &info); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } else td->td_retval[0] = info.ksi_signo; @@ -553,13 +554,13 @@ if (args->tgid == -1) return linux_kill(td, &ka); - if ((p = pfind(args->pid)) == NULL) + if ((p = pfindr(args->pid)) == NULL) return ESRCH; if (p->p_sysent != &elf_linux_sysvec) return ESRCH; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); em = em_find(p, EMUL_DONTLOCK); --- //depot/vendor/freebsd/src/sys/compat/linux/linux_uid16.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/compat/linux/linux_uid16.c 2007/08/31 20:34:30 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +116,7 @@ return (error); newcred = crget(); p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; /* @@ -125,7 +126,7 @@ */ if ((error = priv_check_cred(oldcred, PRIV_CRED_SETGROUPS, 0)) != 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -146,7 +147,7 @@ setsugid(td->td_proc); p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); } --- //depot/vendor/freebsd/src/sys/compat/svr4/imgact_svr4.c 2005/04/01 20:00:37 +++ //depot/user/kris/contention/sys/compat/svr4/imgact_svr4.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -107,13 +108,13 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(imgp->proc); + PROC_RLOCK(imgp->proc); if (a_out->a_text > maxtsiz || a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA)) { - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); return (ENOMEM); } - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); VOP_UNLOCK(imgp->vp, 0, td); --- //depot/vendor/freebsd/src/sys/compat/svr4/svr4_fcntl.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/compat/svr4/svr4_fcntl.c 2007/08/31 20:34:30 @@ -386,14 +386,14 @@ retval = td->td_retval[0]; - PROC_LOCK(p); + PROC_RLOCK(p); if (!(bsd_flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { #if defined(NOTYET) struct file *fp; error = fget(td, retval, &fp); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * we may have lost a race the above open() and * another thread issuing a close() @@ -406,11 +406,11 @@ td); fdrop(fp, td); } else { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } #else } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); #endif return error; } --- //depot/vendor/freebsd/src/sys/compat/svr4/svr4_filio.c 2007/04/04 09:18:07 +++ //depot/user/kris/contention/sys/compat/svr4/svr4_filio.c 2007/08/31 20:34:30 @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -66,13 +67,13 @@ int idx = 0, cerr; u_long siz; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (uap->nfds > lim_cur(td->td_proc, RLIMIT_NOFILE) && uap->nfds > FD_SETSIZE) { - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); return (EINVAL); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); pa.fds = uap->fds; pa.nfds = uap->nfds; @@ -146,7 +147,7 @@ #ifdef DEBUG_SVR4 struct sigacts *ps; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); ps = td->td_proc->p_sigacts; mtx_lock(&ps->ps_mtx); #endif @@ -156,7 +157,7 @@ DPRINTF(("siglist = 0x%x\n", td->td_siglist)); #ifdef DEBUG_SVR4 mtx_unlock(&ps->ps_mtx); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); #endif } --- //depot/vendor/freebsd/src/sys/compat/svr4/svr4_misc.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/compat/svr4/svr4_misc.c 2007/08/31 20:34:30 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -826,12 +827,12 @@ int error; p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); calcru(p, &utime, &stime); PROC_SUNLOCK(p); calccru(p, &cutime, &cstime); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); tms.tms_utime = timeval_to_clock_t(&utime); tms.tms_stime = timeval_to_clock_t(&stime); @@ -859,9 +860,9 @@ switch (uap->cmd) { case SVR4_GFILLIM: - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); *retval = lim_cur(td->td_proc, RLIMIT_FSIZE) / 512; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); if (*retval == -1) *retval = 0x7fffffff; return 0; @@ -871,17 +872,17 @@ struct rlimit krl; krl.rlim_cur = uap->newlimit * 512; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); krl.rlim_max = lim_max(td->td_proc, RLIMIT_FSIZE); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); error = kern_setrlimit(td, RLIMIT_FSIZE, &krl); if (error) return error; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); *retval = lim_cur(td->td_proc, RLIMIT_FSIZE); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); if (*retval == -1) *retval = 0x7fffffff; return 0; @@ -892,9 +893,9 @@ struct vmspace *vm = td->td_proc->p_vmspace; register_t r; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); r = lim_cur(td->td_proc, RLIMIT_DATA); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); if (r == -1) r = 0x7fffffff; @@ -908,9 +909,9 @@ } case SVR4_GDESLIM: - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); *retval = lim_cur(td->td_proc, RLIMIT_NOFILE); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); if (*retval == -1) *retval = 0x7fffffff; return 0; @@ -927,9 +928,12 @@ struct proc *p; /* look in the live processes */ - if ((p = pfind(pid)) == NULL) + if ((p = pfindr(pid)) == NULL) { /* look in the zombies */ p = zpfind(pid); + if (p != NULL) + PROC_DOWNGRADE(p); + } return p; } @@ -956,14 +960,14 @@ /*FALLTHROUGH*/ case 0: /* getpgrp() */ - PROC_LOCK(p); + PROC_RLOCK(p); *retval = p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case 2: /* getsid(pid) */ if (uap->pid == 0) - PROC_LOCK(p); + PROC_RLOCK(p); else if ((p = svr4_pfind(uap->pid)) == NULL) return ESRCH; /* @@ -971,7 +975,7 @@ * the session leader. */ *retval = (register_t) p->p_session->s_sid; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case 3: /* setsid() */ @@ -980,12 +984,12 @@ case 4: /* getpgid(pid) */ if (uap->pid == 0) - PROC_LOCK(p); + PROC_RLOCK(p); else if ((p = svr4_pfind(uap->pid)) == NULL) return ESRCH; *retval = (int) p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case 5: /* setpgid(pid, pgid); */ @@ -1162,9 +1166,9 @@ break; case SVR4_P_PGID: - PROC_LOCK(q); + PROC_RLOCK(q); pid = -q->p_pgid; - PROC_UNLOCK(q); + PROC_RUNLOCK(q); break; case SVR4_P_ALL: @@ -1212,16 +1216,16 @@ nfound = 0; sx_slock(&proctree_lock); LIST_FOREACH(p, &q->p_children, p_sibling) { - PROC_LOCK(p); + PROC_WLOCK(p); if (pid != WAIT_ANY && p->p_pid != pid && p->p_pgid != -pid) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); DPRINTF(("pid %d pgid %d != %d\n", p->p_pid, p->p_pgid, pid)); continue; } if (p_canwait(td, p)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } @@ -1245,7 +1249,7 @@ PROC_SLOCK(p); calcru(p, &ru.ru_utime, &ru.ru_stime); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sx_sunlock(&proctree_lock); /* Copy the info out to userland. */ @@ -1272,12 +1276,12 @@ PROC_SLOCK(p); calcru(p, &ru.ru_utime, &ru.ru_stime); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (((uap->options & SVR4_WNOWAIT)) == 0) { - PROC_LOCK(q); + PROC_WLOCK(q); sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); + PROC_WUNLOCK(q); } *retval = 0; @@ -1296,19 +1300,19 @@ PROC_SLOCK(p); calcru(p, &ru.ru_utime, &ru.ru_stime); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (((uap->options & SVR4_WNOWAIT)) == 0) { - PROC_LOCK(q); + PROC_WLOCK(q); sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); + PROC_WUNLOCK(q); } *retval = 0; DPRINTF(("jobcontrol %d\n", pid)); return (svr4_setinfo(pid, &ru, status, uap->info)); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } if (nfound == 0) { @@ -1322,14 +1326,14 @@ return (svr4_setinfo(0, NULL, 0, uap->info)); } - PROC_LOCK(q); + PROC_WLOCK(q); sx_sunlock(&proctree_lock); if (q->p_flag & P_STATCHILD) { q->p_flag &= ~P_STATCHILD; error = 0; } else - error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "svr4_wait", 0); - PROC_UNLOCK(q); + error = rw_sleep(q, &q->p_rwlock, PWAIT | PCATCH, "svr4_wait", 0); + PROC_WUNLOCK(q); if (error) return error; goto loop; --- //depot/vendor/freebsd/src/sys/compat/svr4/svr4_resource.c 2005/01/05 22:36:13 +++ //depot/user/kris/contention/sys/compat/svr4/svr4_resource.c 2007/08/31 20:34:30 @@ -76,6 +76,7 @@ #include #include #include +#include #include #include @@ -137,9 +138,9 @@ if (rl == -1) return EINVAL; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); lim_rlimit(td->td_proc, rl, &blim); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); /* * Our infinity, is their maxfiles. @@ -188,9 +189,9 @@ if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0) return error; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); lim_rlimit(td->td_proc, rl, &curlim); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); /* * if the limit is SVR4_RLIM_INFINITY, then we set it to our @@ -235,9 +236,9 @@ if (rl == -1) return EINVAL; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); lim_rlimit(td->td_proc, rl, &blim); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); /* * Our infinity, is their maxfiles. @@ -286,9 +287,9 @@ if ((error = copyin(uap->rlp, &slim, sizeof(slim))) != 0) return error; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); lim_rlimit(td->td_proc, rl, &curlim); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); /* * if the limit is SVR4_RLIM64_INFINITY, then we set it to our --- //depot/vendor/freebsd/src/sys/compat/svr4/svr4_signal.c 2005/09/28 07:07:24 +++ //depot/user/kris/contention/sys/compat/svr4/svr4_signal.c 2007/08/31 20:34:30 @@ -410,9 +410,9 @@ { sigset_t mask; - PROC_LOCK(p); + PROC_RLOCK(p); mask = td->td_sigmask; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); SIGDELSET(mask, signum); return kern_sigsuspend(td, mask); } @@ -465,11 +465,11 @@ case 1: /* sigpending */ if (uap->mask == NULL) return 0; - PROC_LOCK(p); + PROC_RLOCK(p); bss = p->p_siglist; SIGSETOR(bss, td->td_siglist); SIGSETAND(bss, td->td_sigmask); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); bsd_to_svr4_sigset(&bss, &sss); break; @@ -534,9 +534,7 @@ switch (uap->func) { case 0: DPRINTF(("getcontext(%p)\n", uap->uc)); - PROC_LOCK(td->td_proc); onstack = sigonstack(cpu_getstack(td)); - PROC_UNLOCK(td->td_proc); svr4_getcontext(td, &uc, &td->td_sigmask, onstack); return copyout(&uc, uap->uc, sizeof(uc)); @@ -570,8 +568,8 @@ { sigset_t mask; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); mask = td->td_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); return kern_sigsuspend(td, mask); } --- //depot/vendor/freebsd/src/sys/compat/svr4/svr4_stream.c 2006/08/05 22:06:35 +++ //depot/user/kris/contention/sys/compat/svr4/svr4_stream.c 2007/08/16 16:17:38 @@ -1481,8 +1481,6 @@ uap->dat, uap->flags); #endif /* DEBUG_SVR4 */ - FILE_LOCK_ASSERT(fp, MA_NOTOWNED); - if (uap->ctl != NULL) { if ((error = copyin(uap->ctl, &ctl, sizeof(ctl))) != 0) { #ifdef DEBUG_SVR4 @@ -1656,8 +1654,6 @@ error = 0; afp = NULL; - FILE_LOCK_ASSERT(fp, MA_NOTOWNED); - memset(&sc, 0, sizeof(sc)); #ifdef DEBUG_SVR4 --- //depot/vendor/freebsd/src/sys/conf/options 2007/09/12 07:47:27 +++ //depot/user/kris/contention/sys/conf/options 2007/09/14 21:34:44 @@ -248,6 +248,9 @@ # Enable gjournal-based UFS journal. UFS_GJOURNAL opt_ufs.h +# Disable shared lookups for UFS +NO_UFS_LOOKUP_SHARED opt_ufs.h + # The below sentence is not in English, and neither is this one. # We plan to remove the static dependences above, with a # _ROOT option to control if it usable as root. This list @@ -540,6 +543,7 @@ LOCK_PROFILING opt_global.h LOCK_PROFILING_FAST opt_global.h LOCK_PROFILING_SHARED opt_global.h +SPINLOCK_PROFILING opt_global.h MSIZE opt_global.h REGRESSION opt_global.h RESTARTABLE_PANICS opt_global.h --- //depot/vendor/freebsd/src/sys/ddb/db_command.c 2007/01/17 15:10:53 +++ //depot/user/kris/contention/sys/ddb/db_command.c 2007/08/31 20:34:30 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -591,7 +592,7 @@ DB_ERROR(("Can't lock process with pid %ld\n", (long) pid)); else { psignal(p, sig); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } out: --- //depot/vendor/freebsd/src/sys/dev/ata/ata-chipset.c 2007/09/10 19:22:16 +++ //depot/user/kris/contention/sys/dev/ata/ata-chipset.c 2007/09/14 21:34:44 @@ -4126,7 +4126,9 @@ mode = ata_limit_mode(dev, mode, ctlr->chip->max_dma); +#if 0 mode = ata_check_80pin(dev, mode); +#endif error = ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); --- //depot/vendor/freebsd/src/sys/dev/bktr/bktr_core.c 2005/12/05 18:57:50 +++ //depot/user/kris/contention/sys/dev/bktr/bktr_core.c 2007/08/31 20:34:30 @@ -111,6 +111,7 @@ #include #include #include +#include #include #include #include @@ -124,8 +125,8 @@ #if (__FreeBSD_version < 500000) #include /* for DELAY */ -#define PROC_LOCK(p) -#define PROC_UNLOCK(p) +#define PROC_WLOCK(p) +#define PROC_WUNLOCK(p) #include #else #include @@ -168,8 +169,8 @@ /* *** BSDI *** */ /****************/ #ifdef __bsdi__ -#define PROC_LOCK(p) -#define PROC_UNLOCK(p) +#define PROC_WLOCK(p) +#define PROC_WUNLOCK(p) #endif /* __bsdi__ */ @@ -210,8 +211,8 @@ return (bktr->bktr_dev.dv_xname); } -#define PROC_LOCK(p) -#define PROC_UNLOCK(p) +#define PROC_WLOCK(p) +#define PROC_WUNLOCK(p) #endif /* __NetBSD__ || __OpenBSD__ */ @@ -917,9 +918,9 @@ */ if (bktr->proc != NULL) { - PROC_LOCK(bktr->proc); + PROC_WLOCK(bktr->proc); psignal( bktr->proc, bktr->signal); - PROC_UNLOCK(bktr->proc); + PROC_WUNLOCK(bktr->proc); } /* --- //depot/vendor/freebsd/src/sys/dev/hwpmc/hwpmc_logging.c 2007/04/19 08:07:15 +++ //depot/user/kris/contention/sys/dev/hwpmc/hwpmc_logging.c 2007/08/31 20:34:30 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -246,9 +247,9 @@ td = curthread; mycred = td->td_ucred; - PROC_LOCK(po->po_owner); + PROC_RLOCK(po->po_owner); ownercred = crhold(po->po_owner->p_ucred); - PROC_UNLOCK(po->po_owner); + PROC_RUNLOCK(po->po_owner); PMCDBG(LOG,INI,1, "po=%p kt=%p", po, po->po_kthread); KASSERT(po->po_kthread == curthread->td_proc, @@ -322,9 +323,9 @@ /* XXX also check for SIGPIPE if a socket */ /* send a SIGIO to the owner and exit */ - PROC_LOCK(po->po_owner); + PROC_WLOCK(po->po_owner); psignal(po->po_owner, SIGIO); - PROC_UNLOCK(po->po_owner); + PROC_WUNLOCK(po->po_owner); po->po_error = error; /* save for flush log */ @@ -572,9 +573,9 @@ goto error; /* mark process as using HWPMCs */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_HWPMC; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* create a log initialization entry */ PMCLOG_RESERVE_WITH_ERROR(po, INITIALIZE, --- //depot/vendor/freebsd/src/sys/dev/hwpmc/hwpmc_mod.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/dev/hwpmc/hwpmc_mod.c 2007/08/31 20:34:30 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -842,9 +843,9 @@ /* if the PMC now lacks targets, send the owner a SIGIO */ if (LIST_EMPTY(&pm->pm_targets)) { p = pm->pm_owner->po_owner; - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGIO); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); PMCDBG(PRC,SIG,2, "signalling proc=%p signal=%d", p, SIGIO); @@ -869,15 +870,15 @@ if ((o = pm->pm_owner->po_owner) == t) return 0; - PROC_LOCK(o); + PROC_RLOCK(o); oc = o->p_ucred; crhold(oc); - PROC_UNLOCK(o); + PROC_RUNLOCK(o); - PROC_LOCK(t); + PROC_RLOCK(t); tc = t->p_ucred; crhold(tc); - PROC_UNLOCK(t); + PROC_RUNLOCK(t); /* * The effective uid of the PMC owner should match at least one @@ -959,9 +960,9 @@ FREE(freepath, M_TEMP); } /* mark process as using HWPMCs */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_HWPMC; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return 0; } @@ -1077,9 +1078,9 @@ if (flags & PMC_FLAG_REMOVE) FREE(pp, M_PMC); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag &= ~P_HWPMC; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return 0; } @@ -1585,9 +1586,8 @@ pmclog_process_procexec(po, PMC_ID_INVALID, p->p_pid, pk->pm_entryaddr, fullpath); - PROC_LOCK(p); + /* Lockless read. */ is_using_hwpmcs = p->p_flag & P_HWPMC; - PROC_UNLOCK(p); if (!is_using_hwpmcs) { if (freepath) @@ -2131,9 +2131,9 @@ LIST_INSERT_HEAD(&po->po_pmcs, pmc, pm_next); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_HWPMC; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (po->po_flags & PMC_PO_OWNS_LOGFILE) pmclog_process_pmcallocate(pmc); @@ -3149,7 +3149,7 @@ } /* lookup pid */ - if ((p = pfind(a.pm_pid)) == NULL) { + if ((p = pfindr(a.pm_pid)) == NULL) { error = ESRCH; break; } @@ -3159,7 +3159,7 @@ */ if (p->p_flag & P_WEXIT) { error = ESRCH; - PROC_UNLOCK(p); /* pfind() returns a locked process */ + PROC_RUNLOCK(p); /* pfindr() returns a locked process */ break; } @@ -3169,7 +3169,7 @@ */ error = p_candebug(curthread, p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error == 0) error = pmc_attach_process(p, pm); @@ -3199,7 +3199,7 @@ if ((error = pmc_find_pmc(a.pm_pmc, &pm)) != 0) break; - if ((p = pfind(a.pm_pid)) == NULL) { + if ((p = pfindr(a.pm_pid)) == NULL) { error = ESRCH; break; } @@ -3212,7 +3212,7 @@ if (p->p_flag & P_WEXIT) error = ESRCH; - PROC_UNLOCK(p); /* pfind() returns a locked process */ + PROC_RUNLOCK(p); /* pfindr() returns a locked process */ if (error == 0) error = pmc_detach_process(p, pm); @@ -3834,9 +3834,8 @@ struct pmc_owner *po; pmc_value_t newvalue, tmp; - PROC_LOCK(p); + /* Lockless read. */ is_using_hwpmcs = p->p_flag & P_HWPMC; - PROC_UNLOCK(p); /* * Log a sysexit event to all SS PMC owners. @@ -3999,9 +3998,8 @@ (void) flags; /* unused parameter */ - PROC_LOCK(p1); + /* Lockless read. */ is_using_hwpmcs = p1->p_flag & P_HWPMC; - PROC_UNLOCK(p1); /* * If there are system-wide sampling PMCs active, we need to @@ -4063,9 +4061,9 @@ /* * Now mark the new process as being tracked by this driver. */ - PROC_LOCK(newproc); + PROC_WLOCK(newproc); newproc->p_flag |= P_HWPMC; - PROC_UNLOCK(newproc); + PROC_WUNLOCK(newproc); done: sx_xunlock(&pmc_sx); @@ -4280,9 +4278,9 @@ po->po_owner->p_pid, po->po_owner->p_comm); - PROC_LOCK(po->po_owner); + PROC_WLOCK(po->po_owner); psignal(po->po_owner, SIGBUS); - PROC_UNLOCK(po->po_owner); + PROC_WUNLOCK(po->po_owner); pmc_destroy_owner_descriptor(po); } --- //depot/vendor/freebsd/src/sys/dev/hwpmc/hwpmc_x86.c 2006/04/04 02:38:36 +++ //depot/user/kris/contention/sys/dev/hwpmc/hwpmc_x86.c 2007/09/08 18:21:40 @@ -64,7 +64,7 @@ cputype = -1; switch (cpu_id & 0xF00) { -#if defined(__i386__) +#if defined(__i386__) || defined(__amd64__) case 0x500: /* Pentium family processors */ cputype = PMC_CPU_INTEL_P5; break; @@ -82,9 +82,12 @@ case 0x7: case 0x8: case 0xA: case 0xB: cputype = PMC_CPU_INTEL_PIII; break; - case 0x9: case 0xD: case 0xE: + case 0x9: case 0xD: case 0xE: case 0xF: cputype = PMC_CPU_INTEL_PM; break; + default: + printf("cpu_type=0x%x cpu_model=0x%x\n", (cpu_id & 0xF00), + ((cpu_id & 0xF0) >> 4)); } break; #endif @@ -127,7 +130,7 @@ break; #endif -#if defined(__i386__) +#if defined(__i386__) || defined(__amd64__) /* * P6 Family Processors */ @@ -144,7 +147,8 @@ /* * Intel Pentium PMCs. */ - +#endif +#if defined(__i386__) case PMC_CPU_INTEL_P5: error = pmc_initialize_p5(pmc_mdep); break; --- //depot/vendor/freebsd/src/sys/dev/ieee488/ibfoo.c 2005/03/07 11:10:19 +++ //depot/user/kris/contention/sys/dev/ieee488/ibfoo.c 2007/03/27 05:42:40 @@ -809,7 +809,7 @@ ib = malloc(sizeof *ib, M_IBFOO, M_WAITOK | M_ZERO); LIST_INIT(&ib->handles); - callout_init(&ib->callout, 1); + callout_init(&ib->callout, CALLOUT_MPSAFE); ib->unrhdr = new_unrhdr(0, INT_MAX, NULL); dev->si_drv2 = ib; ib->u = u; --- //depot/vendor/freebsd/src/sys/dev/iscsi/initiator/isc_soc.c 2007/07/24 15:37:14 +++ //depot/user/kris/contention/sys/dev/iscsi/initiator/isc_soc.c 2007/08/31 20:34:30 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -519,9 +520,9 @@ sdebug(2, "terminated, flags=%x so_count=%d so_state=%x error=%d", sp->flags, so->so_count, so->so_state, error); if((sp->proc != NULL) && sp->signal) { - PROC_LOCK(sp->proc); + PROC_WLOCK(sp->proc); psignal(sp->proc, sp->signal); - PROC_UNLOCK(sp->proc); + PROC_WUNLOCK(sp->proc); sp->flags |= ISC_SIGNALED; sdebug(2, "pid=%d signaled(%d)", sp->proc->p_pid, sp->signal); } --- //depot/vendor/freebsd/src/sys/dev/md/md.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/dev/md/md.c 2007/06/05 06:30:35 @@ -609,15 +609,14 @@ for (i = bp->bio_offset / PAGE_SIZE; i <= lastp; i++) { len = ((i == lastp) ? lastend : PAGE_SIZE) - offs; - m = vm_page_grab(sc->object, i, - VM_ALLOC_NORMAL|VM_ALLOC_RETRY); + m = vm_page_grab(sc->object, i, VM_ALLOC_NORMAL|VM_ALLOC_RETRY); VM_OBJECT_UNLOCK(sc->object); sched_pin(); sf = sf_buf_alloc(m, SFB_CPUPRIVATE); VM_OBJECT_LOCK(sc->object); - if (bp->bio_cmd == BIO_READ) { - if (m->valid != VM_PAGE_BITS_ALL) - rv = vm_pager_get_pages(sc->object, &m, 1, 0); + if ((bp->bio_cmd == BIO_READ || len != PAGE_SIZE) && + m->valid != VM_PAGE_BITS_ALL) { + rv = vm_pager_get_pages(sc->object, &m, 1, 0); if (rv == VM_PAGER_ERROR) { sf_buf_free(sf); sched_unpin(); @@ -626,44 +625,47 @@ vm_page_unlock_queues(); break; } + } + switch (bp->bio_cmd) { + case BIO_READ: bcopy((void *)(sf_buf_kva(sf) + offs), p, len); - } else if (bp->bio_cmd == BIO_WRITE) { - if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL) - rv = vm_pager_get_pages(sc->object, &m, 1, 0); - if (rv == VM_PAGER_ERROR) { - sf_buf_free(sf); - sched_unpin(); - vm_page_lock_queues(); - vm_page_wakeup(m); - vm_page_unlock_queues(); - break; - } + break; + case BIO_WRITE: bcopy(p, (void *)(sf_buf_kva(sf) + offs), len); m->valid = VM_PAGE_BITS_ALL; -#if 0 - } else if (bp->bio_cmd == BIO_DELETE) { - if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL) - rv = vm_pager_get_pages(sc->object, &m, 1, 0); - if (rv == VM_PAGER_ERROR) { - sf_buf_free(sf); - sched_unpin(); - vm_page_lock_queues(); - vm_page_wakeup(m); - vm_page_unlock_queues(); - break; - } + break; + case BIO_DELETE: bzero((void *)(sf_buf_kva(sf) + offs), len); - vm_page_dirty(m); - m->valid = VM_PAGE_BITS_ALL; -#endif + break; } sf_buf_free(sf); sched_unpin(); vm_page_lock_queues(); - vm_page_wakeup(m); - vm_page_activate(m); - if (bp->bio_cmd == BIO_WRITE) + switch (bp->bio_cmd) { + case BIO_READ: + vm_page_wakeup(m); + vm_page_activate(m); + break; + case BIO_WRITE: + vm_page_wakeup(m); + vm_page_activate(m); vm_page_dirty(m); + break; + case BIO_DELETE: +#if 0 + vm_page_set_invalid(m, offs, len); + if (m->valid != 0) { + vm_page_wakeup(m); + vm_page_activate(m); + } else { +#endif + vm_pager_page_unswapped(m); + vm_page_free(m); +#if 0 + } +#endif + break; + } vm_page_unlock_queues(); /* Actions on further pages start at offset 0 */ @@ -1082,7 +1084,7 @@ mdio->md_unit = sc->unit; sc->mediasize = mdio->md_mediasize; if (mdio->md_sectorsize == 0) - sc->sectorsize = DEV_BSIZE; + sc->sectorsize = PAGE_SIZE; else sc->sectorsize = mdio->md_sectorsize; error = EDOOFUS; --- //depot/vendor/freebsd/src/sys/dev/mem/memdev.c 2004/08/04 18:30:45 +++ //depot/user/kris/contention/sys/dev/mem/memdev.c 2007/07/26 22:46:10 @@ -50,7 +50,7 @@ static struct cdevsw mem_cdevsw = { .d_version = D_VERSION, - .d_flags = D_MEM|D_NEEDGIANT, + .d_flags = D_MEM, .d_open = memopen, .d_read = memrw, .d_write = memrw, --- //depot/vendor/freebsd/src/sys/dev/mfi/mfi.c 2007/08/26 00:04:27 +++ //depot/user/kris/contention/sys/dev/mfi/mfi.c 2007/08/31 20:34:30 @@ -71,6 +71,7 @@ #include #include #include +#include #include #include @@ -518,7 +519,7 @@ bus_generic_attach(sc->mfi_dev); /* Start the timeout watchdog */ - callout_init(&sc->mfi_watchdog_callout, 1); + callout_init(&sc->mfi_watchdog_callout, CALLOUT_MPSAFE); callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz, mfi_timeout, sc); @@ -1384,9 +1385,9 @@ TAILQ_FOREACH_SAFE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) { TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry, aen_link); - PROC_LOCK(mfi_aen_entry->p); + PROC_WLOCK(mfi_aen_entry->p); psignal(mfi_aen_entry->p, SIGIO); - PROC_UNLOCK(mfi_aen_entry->p); + PROC_WUNLOCK(mfi_aen_entry->p); free(mfi_aen_entry, M_MFIBUF); } } --- //depot/vendor/freebsd/src/sys/dev/sound/midi/midi.c 2007/04/02 06:07:42 +++ //depot/user/kris/contention/sys/dev/sound/midi/midi.c 2007/08/31 20:34:30 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -561,9 +562,9 @@ } selwakeup(&m->rsel); if (m->async) { - PROC_LOCK(m->async); + PROC_WLOCK(m->async); psignal(m->async, SIGIO); - PROC_UNLOCK(m->async); + PROC_WUNLOCK(m->async); } #if 0 } @@ -603,9 +604,9 @@ } selwakeup(&m->wsel); if (m->async) { - PROC_LOCK(m->async); + PROC_WLOCK(m->async); psignal(m->async, SIGIO); - PROC_UNLOCK(m->async); + PROC_WUNLOCK(m->async); } } mtx_unlock(&m->qlock); --- //depot/vendor/freebsd/src/sys/dev/sound/midi/mpu401.c 2007/02/25 13:57:05 +++ //depot/user/kris/contention/sys/dev/sound/midi/mpu401.c 2007/03/27 05:42:40 @@ -177,7 +177,7 @@ kobj_init((kobj_t)m, cls); - callout_init(&m->timer, 1); + callout_init(&m->timer, CALLOUT_MPSAFE); m->si = softintr; m->cookie = cookie; --- //depot/vendor/freebsd/src/sys/dev/streams/streams.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/dev/streams/streams.c 2007/08/16 16:17:38 @@ -251,12 +251,7 @@ return error; } - FILE_LOCK(fp); - fp->f_data = so; - fp->f_flag = FREAD|FWRITE; - fp->f_ops = &svr4_netops; - fp->f_type = DTYPE_SOCKET; - FILE_UNLOCK(fp); + finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &svr4_netops); /* * Allocate a stream structure and attach it to this socket. --- //depot/vendor/freebsd/src/sys/dev/syscons/scmouse.c 2007/05/25 13:18:28 +++ //depot/user/kris/contention/sys/dev/syscons/scmouse.c 2007/08/31 20:34:30 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -763,10 +764,10 @@ cur_scp->mouse_proc = NULL; cur_scp->mouse_pid = 0; if (p1) - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); } else { psignal(cur_scp->mouse_proc, cur_scp->mouse_signal); - PROC_UNLOCK(cur_scp->mouse_proc); + PROC_WUNLOCK(cur_scp->mouse_proc); break; } } @@ -818,10 +819,10 @@ cur_scp->mouse_proc = NULL; cur_scp->mouse_pid = 0; if (p1) - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); } else { psignal(cur_scp->mouse_proc, cur_scp->mouse_signal); - PROC_UNLOCK(cur_scp->mouse_proc); + PROC_WUNLOCK(cur_scp->mouse_proc); break; } } --- //depot/vendor/freebsd/src/sys/dev/syscons/syscons.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/dev/syscons/syscons.c 2007/08/31 20:34:30 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -940,15 +941,15 @@ mode = (struct vt_mode *)data; DPRINTF(5, ("%s%d: VT_SETMODE ", SC_DRIVER_NAME, sc->unit)); if (scp->smode.mode == VT_PROCESS) { - p1 = pfind(scp->pid); + p1 = pfindr(scp->pid); if (scp->proc == p1 && scp->proc != td->td_proc) { if (p1) - PROC_UNLOCK(p1); + PROC_RUNLOCK(p1); DPRINTF(5, ("error EPERM\n")); return EPERM; } if (p1) - PROC_UNLOCK(p1); + PROC_RUNLOCK(p1); } s = spltty(); if (mode->mode == VT_AUTO) { @@ -2185,10 +2186,10 @@ if (sc->switch_in_progress && (cur_scp->smode.mode == VT_PROCESS) && cur_scp->proc) { - p = pfind(cur_scp->pid); + p = pfindr(cur_scp->pid); if (cur_scp->proc != p) { if (p) - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * The controlling process has died!!. Do some clean up. * NOTE:`cur_scp->proc' and `cur_scp->smode.mode' @@ -2220,7 +2221,7 @@ } } else { if (p) - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * The controlling process is alive, but not responding... * It is either buggy or it may be just taking time. @@ -2401,8 +2402,8 @@ struct proc *p; if (scp->proc) { - if ((p = pfind(scp->pid)) != NULL) - PROC_UNLOCK(p); + if ((p = pfindr(scp->pid)) != NULL) + PROC_RUNLOCK(p); if (scp->proc == p) return TRUE; scp->proc = NULL; @@ -2418,9 +2419,9 @@ if (scp->smode.mode != VT_PROCESS) return FALSE; scp->status |= SWITCH_WAIT_REL; - PROC_LOCK(scp->proc); + PROC_WLOCK(scp->proc); psignal(scp->proc, scp->smode.relsig); - PROC_UNLOCK(scp->proc); + PROC_WUNLOCK(scp->proc); DPRINTF(5, ("sending relsig to %d\n", scp->pid)); return TRUE; } @@ -2433,9 +2434,9 @@ if (scp->sc->unit == sc_console_unit) cnavailable(sc_consptr, FALSE); scp->status |= SWITCH_WAIT_ACQ; - PROC_LOCK(scp->proc); + PROC_WLOCK(scp->proc); psignal(scp->proc, scp->smode.acqsig); - PROC_UNLOCK(scp->proc); + PROC_WUNLOCK(scp->proc); DPRINTF(5, ("sending acqsig to %d\n", scp->pid)); return TRUE; } --- //depot/vendor/freebsd/src/sys/dev/usb/if_aue.c 2007/06/23 06:02:34 +++ //depot/user/kris/contention/sys/dev/usb/if_aue.c 2007/07/26 22:47:05 @@ -1204,7 +1204,7 @@ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - callout_init(&sc->aue_tick_callout, 1); + callout_init(&sc->aue_tick_callout, CALLOUT_MPSAFE); (void) callout_reset(&sc->aue_tick_callout, hz, aue_tick, sc); return; } --- //depot/vendor/freebsd/src/sys/dev/usb/uhid.c 2007/06/21 14:59:23 +++ //depot/user/kris/contention/sys/dev/usb/uhid.c 2007/08/31 20:34:30 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -399,9 +400,9 @@ selwakeuppri(&sc->sc_rsel, PZERO); if (sc->sc_async != NULL) { DPRINTFN(3, ("uhid_intr: sending SIGIO %p\n", sc->sc_async)); - PROC_LOCK(sc->sc_async); + PROC_WLOCK(sc->sc_async); psignal(sc->sc_async, SIGIO); - PROC_UNLOCK(sc->sc_async); + PROC_WUNLOCK(sc->sc_async); } } --- //depot/vendor/freebsd/src/sys/dev/usb/usb.c 2007/06/20 05:13:26 +++ //depot/user/kris/contention/sys/dev/usb/usb.c 2007/08/31 20:34:30 @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -817,9 +818,9 @@ wakeup(&usb_events); selwakeuppri(&usb_selevent, PZERO); if (usb_async_proc != NULL) { - PROC_LOCK(usb_async_proc); + PROC_WLOCK(usb_async_proc); psignal(usb_async_proc, SIGIO); - PROC_UNLOCK(usb_async_proc); + PROC_WUNLOCK(usb_async_proc); } splx(s); } --- //depot/vendor/freebsd/src/sys/dev/utopia/utopia.c 2005/06/22 06:55:39 +++ //depot/user/kris/contention/sys/dev/utopia/utopia.c 2007/08/31 20:34:30 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -652,10 +653,10 @@ if ((kp = utopia_kproc) != NULL) { utopia_kproc = NULL; wakeup_one(&utopia_list); - PROC_LOCK(kp); + PROC_WLOCK(kp); UTP_WUNLOCK_LIST(); - msleep(kp, &kp->p_mtx, PWAIT, "utopia_destroy", 0); - PROC_UNLOCK(kp); + rw_sleep(kp, &kp->p_rwlock, PWAIT, "utopia_destroy", 0); + PROC_WUNLOCK(kp); } else UTP_WUNLOCK_LIST(); mtx_destroy(&utopia_list_mtx); --- //depot/vendor/freebsd/src/sys/fs/coda/coda_psdev.c 2007/07/12 21:08:28 +++ //depot/user/kris/contention/sys/fs/coda/coda_psdev.c 2007/08/31 20:34:30 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -555,10 +556,10 @@ can not do this. A better solution is necessary. */ i = 0; - PROC_LOCK(p); + PROC_WLOCK(p); psig_omask = td->td_sigmask; do { - error = msleep(&vmp->vm_sleep, &p->p_mtx, + error = rw_sleep(&vmp->vm_sleep, &p->p_rwlock, (coda_call_sleep|coda_pcatch), "coda_call", hz*2); if (error == 0) @@ -613,7 +614,7 @@ } while (error && i++ < 128 && VC_OPEN(vcp)); td->td_sigmask = psig_omask; signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #else (void) tsleep(&vmp->vm_sleep, coda_call_sleep, "coda_call", 0); #endif --- //depot/vendor/freebsd/src/sys/fs/coda/coda_vnops.c 2007/07/20 11:17:45 +++ //depot/user/kris/contention/sys/fs/coda/coda_vnops.c 2007/08/31 20:34:30 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include --- //depot/vendor/freebsd/src/sys/fs/devfs/devfs_vnops.c 2007/07/26 17:02:32 +++ //depot/user/kris/contention/sys/fs/devfs/devfs_vnops.c 2007/08/16 16:17:38 @@ -800,12 +800,9 @@ if(fp == NULL) return (error); #endif - FILE_LOCK(fp); KASSERT(fp->f_ops == &badfileops, ("Could not vnode bypass device on fdops %p", fp->f_ops)); - fp->f_data = dev; - fp->f_ops = &devfs_ops_f; - FILE_UNLOCK(fp); + finit(fp, fp->f_flag, DTYPE_VNODE, dev, &devfs_ops_f); return (error); } --- //depot/vendor/freebsd/src/sys/fs/fdescfs/fdesc_vfsops.c 2007/04/04 09:18:07 +++ //depot/user/kris/contention/sys/fs/fdescfs/fdesc_vfsops.c 2007/08/31 20:34:30 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -172,9 +173,9 @@ * limit is ever reduced below the current number * of open files... ] */ - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); lim = lim_cur(td->td_proc, RLIMIT_NOFILE); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); fdp = td->td_proc->p_fd; FILEDESC_SLOCK(fdp); last = min(fdp->fd_nfiles, lim); --- //depot/vendor/freebsd/src/sys/fs/fifofs/fifo_vnops.c 2007/07/26 17:02:32 +++ //depot/user/kris/contention/sys/fs/fifofs/fifo_vnops.c 2007/08/16 16:17:38 @@ -294,11 +294,8 @@ } mtx_unlock(&fifo_mtx); KASSERT(fp != NULL, ("can't fifo/vnode bypass")); - FILE_LOCK(fp); KASSERT(fp->f_ops == &badfileops, ("not badfileops in fifo_open")); - fp->f_data = fip; - fp->f_ops = &fifo_ops_f; - FILE_UNLOCK(fp); + finit(fp, fp->f_flag, DTYPE_FIFO, fip, &fifo_ops_f); return (0); } @@ -713,9 +710,7 @@ if (uio->uio_resid == 0) return (0); sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0; - mtx_lock(&Giant); error = soreceive(fip->fi_readsock, NULL, uio, NULL, NULL, &sflags); - mtx_unlock(&Giant); return (error); } @@ -735,8 +730,6 @@ fip = fp->f_data; KASSERT(uio->uio_rw == UIO_WRITE,("fifo_write mode")); sflags = (fp->f_flag & FNONBLOCK) ? MSG_NBIO : 0; - mtx_lock(&Giant); error = sosend(fip->fi_writesock, NULL, uio, 0, NULL, sflags, td); - mtx_unlock(&Giant); return (error); } --- //depot/vendor/freebsd/src/sys/fs/msdosfs/msdosfs_vnops.c 2007/08/31 22:32:13 +++ //depot/user/kris/contention/sys/fs/msdosfs/msdosfs_vnops.c 2007/09/14 21:34:44 @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include @@ -703,14 +704,18 @@ * If they've exceeded their filesize limit, tell them about it. */ if (td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if ((uoff_t)uio->uio_offset + uio->uio_resid > lim_cur(td->td_proc, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(td->td_proc)) { + PROC_RUNLOCK(td->td_proc); + PROC_WLOCK(td->td_proc); + } psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } /* --- //depot/vendor/freebsd/src/sys/fs/nwfs/nwfs_io.c 2007/06/01 14:37:18 +++ //depot/user/kris/contention/sys/fs/nwfs/nwfs_io.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -236,14 +237,18 @@ } if (uiop->uio_resid == 0) return 0; if (td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (uiop->uio_offset + uiop->uio_resid > lim_cur(td->td_proc, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(td->td_proc)) { + PROC_RUNLOCK(td->td_proc); + PROC_WLOCK(td->td_proc); + } psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } error = ncp_write(NWFSTOCONN(nmp), &np->n_fh, uiop, cred); NCPVNDEBUG("after: ofs=%d,resid=%d\n",(int)uiop->uio_offset, uiop->uio_resid); --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs.c 2007/03/12 12:21:59 +++ //depot/user/kris/contention/sys/fs/procfs/procfs.c 2007/08/31 20:34:30 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -103,7 +104,7 @@ int procfs_attr(PFS_ATTR_ARGS) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); /* XXX inefficient, split into separate functions */ if (strcmp(pn->pn_name, "ctl") == 0 || @@ -132,7 +133,7 @@ int procfs_notsystem(PFS_VIS_ARGS) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); return ((p->p_flag & P_SYSTEM) == 0); } @@ -143,7 +144,7 @@ int procfs_candebug(PFS_VIS_ARGS) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); return ((p->p_flag & P_SYSTEM) == 0 && p_candebug(td, p) == 0); } --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_ctl.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_ctl.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -117,7 +118,7 @@ */ if (op == PROCFS_CTL_ATTACH) { sx_xlock(&proctree_lock); - PROC_LOCK(p); + PROC_WLOCK(p); if ((error = p_candebug(td, p)) != 0) goto out; if (p->p_flag & P_TRACED) { @@ -148,7 +149,7 @@ } psignal(p, SIGSTOP); out: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sx_xunlock(&proctree_lock); return (error); } @@ -159,10 +160,10 @@ * they have previously attached, but no longer have permission to * debug. */ - PROC_LOCK(p); + PROC_WLOCK(p); if (op != PROCFS_CTL_DETACH && ((error = p_candebug(td, p)))) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } @@ -179,7 +180,7 @@ default: if (!TRACE_WAIT_P(td->td_proc, p)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EBUSY); } } @@ -207,7 +208,7 @@ case PROCFS_CTL_DETACH: /* if not being traced, then this is a painless no-op */ if ((p->p_flag & P_TRACED) == 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -216,24 +217,24 @@ /* remove pending SIGTRAP, else the process will die */ sigqueue_delete_proc(p, SIGTRAP); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* give process back to original parent */ sx_xlock(&proctree_lock); if (p->p_oppid != p->p_pptr->p_pid) { struct proc *pp; - pp = pfind(p->p_oppid); - PROC_LOCK(p); + pp = pfindr(p->p_oppid); + PROC_WLOCK(p); if (pp) { - PROC_UNLOCK(pp); + PROC_RUNLOCK(pp); proc_reparent(p, pp); } } else - PROC_LOCK(p); + PROC_WLOCK(p); p->p_oppid = 0; p->p_flag &= ~P_WAITED; /* XXX ? */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sx_xunlock(&proctree_lock); wakeup(td->td_proc); /* XXX for CTL_WAIT below ? */ @@ -246,7 +247,7 @@ */ case PROCFS_CTL_STEP: error = proc_sstep(FIRST_THREAD_IN_PROC(p)); /* XXXKSE */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (error) return (error); break; @@ -257,7 +258,7 @@ */ case PROCFS_CTL_RUN: p->p_flag &= ~P_STOPPED_SIG; /* this uses SIGSTOP */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); break; /* @@ -271,16 +272,16 @@ (P_SHOULDSTOP(p)) && (p->p_flag & P_TRACED) && (p->p_pptr == td->td_proc)) - error = msleep(p, &p->p_mtx, + error = rw_sleep(p, &p->p_rwlock, PWAIT|PCATCH, "procfsx", 0); if (error == 0 && !TRACE_WAIT_P(td->td_proc, p)) error = EBUSY; } else { while (error == 0 && P_SHOULDSTOP(p)) - error = msleep(p, &p->p_mtx, + error = rw_sleep(p, &p->p_rwlock, PWAIT|PCATCH, "procfs", 0); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); default: panic("procfs_control"); @@ -333,7 +334,7 @@ nm = findname(signames, sbuf_data(sb), sbuf_len(sb)); if (nm) { printf("procfs: got a sig%s\n", sbuf_data(sb)); - PROC_LOCK(p); + PROC_WLOCK(p); /* This is very broken XXXKSE: */ if (TRACE_WAIT_P(td->td_proc, p)) { @@ -349,7 +350,7 @@ PROC_SUNLOCK(p); } else psignal(p, nm->nm_val); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = 0; } } --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_dbregs.c 2007/04/15 13:26:55 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_dbregs.c 2007/08/31 20:34:30 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -98,10 +99,10 @@ if (uio->uio_offset != 0) return (0); - PROC_LOCK(p); + PROC_RLOCK(p); KASSERT(p->p_lock > 0, ("proc not held")); if (p_candebug(td, p) != 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EPERM); } @@ -110,18 +111,17 @@ #ifdef COMPAT_IA32 if (td->td_proc->p_sysent == &ia32_freebsd_sysvec) { if (td2->td_proc->p_sysent != &ia32_freebsd_sysvec) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EINVAL); } wrap32 = 1; } #endif error = PROC(read, dbregs, td2, &r); - if (error == 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); + if (error == 0) error = UIOMOVE_FROMBUF(r, uio); - PROC_LOCK(p); - } + PROC_WLOCK(p); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (!P_SHOULDSTOP(p)) /* XXXKSE should be P_TRACED? */ error = EBUSY; @@ -129,7 +129,7 @@ /* XXXKSE: */ error = PROC(write, dbregs, td2, &r); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_fpregs.c 2007/04/15 13:31:56 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_fpregs.c 2007/08/31 20:34:30 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -92,10 +93,10 @@ if (uio->uio_offset != 0) return (0); - PROC_LOCK(p); + PROC_RLOCK(p); KASSERT(p->p_lock > 0, ("proc not held")); if (p_candebug(td, p)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EPERM); } @@ -104,18 +105,17 @@ #ifdef COMPAT_IA32 if (td->td_proc->p_sysent == &ia32_freebsd_sysvec) { if (td2->td_proc->p_sysent != &ia32_freebsd_sysvec) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EINVAL); } wrap32 = 1; } #endif error = PROC(read, fpregs, td2, &r); - if (error == 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); + if (error == 0) error = UIOMOVE_FROMBUF(r, uio); - PROC_LOCK(p); - } + PROC_WLOCK(p); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (!P_SHOULDSTOP(p)) error = EBUSY; @@ -123,7 +123,7 @@ /* XXXKSE: */ error = PROC(write, fpregs, td2, &r); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_ioctl.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_ioctl.c 2007/08/31 20:34:30 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -72,7 +73,7 @@ KASSERT(p != NULL, ("%s() called without a process", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); error = 0; switch (cmd) { @@ -127,7 +128,7 @@ while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) { /* sleep until p stops */ _PHOLD(p); - error = msleep(&p->p_stype, &p->p_mtx, + error = rw_sleep(&p->p_stype, &p->p_rwlock, PWAIT|PCATCH, "pioctl", 0); _PRELE(p); if (error != 0) @@ -147,7 +148,7 @@ while (p->p_step == 0 && (p->p_flag & P_WEXIT) == 0) { /* sleep until p stops */ _PHOLD(p); - error = msleep(&p->p_stype, &p->p_mtx, + error = rw_sleep(&p->p_stype, &p->p_rwlock, PWAIT|PCATCH, "pioctl", 0); _PRELE(p); if (error != 0) @@ -210,7 +211,7 @@ procfs_close(PFS_CLOSE_ARGS) { if (p != NULL && (p->p_pfsflags & PF_LINGER) == 0) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); p->p_pfsflags = 0; p->p_stops = 0; p->p_step = 0; --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_map.c 2007/04/23 06:17:44 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_map.c 2007/08/31 20:34:30 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -93,9 +94,9 @@ int wrap32 = 0; #endif - PROC_LOCK(p); + PROC_RLOCK(p); error = p_candebug(td, p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error) return (error); --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_mem.c 2005/01/06 18:11:58 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_mem.c 2007/08/31 20:34:30 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -61,9 +62,9 @@ if (uio->uio_resid == 0) return (0); - PROC_LOCK(p); + PROC_RLOCK(p); error = p_candebug(td, p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error == 0) error = proc_rwmem(p, uio); --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_regs.c 2007/04/15 13:26:55 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_regs.c 2007/08/31 20:34:30 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -92,10 +93,9 @@ if (uio->uio_offset != 0) return (0); - PROC_LOCK(p); - PROC_ASSERT_HELD(p); + PROC_RLOCK(p); if (p_candebug(td, p)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EPERM); } @@ -104,18 +104,17 @@ #ifdef COMPAT_IA32 if (td->td_proc->p_sysent == &ia32_freebsd_sysvec) { if (td2->td_proc->p_sysent != &ia32_freebsd_sysvec) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EINVAL); } wrap32 = 1; } #endif error = PROC(read, regs, td2, &r); - if (error == 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); + if (error == 0) error = UIOMOVE_FROMBUF(r, uio); - PROC_LOCK(p); - } + PROC_WLOCK(p); if (error == 0 && uio->uio_rw == UIO_WRITE) { if (!P_SHOULDSTOP(p)) error = EBUSY; @@ -123,7 +122,7 @@ /* XXXKSE: */ error = PROC(write, regs, td2, &r); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_rlimit.c 2005/01/06 18:11:58 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_rlimit.c 2007/08/31 20:34:30 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -70,9 +71,9 @@ * Obtain a private reference to resource limits */ - PROC_LOCK(p); + PROC_RLOCK(p); limp = lim_hold(p->p_limit); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); for (i = 0; i < RLIM_NLIMITS; i++) { --- //depot/vendor/freebsd/src/sys/fs/procfs/procfs_status.c 2007/06/09 21:51:31 +++ //depot/user/kris/contention/sys/fs/procfs/procfs_status.c 2007/08/31 20:34:30 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -74,7 +75,7 @@ int i; pid = p->p_pid; - PROC_LOCK(p); + PROC_WLOCK(p); ppid = p->p_pptr ? p->p_pptr->p_pid : 0; pgid = p->p_pgrp->pg_id; sess = p->p_pgrp->pg_session; @@ -167,7 +168,7 @@ } else { sbuf_printf(sb, " -"); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sbuf_printf(sb, "\n"); return (0); @@ -190,13 +191,13 @@ * Linux behaviour is to return zero-length in this case. */ - PROC_LOCK(p); + PROC_RLOCK(p); if (p->p_args && p_cansee(td, p) == 0) { sbuf_bcpy(sb, p->p_args->ar_args, p->p_args->ar_length); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (p != td->td_proc) { sbuf_printf(sb, "%.*s", MAXCOMLEN, p->p_comm); } else { --- //depot/vendor/freebsd/src/sys/fs/pseudofs/pseudofs.c 2007/04/15 17:12:17 +++ //depot/user/kris/contention/sys/fs/pseudofs/pseudofs.c 2007/08/31 20:34:30 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include --- //depot/vendor/freebsd/src/sys/fs/pseudofs/pseudofs_fileno.c 2007/04/15 17:12:17 +++ //depot/user/kris/contention/sys/fs/pseudofs/pseudofs_fileno.c 2007/08/31 20:34:30 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include --- //depot/vendor/freebsd/src/sys/fs/pseudofs/pseudofs_internal.h 2007/04/15 17:12:17 +++ //depot/user/kris/contention/sys/fs/pseudofs/pseudofs_internal.h 2007/08/31 20:34:30 @@ -131,7 +131,7 @@ PFS_TRACE(("%s", pn->pn_name)); KASSERT(pn->pn_fill != NULL, ("%s(): no callback", __func__)); if (p != NULL) { - PROC_LOCK_ASSERT(p, MA_NOTOWNED); + PROC_LOCK_ASSERT(p, RA_UNLOCKED); PROC_ASSERT_HELD(p); } pfs_assert_not_owned(pn); @@ -145,7 +145,7 @@ PFS_TRACE(("%s", pn->pn_name)); KASSERT(pn->pn_attr != NULL, ("%s(): no callback", __func__)); if (p != NULL) - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); pfs_assert_not_owned(pn); return ((pn->pn_attr)(PFS_ATTR_ARGNAMES)); } @@ -157,7 +157,7 @@ PFS_TRACE(("%s", pn->pn_name)); KASSERT(pn->pn_vis != NULL, ("%s(): no callback", __func__)); KASSERT(p != NULL, ("%s(): no process", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); pfs_assert_not_owned(pn); return ((pn->pn_vis)(PFS_VIS_ARGNAMES)); } @@ -169,7 +169,7 @@ PFS_TRACE(("%s", pn->pn_name)); KASSERT(pn->pn_ioctl != NULL, ("%s(): no callback", __func__)); if (p != NULL) - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); pfs_assert_not_owned(pn); return ((pn->pn_ioctl)(PFS_IOCTL_ARGNAMES)); } @@ -181,7 +181,7 @@ PFS_TRACE(("%s", pn->pn_name)); KASSERT(pn->pn_getextattr != NULL, ("%s(): no callback", __func__)); if (p != NULL) - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); pfs_assert_not_owned(pn); return ((pn->pn_getextattr)(PFS_GETEXTATTR_ARGNAMES)); } @@ -193,7 +193,7 @@ PFS_TRACE(("%s", pn->pn_name)); KASSERT(pn->pn_close != NULL, ("%s(): no callback", __func__)); if (p != NULL) - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); pfs_assert_not_owned(pn); return ((pn->pn_close)(PFS_CLOSE_ARGNAMES)); } --- //depot/vendor/freebsd/src/sys/fs/pseudofs/pseudofs_vncache.c 2007/04/23 19:21:51 +++ //depot/user/kris/contention/sys/fs/pseudofs/pseudofs_vncache.c 2007/08/31 20:34:30 @@ -39,6 +39,7 @@ #include #include #include +#include #include #include --- //depot/vendor/freebsd/src/sys/fs/pseudofs/pseudofs_vnops.c 2007/06/07 15:08:18 +++ //depot/user/kris/contention/sys/fs/pseudofs/pseudofs_vnops.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -77,7 +78,7 @@ if (proc == NULL) return (0); - PROC_LOCK_ASSERT(proc, MA_OWNED); + PROC_LOCK_ASSERT(proc, RA_LOCKED); visible = ((proc->p_flag & P_WEXIT) == 0); if (visible) @@ -107,10 +108,10 @@ if (p) *p = proc; else - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); PFS_RETURN (1); } - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); PFS_RETURN (0); } @@ -167,7 +168,7 @@ error = pn_close(va->a_td, proc, pn); if (proc != NULL) - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); PFS_RETURN (error); } @@ -228,7 +229,7 @@ vap->va_gid = proc->p_ucred->cr_rgid; if (pn->pn_attr != NULL) error = pn_attr(va->a_td, proc, pn, vap); - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); } else { vap->va_uid = 0; vap->va_gid = 0; @@ -268,7 +269,7 @@ error = pn_ioctl(curthread, proc, pn, va->a_command, va->a_data); if (proc != NULL) - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); PFS_RETURN (error); } @@ -303,7 +304,7 @@ va->a_size, va->a_cred); if (proc != NULL) - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); pfs_unlock(pn); PFS_RETURN (error); @@ -499,7 +500,7 @@ PFS_RETURN (EIO); if (proc != NULL) { _PHOLD(proc); - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); } if (pn->pn_flags & PFS_RAWRD) { @@ -578,7 +579,7 @@ if (*p == NULL) *pn = (*pn)->pn_next; else - PROC_LOCK(*p); + PROC_RLOCK(*p); } if ((*pn) == NULL) @@ -586,7 +587,7 @@ if (*p != NULL) { visible = pfs_visible_proc(td, *pn, *p); - PROC_UNLOCK(*p); + PROC_RUNLOCK(*p); } else if (proc != NULL) { visible = pfs_visible_proc(td, *pn, proc); } else { @@ -654,7 +655,7 @@ if (pfs_iterate(curthread, proc, pd, &pn, &p) == -1) { /* nothing left... */ if (proc != NULL) - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); pfs_unlock(pd); sx_sunlock(&allproc_lock); free(buf, M_IOV); @@ -702,7 +703,7 @@ ent += PFS_DELEN; } if (proc != NULL) - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); pfs_unlock(pd); sx_sunlock(&allproc_lock); PFS_TRACE(("%zd bytes", ent - buf)); @@ -739,11 +740,11 @@ if ((proc = pfind(pvd->pvd_pid)) == NULL) PFS_RETURN (EIO); if (proc->p_flag & P_WEXIT) { - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); PFS_RETURN (EIO); } _PHOLD(proc); - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); } /* sbuf_new() can't fail with a static buffer */ @@ -833,7 +834,7 @@ PFS_RETURN (EIO); if (proc != NULL) { _PHOLD(proc); - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); } if (pn->pn_flags & PFS_RAWWR) { --- //depot/vendor/freebsd/src/sys/fs/smbfs/smbfs_io.c 2007/06/04 21:48:11 +++ //depot/user/kris/contention/sys/fs/smbfs/smbfs_io.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -278,14 +279,18 @@ if (uiop->uio_resid == 0) return 0; if (p != NULL) { - PROC_LOCK(p); + PROC_RLOCK(p); if (uiop->uio_offset + uiop->uio_resid > lim_cur(p, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(p)) { + PROC_RUNLOCK(p); + PROC_WLOCK(p); + } psignal(p, SIGXFSZ); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return EFBIG; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } smb_makescred(&scred, td, cred); error = smb_write(smp->sm_share, np->n_fid, uiop, &scred); --- //depot/vendor/freebsd/src/sys/fs/tmpfs/tmpfs_vnops.c 2007/08/16 11:02:30 +++ //depot/user/kris/contention/sys/fs/tmpfs/tmpfs_vnops.c 2007/08/31 21:06:36 @@ -47,6 +47,8 @@ #include #include #include +#include +#include #include #include #include @@ -700,14 +702,18 @@ return (EFBIG); if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (uio->uio_offset + uio->uio_resid > lim_cur(td->td_proc, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(td->td_proc)) { + PROC_RUNLOCK(td->td_proc); + PROC_WLOCK(td->td_proc); + } psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } extended = uio->uio_offset + uio->uio_resid > node->tn_size; --- //depot/vendor/freebsd/src/sys/geom/geom.h 2007/05/05 16:37:01 +++ //depot/user/kris/contention/sys/geom/geom.h 2007/05/12 21:25:58 @@ -288,6 +288,10 @@ off_t offset; off_t length; }; +struct g_delete { + off_t offset; + off_t length; +}; MALLOC_DECLARE(M_GEOM); --- //depot/vendor/freebsd/src/sys/geom/geom_dev.c 2007/05/05 17:07:34 +++ //depot/user/kris/contention/sys/geom/geom_dev.c 2007/05/12 21:25:58 @@ -245,7 +245,7 @@ struct g_geom *gp; struct g_consumer *cp; struct g_kerneldump kd; - off_t offset, length; + struct g_delete *del; int i, error; u_int u; @@ -299,17 +299,14 @@ error = g_io_flush(cp); break; case DIOCGDELETE: - offset = ((off_t *)data)[0]; - length = ((off_t *)data)[1]; - if ((offset % cp->provider->sectorsize) != 0 || - (length % cp->provider->sectorsize) != 0 || - length <= 0 || length > MAXPHYS) { - printf("%s: offset=%jd length=%jd\n", __func__, offset, - length); + del = (struct g_delete *)data; + if ((del->offset % cp->provider->sectorsize) != 0 || + (del->length % cp->provider->sectorsize) != 0 || + del->length <= 0 || del->length > MAXPHYS) { error = EINVAL; break; } - error = g_delete_data(cp, offset, length); + error = g_delete_data(cp, del->offset, del->length); break; case DIOCGIDENT: error = g_io_getattr("GEOM::ident", cp, &i, data); --- //depot/vendor/freebsd/src/sys/gnu/fs/ext2fs/ext2_readwrite.c 2005/06/14 03:01:09 +++ //depot/user/kris/contention/sys/gnu/fs/ext2fs/ext2_readwrite.c 2007/08/31 20:34:30 @@ -210,14 +210,18 @@ */ td = uio->uio_td; if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (uio->uio_offset + uio->uio_resid > lim_cur(td->td_proc, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(td->td_proc)) { + PROC_RUNLOCK(td->td_proc); + PROC_WLOCK(td->td_proc); + } psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } resid = uio->uio_resid; --- //depot/vendor/freebsd/src/sys/gnu/fs/ext2fs/ext2_vnops.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/gnu/fs/ext2fs/ext2_vnops.c 2007/08/31 20:34:30 @@ -63,6 +63,7 @@ #include #include #include +#include #include #include --- //depot/vendor/freebsd/src/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c 2007/02/15 22:11:58 +++ //depot/user/kris/contention/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c 2007/08/31 20:34:30 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -608,14 +609,18 @@ #if 0 td = uio->uio_td; if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (uio->uio_offset + uio->uio_resid > lim_cur(td->td_proc, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(td->td_proc)) { + PROC_RUNLOCK(td->td_proc); + PROC_WLOCK(td->td_proc); + } psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } #endif --- //depot/vendor/freebsd/src/sys/i386/conf/GENERIC 2007/07/01 21:52:48 +++ //depot/user/kris/contention/sys/i386/conf/GENERIC 2007/07/26 15:30:52 @@ -72,6 +72,13 @@ options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed +#options SPINLOCK_PROFILING +options LOCK_PROFILING +#options KTR +#options KTR_ENTRIES=32768 +#options KTR_MASK=(KTR_CONTENTION) +#options KTR_COMPILE=(KTR_CONTENTION) + # To make an SMP kernel, the next two lines are needed options SMP # Symmetric MultiProcessor Kernel device apic # I/O APIC --- //depot/vendor/freebsd/src/sys/i386/i386/machdep.c 2007/08/09 20:17:35 +++ //depot/user/kris/contention/sys/i386/i386/machdep.c 2007/08/31 20:34:30 @@ -80,6 +80,7 @@ #include #include #include +#include #include #include #include @@ -289,7 +290,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -327,7 +328,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Save most if not all of trap frame. */ sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax; @@ -385,7 +386,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -398,7 +399,7 @@ regs->tf_fs = _udatasel; load_gs(_udatasel); regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } #endif /* COMPAT_43 */ @@ -417,7 +418,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -468,7 +469,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * If we're a vm86 process, we want to save the segment registers. @@ -506,7 +507,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -518,7 +519,7 @@ regs->tf_es = _udatasel; regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } #endif /* COMPAT_FREEBSD4 */ @@ -537,7 +538,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -604,7 +605,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * If we're a vm86 process, we want to save the segment registers. @@ -642,7 +643,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -654,7 +655,7 @@ regs->tf_es = _udatasel; regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -780,7 +781,7 @@ regs->tf_eip = scp->sc_pc; regs->tf_eflags = eflags; - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (scp->sc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -790,7 +791,7 @@ SIGSETOLD(td->td_sigmask, scp->sc_mask); SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } #endif /* COMPAT_43 */ @@ -897,7 +898,7 @@ bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -908,7 +909,7 @@ td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } #endif /* COMPAT_FREEBSD4 */ @@ -1018,7 +1019,7 @@ bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -1029,7 +1030,7 @@ td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } @@ -2148,6 +2149,7 @@ */ mutex_init(); mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS | MTX_NOPROFILE); + rwlock_init(); /* make ldt memory segments */ ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1); @@ -2592,9 +2594,7 @@ tp = td->td_frame; - PROC_LOCK(curthread->td_proc); mcp->mc_onstack = sigonstack(tp->tf_esp); - PROC_UNLOCK(curthread->td_proc); mcp->mc_gs = td->td_pcb->pcb_gs; mcp->mc_fs = tp->tf_fs; mcp->mc_es = tp->tf_es; --- //depot/vendor/freebsd/src/sys/i386/i386/mem.c 2006/01/23 15:50:33 +++ //depot/user/kris/contention/sys/i386/i386/mem.c 2007/07/26 22:46:10 @@ -87,10 +87,6 @@ int error = 0; vm_offset_t addr; - /* XXX UPS Why ? */ - GIANT_REQUIRED; - - if (minor(dev) != CDEV_MINOR_MEM && minor(dev) != CDEV_MINOR_KMEM) return EIO; --- //depot/vendor/freebsd/src/sys/i386/i386/trap.c 2007/07/26 15:36:47 +++ //depot/user/kris/contention/sys/i386/i386/trap.c 2007/08/31 21:56:06 @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -512,9 +513,9 @@ if (frame->tf_eip == (int)cpu_switch_load_gs) { PCPU_GET(curpcb)->pcb_gs = 0; #if 0 - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGBUS); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #endif goto out; } @@ -754,18 +755,18 @@ * Keep swapout from messing with us during this * critical time. */ - PROC_LOCK(p); + PROC_WLOCK(p); ++p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Fault in the user page: */ rv = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); - PROC_LOCK(p); + PROC_WLOCK(p); --p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * Don't have to worry about process locking or stacks in the --- //depot/vendor/freebsd/src/sys/i386/i386/tsc.c 2007/06/04 18:28:45 +++ //depot/user/kris/contention/sys/i386/i386/tsc.c 2007/06/05 06:30:35 @@ -52,7 +52,7 @@ static eventhandler_tag tsc_levels_tag, tsc_pre_tag, tsc_post_tag; #ifdef SMP -static int smp_tsc; +static int smp_tsc = 1; SYSCTL_INT(_kern_timecounter, OID_AUTO, smp_tsc, CTLFLAG_RDTUN, &smp_tsc, 0, "Indicates whether the TSC is safe to use in SMP mode"); TUNABLE_INT("kern.timecounter.smp_tsc", &smp_tsc); --- //depot/vendor/freebsd/src/sys/i386/ibcs2/ibcs2_fcntl.c 2005/02/07 22:07:03 +++ //depot/user/kris/contention/sys/i386/ibcs2/ibcs2_fcntl.c 2007/08/31 20:34:30 @@ -197,13 +197,13 @@ } else #endif /* SPX_HACK */ free(path, M_TEMP); - PROC_LOCK(p); + PROC_RLOCK(p); if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { struct file *fp; int error; error = fget(td, td->td_retval[0], &fp); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error) return (EBADF); @@ -213,7 +213,7 @@ td); fdrop(fp, td); } else - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return ret; } --- //depot/vendor/freebsd/src/sys/i386/ibcs2/ibcs2_ioctl.c 2005/01/06 23:25:27 +++ //depot/user/kris/contention/sys/i386/ibcs2/ibcs2_ioctl.c 2007/08/31 20:34:30 @@ -524,9 +524,9 @@ { pid_t pg_id; - PROC_LOCK(p); + PROC_RLOCK(p); pg_id = p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = copyout((caddr_t)&pg_id, uap->data, sizeof(pg_id)); break; @@ -557,7 +557,7 @@ short bitx, bity; } ibcs2_jwinsize; - PROC_LOCK(p); + PROC_RLOCK(p); SESS_LOCK(p->p_session); ibcs2_jwinsize.bytex = 80; /* p->p_session->s_ttyp->t_winsize.ws_col; XXX */ @@ -568,7 +568,7 @@ ibcs2_jwinsize.bity = p->p_session->s_ttyp->t_winsize.ws_ypixel; SESS_UNLOCK(p->p_session); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = copyout((caddr_t)&ibcs2_jwinsize, uap->data, sizeof(ibcs2_jwinsize)); break; --- //depot/vendor/freebsd/src/sys/i386/ibcs2/ibcs2_misc.c 2007/03/26 15:42:26 +++ //depot/user/kris/contention/sys/i386/ibcs2/ibcs2_misc.c 2007/08/31 20:34:30 @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -108,30 +109,30 @@ p = td->td_proc; switch (uap->cmd) { case IBCS2_GETFSIZE: - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = lim_cur(p, RLIMIT_FSIZE); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (td->td_retval[0] == -1) td->td_retval[0] = 0x7fffffff; return 0; case IBCS2_SETFSIZE: - PROC_LOCK(p); + PROC_RLOCK(p); rl.rlim_max = lim_max(p, RLIMIT_FSIZE); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); rl.rlim_cur = uap->newlimit; error = kern_setrlimit(td, RLIMIT_FSIZE, &rl); if (!error) { - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = lim_cur(p, RLIMIT_FSIZE); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } else { DPRINTF(("failed ")); } return error; case IBCS2_GETPSIZE: - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = lim_cur(p, RLIMIT_RSS); /* XXX */ - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case IBCS2_GETDTABLESIZE: uap->cmd = IBCS2_SC_OPEN_MAX; @@ -779,9 +780,9 @@ break; case IBCS2_SC_CHILD_MAX: - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = lim_cur(td->td_proc, RLIMIT_NPROC); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case IBCS2_SC_CLK_TCK: @@ -793,9 +794,9 @@ break; case IBCS2_SC_OPEN_MAX: - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = lim_cur(td->td_proc, RLIMIT_NOFILE); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case IBCS2_SC_JOB_CONTROL: @@ -958,9 +959,9 @@ struct proc *p = td->td_proc; switch (uap->type) { case 0: /* getpgrp */ - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; case 1: /* setpgrp */ @@ -970,9 +971,9 @@ sa.pid = 0; sa.pgid = 0; setpgid(td, &sa); - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; } --- //depot/vendor/freebsd/src/sys/i386/ibcs2/ibcs2_signal.c 2005/02/13 17:38:17 +++ //depot/user/kris/contention/sys/i386/ibcs2/ibcs2_signal.c 2007/08/31 20:34:30 @@ -289,7 +289,7 @@ /* special sigset() check */ if(IBCS2_SIGCALL(uap->sig) == IBCS2_SIGSET_MASK) { - PROC_LOCK(p); + PROC_WLOCK(p); /* check to make sure signal is not blocked */ if(sigismember(&td->td_sigmask, signum)) { /* return SIG_HOLD and unblock signal*/ @@ -297,7 +297,7 @@ SIGDELSET(td->td_sigmask, signum); signotify(td); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } return 0; @@ -328,9 +328,9 @@ { sigset_t mask; - PROC_LOCK(p); + PROC_RLOCK(p); mask = td->td_sigmask; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); SIGDELSET(mask, signum); return kern_sigsuspend(td, mask); } @@ -387,11 +387,11 @@ sigset_t bss; ibcs2_sigset_t iss; - PROC_LOCK(p); + PROC_WLOCK(p); bss = td->td_siglist; SIGSETOR(bss, p->p_siglist); SIGSETAND(bss, td->td_sigmask); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); bsd_to_ibcs2_sigset(&bss, &iss); return copyout(&iss, uap->mask, sizeof(iss)); @@ -420,9 +420,9 @@ { sigset_t mask; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); mask = td->td_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); return kern_sigsuspend(td, mask); } --- //depot/vendor/freebsd/src/sys/i386/linux/imgact_linux.c 2007/02/24 16:52:52 +++ //depot/user/kris/contention/sys/i386/linux/imgact_linux.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -106,13 +107,13 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(imgp->proc); + PROC_RLOCK(imgp->proc); if (a_out->a_text > maxtsiz || a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA)) { - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); return (ENOMEM); } - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); VOP_UNLOCK(imgp->vp, 0, td); --- //depot/vendor/freebsd/src/sys/i386/linux/linux_machdep.c 2007/07/20 08:36:59 +++ //depot/user/kris/contention/sys/i386/linux/linux_machdep.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -359,9 +360,9 @@ if (error) return (error); - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_flag |= P_PPWAIT; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); @@ -374,10 +375,10 @@ thread_unlock(td2); /* wait for the children to exit, ie. emulate vfork */ - PROC_LOCK(p2); + PROC_RLOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); - PROC_UNLOCK(p2); + rw_sleep(td->td_proc, &p2->p_rwlock, PWAIT, "ppwait", 0); + PROC_RUNLOCK(p2); return (0); } @@ -446,9 +447,9 @@ if (args->flags & (LINUX_CLONE_PARENT | LINUX_CLONE_THREAD)) { sx_xlock(&proctree_lock); - PROC_LOCK(p2); + PROC_WLOCK(p2); proc_reparent(p2, td->td_proc->p_pptr); - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); sx_xunlock(&proctree_lock); } @@ -464,9 +465,9 @@ * I think it might be this but I am not sure. */ #ifdef notyet - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_pgrp = td->td_proc->p_pgrp; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); #endif exit_signal = 0; } @@ -489,9 +490,9 @@ printf(LMSG("copyout failed!")); } - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_sigparent = exit_signal; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); td2 = FIRST_THREAD_IN_PROC(p2); /* * in a case of stack = NULL we are supposed to COW calling process stack @@ -561,9 +562,9 @@ (long)p2->p_pid, args->stack, exit_signal); #endif if (args->flags & LINUX_CLONE_VFORK) { - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_flag |= P_PPWAIT; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); } /* @@ -579,10 +580,10 @@ if (args->flags & LINUX_CLONE_VFORK) { /* wait for the children to exit, ie. emulate vfork */ - PROC_LOCK(p2); + PROC_RLOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(td->td_proc, &p2->p_mtx, PWAIT, "ppwait", 0); - PROC_UNLOCK(p2); + rw_sleep(td->td_proc, &p2->p_rwlock, PWAIT, "ppwait", 0); + PROC_RUNLOCK(p2); } return (0); @@ -752,10 +753,10 @@ * mmap'ed region, but some apps do not check * mmap's return value. */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_vmspace->vm_maxsaddr = (char *)USRSTACK - lim_cur(p, RLIMIT_STACK); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } /* This gives us our maximum stack size */ @@ -1018,9 +1019,9 @@ printf(ARGS(pause, "")); #endif - PROC_LOCK(p); + PROC_RLOCK(p); sigmask = td->td_sigmask; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (kern_sigsuspend(td, sigmask)); } --- //depot/vendor/freebsd/src/sys/i386/linux/linux_ptrace.c 2006/02/22 19:00:49 +++ //depot/user/kris/contention/sys/i386/linux/linux_ptrace.c 2007/08/31 20:34:30 @@ -36,6 +36,7 @@ #include #include #include +#include #include #include @@ -221,7 +222,7 @@ linux_proc_read_fpxregs(struct thread *td, struct linux_pt_fpxreg *fpxregs) { - PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + PROC_LOCK_ASSERT(td->td_proc, RA_LOCKED); if (cpu_fxsr == 0 || (td->td_proc->p_sflag & PS_INMEM) == 0) return (EIO); bcopy(&td->td_pcb->pcb_save.sv_xmm, fpxregs, sizeof(*fpxregs)); @@ -232,7 +233,7 @@ linux_proc_write_fpxregs(struct thread *td, struct linux_pt_fpxreg *fpxregs) { - PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + PROC_LOCK_ASSERT(td->td_proc, RA_LOCKED); if (cpu_fxsr == 0 || (td->td_proc->p_sflag & PS_INMEM) == 0) return (EIO); bcopy(fpxregs, &td->td_pcb->pcb_save.sv_xmm, sizeof(*fpxregs)); @@ -394,7 +395,7 @@ td2 = FIRST_THREAD_IN_PROC(p); error = linux_proc_read_fpxregs(td2, &r.fpxreg); _PRELE(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (error == 0) error = copyout(&r.fpxreg, (void *)uap->data, sizeof(r.fpxreg)); @@ -405,12 +406,12 @@ td2 = FIRST_THREAD_IN_PROC(p); error = linux_proc_write_fpxregs(td2, &r.fpxreg); _PRELE(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } break; fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #else error = EIO; #endif --- //depot/vendor/freebsd/src/sys/i386/linux/linux_sysvec.c 2007/04/02 18:42:04 +++ //depot/user/kris/contention/sys/i386/linux/linux_sysvec.c 2007/08/31 20:34:30 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -286,7 +287,7 @@ sig = ksi->ksi_signo; code = ksi->ksi_code; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); regs = td->td_frame; @@ -337,7 +338,7 @@ frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size; frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask); @@ -378,7 +379,7 @@ printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"), fp, oonstack); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -394,7 +395,7 @@ regs->tf_es = _udatasel; regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -421,7 +422,7 @@ int sig, code; int oonstack, i; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); psp = p->p_sigacts; sig = ksi->ksi_signo; code = ksi->ksi_code; @@ -450,7 +451,7 @@ } else fp = (struct l_sigframe *)regs->tf_esp - 1; mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Build the argument list for the signal handler. @@ -497,7 +498,7 @@ * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -512,7 +513,7 @@ regs->tf_es = _udatasel; regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -587,11 +588,11 @@ lmask.__bits[0] = frame.sf_sc.sc_mask; for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) lmask.__bits[i+1] = frame.sf_extramask[i]; - PROC_LOCK(p); + PROC_WLOCK(p); linux_to_bsd_sigset(&lmask, &td->td_sigmask); SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Restore signal context. @@ -688,11 +689,11 @@ return(EINVAL); } - PROC_LOCK(p); + PROC_WLOCK(p); linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask); SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Restore signal context --- //depot/vendor/freebsd/src/sys/i386/svr4/svr4_machdep.c 2005/10/19 15:01:11 +++ //depot/user/kris/contention/sys/i386/svr4/svr4_machdep.c 2007/08/31 20:34:30 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -106,7 +107,7 @@ struct sigaltstack *sf; #endif - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(DONE_MORE_SIGALTSTACK_WORK) psp = p->p_sigacts; sf = &p->p_sigstk; @@ -164,7 +165,7 @@ s->ss_size = 16384; s->ss_flags = 0; #endif - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Set the signal mask @@ -202,7 +203,7 @@ struct sigaltstack *sf; sigset_t mask; - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(DONE_MORE_SIGALTSTACK_WORK) psp = p->p_sigacts; #endif @@ -218,7 +219,7 @@ */ if ((uc->uc_flags & SVR4_UC_CPU) == 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return 0; } @@ -248,7 +249,7 @@ */ if (((r[SVR4_X86_EFL] ^ tf->tf_eflags) & PSL_USERSTATIC) != 0 || !USERMODE(r[SVR4_X86_CS], r[SVR4_X86_EFL])) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } @@ -301,7 +302,7 @@ td->td_sigmask = mask; signotify(td); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return 0; /*EJUSTRETURN;*/ } @@ -425,7 +426,7 @@ int sig; int code; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; #if defined(DEBUG_SVR4) printf("svr4_sendsig(%d)\n", sig); @@ -449,7 +450,7 @@ fp = (struct svr4_sigframe *)tf->tf_esp - 1; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Build the argument list for the signal handler. @@ -483,7 +484,7 @@ * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); /* NOTREACHED */ } @@ -510,7 +511,7 @@ tf->tf_fs = _udatasel; load_gs(_udatasel); tf->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); #endif } --- //depot/vendor/freebsd/src/sys/ia64/ia64/machdep.c 2007/08/04 19:36:57 +++ //depot/user/kris/contention/sys/ia64/ia64/machdep.c 2007/08/31 20:34:30 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -798,6 +799,7 @@ thread0.td_kstack_pages = KSTACK_PAGES; mutex_init(); + rwlock_init(); /* * Initialize the rest of proc 0's PCB. @@ -925,7 +927,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; code = ksi->ksi_code; psp = p->p_sigacts; @@ -974,7 +976,7 @@ } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); get_mcontext(td, &sf.sf_uc.uc_mcontext, 0); @@ -984,7 +986,7 @@ * Process has trashed its stack; give it an illegal * instruction to halt it in its tracks. */ - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); return; } @@ -1015,7 +1017,7 @@ tf->tf_scratch.gr9 = code; tf->tf_scratch.gr10 = (u_int64_t)catcher; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -1054,7 +1056,7 @@ set_mcontext(td, &uc.uc_mcontext); - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (sigonstack(tf->tf_special.sp)) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -1064,7 +1066,7 @@ td->td_sigmask = uc.uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } --- //depot/vendor/freebsd/src/sys/ia64/ia64/trap.c 2007/06/04 21:44:15 +++ //depot/user/kris/contention/sys/ia64/ia64/trap.c 2007/08/31 20:34:30 @@ -569,17 +569,17 @@ * Keep swapout from messing with us during this * critical time. */ - PROC_LOCK(p); + PROC_WLOCK(p); ++p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Fault in the user page: */ rv = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); - PROC_LOCK(p); + PROC_WLOCK(p); --p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * Don't have to worry about process locking or --- //depot/vendor/freebsd/src/sys/kern/imgact_aout.c 2006/03/16 08:58:11 +++ //depot/user/kris/contention/sys/kern/imgact_aout.c 2007/08/31 20:34:30 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -174,16 +175,16 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(imgp->proc); + PROC_RLOCK(imgp->proc); if (/* text can't exceed maximum text size */ a_out->a_text > maxtsiz || /* data + bss can't exceed rlimit */ a_out->a_data + bss_size > lim_cur(imgp->proc, RLIMIT_DATA)) { - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); return (ENOMEM); } - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); /* * Avoid a possible deadlock if the current address space is destroyed --- //depot/vendor/freebsd/src/sys/kern/imgact_elf.c 2007/05/14 22:42:46 +++ //depot/user/kris/contention/sys/kern/imgact_elf.c 2007/08/31 20:34:30 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -760,11 +761,11 @@ * limits after loading the segments since we do * not actually fault in all the segments pages. */ - PROC_LOCK(imgp->proc); + PROC_RLOCK(imgp->proc); if (data_size > lim_cur(imgp->proc, RLIMIT_DATA) || text_size > maxtsiz || total_size > lim_cur(imgp->proc, RLIMIT_VMEM)) { - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); return (ENOMEM); } @@ -781,7 +782,7 @@ */ addr = round_page((vm_offset_t)imgp->proc->p_vmspace->vm_daddr + lim_max(imgp->proc, RLIMIT_DATA)); - PROC_UNLOCK(imgp->proc); + PROC_RUNLOCK(imgp->proc); imgp->entry_addr = entry; --- //depot/vendor/freebsd/src/sys/kern/imgact_gzip.c 2005/12/24 05:00:40 +++ //depot/user/kris/contention/sys/kern/imgact_gzip.c 2007/08/31 20:34:30 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -211,18 +212,18 @@ /* * text/data/bss must not exceed limits */ - PROC_LOCK(gz->ip->proc); + PROC_RLOCK(gz->ip->proc); if ( /* text can't exceed maximum text size */ gz->a_out.a_text > maxtsiz || /* data + bss can't exceed rlimit */ gz->a_out.a_data + gz->bss_size > lim_cur(gz->ip->proc, RLIMIT_DATA)) { - PROC_UNLOCK(gz->ip->proc); + PROC_RUNLOCK(gz->ip->proc); gz->where = __LINE__; return (ENOMEM); } - PROC_UNLOCK(gz->ip->proc); + PROC_RUNLOCK(gz->ip->proc); /* Find out how far we should go */ gz->file_end = gz->file_offset + gz->a_out.a_text + gz->a_out.a_data; --- //depot/vendor/freebsd/src/sys/kern/init_main.c 2007/06/10 00:32:46 +++ //depot/user/kris/contention/sys/kern/init_main.c 2007/08/31 20:34:30 @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -418,7 +419,7 @@ p->p_flag = P_SYSTEM; p->p_sflag = PS_INMEM; p->p_state = PRS_NORMAL; - knlist_init(&p->p_klist, &p->p_mtx, NULL, NULL, NULL); + knlist_init(&p->p_klist, &p->p_rwlock, NULL, NULL, NULL); STAILQ_INIT(&p->p_ktr); p->p_nice = NZERO; td->td_state = TDS_RUNNING; @@ -435,7 +436,7 @@ bcopy("swapper", p->p_comm, sizeof ("swapper")); callout_init(&p->p_itcallout, CALLOUT_MPSAFE); - callout_init_mtx(&p->p_limco, &p->p_mtx, 0); + callout_init_lock(&p->p_limco, &p->p_rwlock, 0); callout_init(&td->td_slpcallout, CALLOUT_MPSAFE); /* Create credentials. */ @@ -709,7 +710,7 @@ KASSERT(initproc->p_pid == 1, ("create_init: initproc->p_pid != 1")); /* divorce init's credentials from the kernel's */ newcred = crget(); - PROC_LOCK(initproc); + PROC_WLOCK(initproc); initproc->p_flag |= P_SYSTEM; oldcred = initproc->p_ucred; crcopy(newcred, oldcred); @@ -720,7 +721,7 @@ audit_cred_proc1(newcred); #endif initproc->p_ucred = newcred; - PROC_UNLOCK(initproc); + PROC_WUNLOCK(initproc); crfree(oldcred); cred_update_thread(FIRST_THREAD_IN_PROC(initproc)); PROC_SLOCK(initproc); --- //depot/vendor/freebsd/src/sys/kern/kern_acct.c 2007/08/31 13:57:47 +++ //depot/user/kris/contention/sys/kern/kern_acct.c 2007/09/14 21:34:44 @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -366,7 +367,7 @@ * Get process accounting information. */ - PROC_LOCK(p); + PROC_WLOCK(p); /* (1) The name of the command that ran */ bcopy(p->p_comm, acct.ac_comm, sizeof acct.ac_comm); @@ -411,7 +412,7 @@ /* (8) The boolean flags that tell how the process terminated, etc. */ acct.ac_flagx = p->p_acflag; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Setup ancillary structure fields. */ acct.ac_flagx |= ANVER; @@ -423,12 +424,12 @@ * Eliminate any file size rlimit. */ newlim = lim_alloc(); - PROC_LOCK(p); + PROC_WLOCK(p); oldlim = p->p_limit; lim_copy(newlim, oldlim); newlim->pl_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; p->p_limit = newlim; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); lim_free(oldlim); /* --- //depot/vendor/freebsd/src/sys/kern/kern_clock.c 2007/06/09 19:49:41 +++ //depot/user/kris/contention/sys/kern/kern_clock.c 2007/08/31 20:34:30 @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -357,7 +358,7 @@ register struct proc *p; { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if (p->p_flag & P_STOPPROF) return; if ((p->p_flag & P_PROFIL) == 0) { @@ -377,13 +378,13 @@ register struct proc *p; { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if (p->p_flag & P_PROFIL) { if (p->p_profthreads != 0) { p->p_flag |= P_STOPPROF; while (p->p_profthreads != 0) - msleep(&p->p_profthreads, &p->p_mtx, PPAUSE, - "stopprof", 0); + rw_sleep(&p->p_profthreads, &p->p_rwlock, + PPAUSE, "stopprof", 0); p->p_flag &= ~P_STOPPROF; } if ((p->p_flag & P_PROFIL) == 0) --- //depot/vendor/freebsd/src/sys/kern/kern_context.c 2007/03/05 13:12:17 +++ //depot/user/kris/contention/sys/kern/kern_context.c 2007/08/31 20:34:30 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -68,9 +69,9 @@ ret = EINVAL; else { get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); ret = copyout(&uc, uap->ucp, UC_COPY_SIZE); } return (ret); @@ -90,9 +91,9 @@ ret = set_mcontext(td, &uc.uc_mcontext); if (ret == 0) { SIG_CANTMASK(uc.uc_sigmask); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); td->td_sigmask = uc.uc_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } } @@ -109,9 +110,9 @@ ret = EINVAL; else { get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); ret = copyout(&uc, uap->oucp, UC_COPY_SIZE); if (ret == 0) { ret = copyin(uap->ucp, &uc, UC_COPY_SIZE); @@ -119,9 +120,9 @@ ret = set_mcontext(td, &uc.uc_mcontext); if (ret == 0) { SIG_CANTMASK(uc.uc_sigmask); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); td->td_sigmask = uc.uc_sigmask; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } } --- //depot/vendor/freebsd/src/sys/kern/kern_descrip.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/kern/kern_descrip.c 2007/08/31 20:34:30 @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -92,7 +93,6 @@ static int fd_first_free(struct filedesc *, int, int); static int fd_last_used(struct filedesc *, int, int); static void fdgrowtable(struct filedesc *, int); -static int fdrop_locked(struct file *fp, struct thread *td); static void fdunused(struct filedesc *fdp, int fd); static void fdused(struct filedesc *fdp, int fd); @@ -134,9 +134,7 @@ /* * Descriptor management. */ -struct filelist filehead; /* head of list of open files */ -int openfiles; /* actual number of open files */ -struct sx filelist_lock; /* sx to protect filelist */ +volatile int openfiles; /* actual number of open files */ struct mtx sigio_lock; /* mtx to protect pointers to sigio */ void (*mq_fdclose)(struct thread *td, int fd, struct file *fp); @@ -257,10 +255,10 @@ { struct proc *p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } @@ -382,14 +380,14 @@ } FILEDESC_SUNLOCK(fdp); newmin = arg; - PROC_LOCK(p); + PROC_RLOCK(p); if (newmin >= lim_cur(p, RLIMIT_NOFILE) || newmin >= maxfilesperproc) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = EINVAL; break; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = do_dup(td, DUP_VARIABLE, fd, newmin, td->td_retval); break; @@ -425,9 +423,7 @@ error = EBADF; break; } - FILE_LOCK(fp); td->td_retval[0] = OFLAGS(fp->f_flag); - FILE_UNLOCK(fp); FILEDESC_SUNLOCK(fdp); break; @@ -438,12 +434,13 @@ error = EBADF; break; } - FILE_LOCK(fp); - fhold_locked(fp); - fp->f_flag &= ~FCNTLFLAGS; - fp->f_flag |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS; - FILE_UNLOCK(fp); + fhold(fp); FILEDESC_SUNLOCK(fdp); + do { + tmp = flg = fp->f_flag; + tmp &= ~FCNTLFLAGS; + tmp |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS; + } while(atomic_cmpset_int(&fp->f_flag, flg, tmp) == 0); tmp = fp->f_flag & FNONBLOCK; error = fo_ioctl(fp, FIONBIO, &tmp, td->td_ucred, td); if (error) { @@ -456,9 +453,7 @@ fdrop(fp, td); break; } - FILE_LOCK(fp); - fp->f_flag &= ~FNONBLOCK; - FILE_UNLOCK(fp); + atomic_clear_int(&fp->f_flag, FNONBLOCK); tmp = 0; (void)fo_ioctl(fp, FIONBIO, &tmp, td->td_ucred, td); fdrop(fp, td); @@ -534,9 +529,9 @@ error = EBADF; break; } - PROC_LOCK(p->p_leader); + PROC_WLOCK(p->p_leader); p->p_leader->p_flag |= P_ADVLOCK; - PROC_UNLOCK(p->p_leader); + PROC_WUNLOCK(p->p_leader); error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, flp, flg); break; @@ -545,9 +540,9 @@ error = EBADF; break; } - PROC_LOCK(p->p_leader); + PROC_WLOCK(p->p_leader); p->p_leader->p_flag |= P_ADVLOCK; - PROC_UNLOCK(p->p_leader); + PROC_WUNLOCK(p->p_leader); error = VOP_ADVLOCK(vp, (caddr_t)p->p_leader, F_SETLK, flp, flg); break; @@ -656,9 +651,9 @@ */ if (old < 0 || new < 0) return (EBADF); - PROC_LOCK(p); + PROC_RLOCK(p); maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (new >= maxfd) return (EMFILE); @@ -794,10 +789,10 @@ PGRP_UNLOCK(pg); } else { struct proc *p = (sigio)->sio_proc; - PROC_LOCK(p); + PROC_WLOCK(p); SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio, sigio, sio_pgsigio); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } SIGIO_UNLOCK(); crfree(sigio->sio_ucred); @@ -832,7 +827,7 @@ PGRP_LOCK_ASSERT(pg, MA_NOTOWNED); } else /* if (sigio->sio_pgid > 0) */ { p = sigio->sio_proc; - PROC_LOCK_ASSERT(p, MA_NOTOWNED); + PROC_LOCK_ASSERT(p, RA_UNLOCKED); } SIGIO_LOCK(); @@ -852,10 +847,10 @@ ("Pgrp sigio in proc sigio list")); KASSERT(sigio->sio_proc == p, ("Bogus proc in sigio list")); - PROC_LOCK(p); + PROC_WLOCK(p); SLIST_REMOVE(&p->p_sigiolst, sigio, sigio, sio_pgsigio); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } SIGIO_UNLOCK(); crfree(sigio->sio_ucred); @@ -894,7 +889,7 @@ sx_slock(&proctree_lock); if (pgid > 0) { - proc = pfind(pgid); + proc = pfindr(pgid); if (proc == NULL) { ret = ESRCH; goto fail; @@ -908,7 +903,7 @@ * restrict FSETOWN to the current process or process * group for maximum safety. */ - PROC_UNLOCK(proc); + PROC_RUNLOCK(proc); if (proc->p_session != curthread->td_proc->p_session) { ret = EPERM; goto fail; @@ -940,20 +935,20 @@ } funsetown(sigiop); if (pgid > 0) { - PROC_LOCK(proc); + PROC_WLOCK(proc); /* * Since funsetownlst() is called without the proctree * locked, we need to check for P_WEXIT. * XXX: is ESRCH correct? */ if ((proc->p_flag & P_WEXIT) != 0) { - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); ret = ESRCH; goto fail; } SLIST_INSERT_HEAD(&proc->p_sigiolst, sigio, sio_pgsigio); sigio->sio_proc = proc; - PROC_UNLOCK(proc); + PROC_WUNLOCK(proc); } else { PGRP_LOCK(pgrp); SLIST_INSERT_HEAD(&pgrp->pg_sigiolst, sigio, sio_pgsigio); @@ -1284,9 +1279,9 @@ if (fdp->fd_freefile > minfd) minfd = fdp->fd_freefile; - PROC_LOCK(p); + PROC_RLOCK(p); maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * Search the bitmap for a free descriptor. If none is found, try @@ -1331,9 +1326,9 @@ FILEDESC_LOCK_ASSERT(fdp); - PROC_LOCK(p); + PROC_RLOCK(p); lim = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if ((i = lim - fdp->fd_nfiles) > 0 && (n -= i) <= 0) return (1); last = min(fdp->fd_nfiles, lim); @@ -1356,15 +1351,13 @@ falloc(struct thread *td, struct file **resultfp, int *resultfd) { struct proc *p = td->td_proc; - struct file *fp, *fq; + struct file *fp; int error, i; int maxuserfiles = maxfiles - (maxfiles / 20); static struct timeval lastfail; static int curfail; fp = uma_zalloc(file_zone, M_WAITOK | M_ZERO); - sx_xlock(&filelist_lock); - if ((openfiles >= maxuserfiles && priv_check(td, PRIV_MAXFILES) != 0) || openfiles >= maxfiles) { @@ -1372,18 +1365,16 @@ printf("kern.maxfiles limit exceeded by uid %i, please see tuning(7).\n", td->td_ucred->cr_ruid); } - sx_xunlock(&filelist_lock); uma_zfree(file_zone, fp); return (ENFILE); } - openfiles++; + atomic_add_int(&openfiles, 1); /* * If the process has file descriptor zero open, add the new file * descriptor to the list of open files at that point, otherwise * put it at the front of the list of open files. */ - fp->f_mtxp = mtx_pool_alloc(mtxpool_sleep); fp->f_count = 1; if (resultfp) fp->f_count++; @@ -1392,12 +1383,6 @@ fp->f_data = NULL; fp->f_vnode = NULL; FILEDESC_XLOCK(p->p_fd); - if ((fq = p->p_fd->fd_ofiles[0])) { - LIST_INSERT_AFTER(fq, fp, f_list); - } else { - LIST_INSERT_HEAD(&filehead, fp, f_list); - } - sx_xunlock(&filelist_lock); if ((error = fdalloc(td, 0, &i))) { FILEDESC_XUNLOCK(p->p_fd); fdrop(fp, td); @@ -1959,6 +1944,23 @@ } /* + * Initialize the file pointer with the specified properties. + * + * The ops are set with release semantics to be certain that the flags, type, and + * data are visible when ops is. This is to prevent ops methods from being + * called with bad data. + */ +void +finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops) +{ + fp->f_flag = flag; + fp->f_type = type; + fp->f_data = data; + atomic_store_rel_ptr((volatile uintptr_t *)&fp->f_ops, (uintptr_t)ops); +} + + +/* * Extract the file pointer associated with the specified descriptor for the * current user process. * @@ -2132,54 +2134,20 @@ sorele(so); } -int -fdrop(struct file *fp, struct thread *td) -{ - - FILE_LOCK(fp); - return (fdrop_locked(fp, td)); -} - /* - * Drop reference on struct file passed in, may call closef if the - * reference hits zero. - * Expects struct file locked, and will unlock it. + * Handle the last reference to a file being closed. */ -static int -fdrop_locked(struct file *fp, struct thread *td) +int +_fdrop(struct file *fp, struct thread *td) { int error; - FILE_LOCK_ASSERT(fp, MA_OWNED); - - if (--fp->f_count > 0) { - FILE_UNLOCK(fp); - return (0); - } - - /* - * We might have just dropped the last reference to a file - * object that is for a UNIX domain socket whose message - * buffers are being examined in unp_gc(). If that is the - * case, FWAIT will be set in f_gcflag and we need to wait for - * unp_gc() to finish its scan. - */ - while (fp->f_gcflag & FWAIT) - msleep(&fp->f_gcflag, fp->f_mtxp, 0, "fpdrop", 0); - - /* We have the last ref so we can proceed without the file lock. */ - FILE_UNLOCK(fp); - if (fp->f_count < 0) - panic("fdrop: count < 0"); + error = 0; + if (fp->f_count != 0) + panic("fdrop: count %d", fp->f_count); if (fp->f_ops != &badfileops) error = fo_close(fp, td); - else - error = 0; - - sx_xlock(&filelist_lock); - LIST_REMOVE(fp, f_list); - openfiles--; - sx_xunlock(&filelist_lock); + atomic_subtract_int(&openfiles, 1); crfree(fp->f_cred); uma_zfree(file_zone, fp); @@ -2222,9 +2190,7 @@ lf.l_len = 0; if (uap->how & LOCK_UN) { lf.l_type = F_UNLCK; - FILE_LOCK(fp); - fp->f_flag &= ~FHASLOCK; - FILE_UNLOCK(fp); + atomic_clear_int(&fp->f_flag, FHASLOCK); error = VOP_ADVLOCK(vp, (caddr_t)fp, F_UNLCK, &lf, F_FLOCK); goto done2; } @@ -2236,9 +2202,7 @@ error = EBADF; goto done2; } - FILE_LOCK(fp); - fp->f_flag |= FHASLOCK; - FILE_UNLOCK(fp); + atomic_set_int(&fp->f_flag, FHASLOCK); error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, (uap->how & LOCK_NB) ? F_FLOCK : F_FLOCK | F_WAIT); done2: @@ -2283,9 +2247,7 @@ * Check that the mode the file is being opened for is a * subset of the mode of the existing descriptor. */ - FILE_LOCK(wfp); if (((mode & (FREAD|FWRITE)) | wfp->f_flag) != wfp->f_flag) { - FILE_UNLOCK(wfp); FILEDESC_XUNLOCK(fdp); return (EACCES); } @@ -2294,8 +2256,7 @@ fdp->fd_ofileflags[indx] = fdp->fd_ofileflags[dfd]; if (fp == NULL) fdused(fdp, indx); - fhold_locked(wfp); - FILE_UNLOCK(wfp); + fhold(wfp); FILEDESC_XUNLOCK(fdp); if (fp != NULL) /* @@ -2416,29 +2377,23 @@ struct proc *p; int error, n; - /* - * Note: because the number of file descriptors is calculated - * in different ways for sizing vs returning the data, - * there is information leakage from the first loop. However, - * it is of a similar order of magnitude to the leakage from - * global system statistics such as kern.openfiles. - */ error = sysctl_wire_old_buffer(req, 0); if (error != 0) return (error); if (req->oldptr == NULL) { - n = 16; /* A slight overestimate. */ - sx_slock(&filelist_lock); - LIST_FOREACH(fp, &filehead, f_list) { - /* - * We should grab the lock, but this is an - * estimate, so does it really matter? - */ - /* mtx_lock(fp->f_mtxp); */ - n += fp->f_count; - /* mtx_unlock(f->f_mtxp); */ + n = 0; + sx_slock(&allproc_lock); + FOREACH_PROC_IN_SYSTEM(p) { + if (p->p_state == PRS_NEW) + continue; + fdp = fdhold(p); + if (fdp == NULL) + continue; + /* overestimates sparse tables. */ + n += fdp->fd_lastfile; + fddrop(fdp); } - sx_sunlock(&filelist_lock); + sx_sunlock(&allproc_lock); return (SYSCTL_OUT(req, 0, n * sizeof(xf))); } error = 0; @@ -2448,14 +2403,14 @@ FOREACH_PROC_IN_SYSTEM(p) { if (p->p_state == PRS_NEW) continue; - PROC_LOCK(p); + PROC_RLOCK(p); if (p_cansee(req->td, p) != 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } + xf.xf_uid = p->p_ucred->cr_uid; + PROC_RUNLOCK(p); xf.xf_pid = p->p_pid; - xf.xf_uid = p->p_ucred->cr_uid; - PROC_UNLOCK(p); fdp = fdhold(p); if (fdp == NULL) continue; @@ -2469,7 +2424,7 @@ xf.xf_vnode = fp->f_vnode; xf.xf_type = fp->f_type; xf.xf_count = fp->f_count; - xf.xf_msgcount = fp->f_msgcount; + xf.xf_msgcount = 0; xf.xf_offset = fp->f_offset; xf.xf_flag = fp->f_flag; error = SYSCTL_OUT(req, &xf, sizeof(xf)); @@ -2557,7 +2512,7 @@ p = file_to_first_proc(fp); db_printf("%8p %4s %8p %08x %04x %5d %6d %8p %5d %12s\n", fp, file_type_to_name(fp->f_type), fp->f_data, fp->f_flag, - fp->f_gcflag, fp->f_count, fp->f_msgcount, fp->f_vnode, + 0, fp->f_count, 0, fp->f_vnode, p != NULL ? p->p_pid : -1, p != NULL ? p->p_comm : "-"); } @@ -2573,6 +2528,7 @@ db_print_file(fp, 1); } +#if 0 DB_SHOW_COMMAND(files, db_show_files) { struct file *fp; @@ -2585,6 +2541,7 @@ } } #endif +#endif SYSCTL_INT(_kern, KERN_MAXFILESPERPROC, maxfilesperproc, CTLFLAG_RW, &maxfilesperproc, 0, "Maximum files allowed open per process"); @@ -2593,7 +2550,7 @@ &maxfiles, 0, "Maximum number of files"); SYSCTL_INT(_kern, OID_AUTO, openfiles, CTLFLAG_RD, - &openfiles, 0, "System-wide number of open files"); + __DEVOLATILE(int *, &openfiles), 0, "System-wide number of open files"); /* ARGSUSED*/ static void @@ -2602,7 +2559,6 @@ file_zone = uma_zcreate("Files", sizeof(struct file), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); - sx_init(&filelist_lock, "filelist lock"); mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF); mtx_init(&fdesc_mtx, "fdesc", NULL, MTX_DEF); } --- //depot/vendor/freebsd/src/sys/kern/kern_event.c 2007/07/14 21:26:58 +++ //depot/user/kris/contention/sys/kern/kern_event.c 2007/08/31 20:34:30 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -119,6 +120,7 @@ .fo_kqfilter = kqueue_kqfilter, .fo_stat = kqueue_stat, .fo_close = kqueue_close, + .fo_flags = DFLAG_MPSAFE }; static int knote_attach(struct knote *kn, struct kqueue *kq); @@ -347,7 +349,7 @@ if (immediate && filt_proc(kn, NOTE_EXIT)) KNOTE_ACTIVATE(kn, 0); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -531,12 +533,7 @@ SLIST_INSERT_HEAD(&fdp->fd_kqlist, kq, kq_list); FILEDESC_XUNLOCK(fdp); - FILE_LOCK(fp); - fp->f_flag = FREAD | FWRITE; - fp->f_type = DTYPE_KQUEUE; - fp->f_data = kq; - fp->f_ops = &kqueueops; - FILE_UNLOCK(fp); + finit(fp, FREAD | FWRITE, DTYPE_KQUEUE, kq, &kqueueops); fdrop(fp, td); td->td_retval[0] = fd; @@ -990,24 +987,17 @@ error = 0; - FILE_LOCK(fp); - do { - kq = fp->f_data; - if (fp->f_type != DTYPE_KQUEUE || kq == NULL) { - error = EBADF; - break; - } - *kqp = kq; - KQ_LOCK(kq); - if ((kq->kq_state & KQ_CLOSING) == KQ_CLOSING) { - KQ_UNLOCK(kq); - error = EBADF; - break; - } - kq->kq_refcnt++; + kq = fp->f_data; + if (fp->f_type != DTYPE_KQUEUE || kq == NULL) + return (EBADF); + *kqp = kq; + KQ_LOCK(kq); + if ((kq->kq_state & KQ_CLOSING) == KQ_CLOSING) { KQ_UNLOCK(kq); - } while (0); - FILE_UNLOCK(fp); + return (EBADF); + } + kq->kq_refcnt++; + KQ_UNLOCK(kq); return error; } @@ -1400,7 +1390,8 @@ revents |= events & (POLLIN | POLLRDNORM); } else { selrecord(td, &kq->kq_sel); - kq->kq_state |= KQ_SEL; + if (SEL_WAITING(&kq->kq_sel)) + kq->kq_state |= KQ_SEL; } } kqueue_release(kq, 1); @@ -1486,8 +1477,9 @@ } if ((kq->kq_state & KQ_SEL) == KQ_SEL) { - kq->kq_state &= ~KQ_SEL; selwakeuppri(&kq->kq_sel, PSOCK); + if (!SEL_WAITING(&kq->kq_sel)) + kq->kq_state &= ~KQ_SEL; } KQ_UNLOCK(kq); @@ -1522,8 +1514,9 @@ wakeup(kq); } if ((kq->kq_state & KQ_SEL) == KQ_SEL) { - kq->kq_state &= ~KQ_SEL; selwakeuppri(&kq->kq_sel, PSOCK); + if (!SEL_WAITING(&kq->kq_sel)) + kq->kq_state &= ~KQ_SEL; } if (!knlist_empty(&kq->kq_sel.si_note)) kqueue_schedtask(kq); @@ -1651,29 +1644,38 @@ return SLIST_EMPTY(&knl->kl_list); } -static struct mtx knlist_lock; -MTX_SYSINIT(knlist_lock, &knlist_lock, "knlist lock for lockless objects", +static struct mtx knlist_mtx; +MTX_SYSINIT(knlist_mtx, &knlist_mtx, "knlist lock for lockless objects", MTX_DEF); -static void knlist_mtx_lock(void *arg); -static void knlist_mtx_unlock(void *arg); -static int knlist_mtx_locked(void *arg); +static void knlist_lock(void *arg); +static void knlist_unlock(void *arg); +static int knlist_locked(void *arg); static void -knlist_mtx_lock(void *arg) +knlist_lock(void *arg) { - mtx_lock((struct mtx *)arg); + struct lock_class *class; + + class = LOCK_CLASS((struct lock_object *)arg); + class->lc_lock((struct lock_object *)arg, 1); } static void -knlist_mtx_unlock(void *arg) +knlist_unlock(void *arg) { - mtx_unlock((struct mtx *)arg); + struct lock_class *class; + + class = LOCK_CLASS((struct lock_object *)arg); + class->lc_unlock((struct lock_object *)arg); } static int -knlist_mtx_locked(void *arg) +knlist_locked(void *arg) { - return (mtx_owned((struct mtx *)arg)); + struct lock_class *class; + + class = LOCK_CLASS((struct lock_object *)arg); + return (class->lc_locked((struct lock_object *)arg)); } void @@ -1682,20 +1684,20 @@ { if (lock == NULL) - knl->kl_lockarg = &knlist_lock; + knl->kl_lockarg = &knlist_mtx; else knl->kl_lockarg = lock; if (kl_lock == NULL) - knl->kl_lock = knlist_mtx_lock; + knl->kl_lock = knlist_lock; else knl->kl_lock = kl_lock; if (kl_unlock == NULL) - knl->kl_unlock = knlist_mtx_unlock; + knl->kl_unlock = knlist_unlock; else knl->kl_unlock = kl_unlock; if (kl_locked == NULL) - knl->kl_locked = knlist_mtx_locked; + knl->kl_locked = knlist_locked; else knl->kl_locked = kl_locked; --- //depot/vendor/freebsd/src/sys/kern/kern_exec.c 2007/07/12 18:03:03 +++ //depot/user/kris/contention/sys/kern/kern_exec.c 2007/08/31 20:34:30 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -241,19 +242,19 @@ AUDIT_ARG(envv, args->begin_envv, args->envc, args->endp - args->begin_envv); if (p->p_flag & P_HADTHREADS) { - PROC_LOCK(p); + PROC_WLOCK(p); if (thread_single(SINGLE_BOUNDARY)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); exec_free_args(args); return (ERESTART); /* Try again later. */ } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } error = do_execve(td, args, mac_p); if (p->p_flag & P_HADTHREADS) { - PROC_LOCK(p); + PROC_WLOCK(p); /* * If success, we upgrade to SINGLE_EXIT state to * force other threads to suicide. @@ -262,7 +263,7 @@ thread_single(SINGLE_EXIT); else thread_single_end(); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } return (error); @@ -315,11 +316,11 @@ * that might allow a local user to illicitly obtain elevated * privileges. */ - PROC_LOCK(p); + PROC_WLOCK(p); KASSERT((p->p_flag & P_INEXEC) == 0, ("%s(): process already has P_INEXEC flag", __func__)); p->p_flag |= P_INEXEC; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Initialize part of the common data @@ -502,13 +503,13 @@ * handlers. In execsigs(), the new process will have its signals * reset. */ - PROC_LOCK(p); + PROC_WLOCK(p); if (sigacts_shared(p->p_sigacts)) { oldsigacts = p->p_sigacts; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); newsigacts = sigacts_alloc(); sigacts_copy(newsigacts, oldsigacts); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_sigacts = newsigacts; } else oldsigacts = NULL; @@ -586,14 +587,14 @@ * fdcheckstd() may call falloc() which may block to * allocate memory, so temporarily drop the process lock. */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); setugidsafety(td); VOP_UNLOCK(imgp->vp, 0, td); error = fdcheckstd(td); vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td); if (error != 0) goto done1; - PROC_LOCK(p); + PROC_WLOCK(p); /* * Set the new credentials. */ @@ -692,15 +693,15 @@ * SX. */ if (PMC_SYSTEM_SAMPLING_ACTIVE() || PMC_PROC_IS_USING_PMCS(p)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); pe.pm_credentialschanged = credential_changing; pe.pm_entryaddr = imgp->entry_addr; PMC_CALL_HOOK_X(td, PMC_FN_PROCESS_EXEC, (void *) &pe); } else - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #else /* !HWPMC_HOOKS */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #endif /* Set values passed into the program in registers. */ @@ -781,9 +782,9 @@ exec_fail: /* we're done here, clear P_INEXEC */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag &= ~P_INEXEC; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); done2: #ifdef MAC --- //depot/vendor/freebsd/src/sys/kern/kern_exit.c 2007/06/13 20:03:43 +++ //depot/user/kris/contention/sys/kern/kern_exit.c 2007/08/31 20:34:30 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,7 @@ #ifdef KTRACE #include #endif +#include #include #include @@ -118,12 +120,7 @@ struct plimit *plim; int locked; - /* - * Drop Giant if caller has it. Eventually we should warn about - * being called with Giant held. - */ - while (mtx_owned(&Giant)) - mtx_unlock(&Giant); + mtx_assert(&Giant, MA_NOTOWNED); p = td->td_proc; if (p == initproc) { @@ -135,7 +132,7 @@ /* * MUST abort all other threads before proceeding past here. */ - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_flag & P_HADTHREADS) { retry: /* @@ -192,10 +189,11 @@ * Wait for any processes that have a hold on our vmspace to * release their reference. */ + PROC_DOWNGRADE(p); while (p->p_lock > 0) - msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0); + rw_sleep(&p->p_lock, &p->p_rwlock, PWAIT, "exithold", 0); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* Drain the limit callout while we don't have the proc locked */ callout_drain(&p->p_limco); @@ -215,9 +213,9 @@ mtx_lock(&ppeers_lock); q = p->p_peers; while (q != NULL) { - PROC_LOCK(q); + PROC_WLOCK(q); psignal(q, SIGKILL); - PROC_UNLOCK(q); + PROC_WUNLOCK(q); q = q->p_peers; } while (p->p_peers != NULL) @@ -236,7 +234,7 @@ * If parent is waiting for us to exit or exec, * P_PPWAIT is set; we will wakeup the parent below. */ - PROC_LOCK(p); + PROC_WLOCK(p); stopprofclock(p); p->p_flag &= ~(P_TRACED | P_PPWAIT); @@ -247,11 +245,11 @@ if (timevalisset(&p->p_realtimer.it_value) && callout_stop(&p->p_itcallout) == 0) { timevalclear(&p->p_realtimer.it_interval); - msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0); + rw_sleep(&p->p_itcallout, &p->p_rwlock, PWAIT, "ritwait", 0); KASSERT(!timevalisset(&p->p_realtimer.it_value), ("realtime timer is still armed")); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Reset any sigio structures pointing to us as a result of @@ -360,20 +358,20 @@ * the trace file. */ if (p->p_traceflag != 0) { - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&ktrace_mtx); p->p_traceflag = 0; mtx_unlock(&ktrace_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); ktrprocexit(td); - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&ktrace_mtx); tracevp = p->p_tracevp; p->p_tracevp = NULL; tracecred = p->p_tracecred; p->p_tracecred = NULL; mtx_unlock(&ktrace_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (tracevp != NULL) { locked = VFS_LOCK_GIANT(tracevp->v_mount); vrele(tracevp); @@ -396,10 +394,10 @@ /* * Release our limits structure. */ - PROC_LOCK(p); + PROC_WLOCK(p); plim = p->p_limit; p->p_limit = NULL; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); lim_free(plim); /* @@ -431,7 +429,7 @@ wakeup(initproc); for (; q != NULL; q = nq) { nq = LIST_NEXT(q, p_sibling); - PROC_LOCK(q); + PROC_WLOCK(q); proc_reparent(q, initproc); q->p_sigparent = SIGCHLD; /* @@ -442,11 +440,11 @@ q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE); psignal(q, SIGKILL); } - PROC_UNLOCK(q); + PROC_WUNLOCK(q); } /* Save exit status. */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_xstat = rv; p->p_xthread = td; /* @@ -466,17 +464,17 @@ * flag set, or if the handler is set to SIG_IGN, notify process * 1 instead (and hope it will handle this situation). */ - PROC_LOCK(p->p_pptr); + PROC_WLOCK(p->p_pptr); mtx_lock(&p->p_pptr->p_sigacts->ps_mtx); if (p->p_pptr->p_sigacts->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) { struct proc *pp; mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx); pp = p->p_pptr; - PROC_UNLOCK(pp); + PROC_WUNLOCK(pp); proc_reparent(p, initproc); p->p_sigparent = SIGCHLD; - PROC_LOCK(p->p_pptr); + PROC_WLOCK(p->p_pptr); /* * If this was the last child of our parent, notify * parent, so in case he was wait(2)ing, he will @@ -521,7 +519,7 @@ PROC_SUNLOCK(p->p_pptr); PROC_SLOCK(p); p->p_state = PRS_ZOMBIE; - PROC_UNLOCK(p->p_pptr); + PROC_WUNLOCK(p->p_pptr); /* * Hopefully no one will try to deliver a signal to the process this @@ -666,31 +664,32 @@ AUDIT_ARG(pid, pid); + mtx_assert(&Giant, MA_NOTOWNED); q = td->td_proc; if (pid == 0) { - PROC_LOCK(q); + PROC_RLOCK(q); pid = -q->p_pgid; - PROC_UNLOCK(q); + PROC_RUNLOCK(q); } if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WLINUXCLONE)) return (EINVAL); loop: if (q->p_flag & P_STATCHILD) { - PROC_LOCK(q); + PROC_WLOCK(q); q->p_flag &= ~P_STATCHILD; - PROC_UNLOCK(q); + PROC_WUNLOCK(q); } nfound = 0; sx_xlock(&proctree_lock); LIST_FOREACH(p, &q->p_children, p_sibling) { - PROC_LOCK(p); + PROC_WLOCK(p); if (pid != WAIT_ANY && p->p_pid != pid && p->p_pgid != -pid) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } if (p_canwait(td, p)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } @@ -704,7 +703,7 @@ */ if ((p->p_sigparent != SIGCHLD) ^ ((options & WLINUXCLONE) != 0)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } @@ -719,23 +718,23 @@ td->td_retval[0] = p->p_pid; if (status) *status = p->p_xstat; /* convert to int */ - PROC_LOCK(q); + PROC_WLOCK(q); sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); + PROC_WUNLOCK(q); /* * If we got the child via a ptrace 'attach', * we need to give it back to the old parent. */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) { - PROC_LOCK(p); + PROC_WLOCK(p); p->p_oppid = 0; proc_reparent(p, t); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); tdsignal(t, NULL, SIGCHLD, p->p_ksi); wakeup(t); - PROC_UNLOCK(t); + PROC_WUNLOCK(t); sx_xunlock(&proctree_lock); return (0); } @@ -756,13 +755,13 @@ * all other writes to this proc are visible now, so * no more locking is needed for p. */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_xstat = 0; /* XXX: why? */ - PROC_UNLOCK(p); - PROC_LOCK(q); + PROC_WUNLOCK(p); + PROC_WLOCK(q); ruadd(&q->p_stats->p_cru, &q->p_crux, &p->p_ru, &p->p_rux); - PROC_UNLOCK(q); + PROC_WUNLOCK(q); /* * Decrement the count of procs running with this uid. @@ -812,10 +811,10 @@ if (status) *status = W_STOPCODE(p->p_xstat); - PROC_LOCK(q); + PROC_WLOCK(q); sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); - PROC_UNLOCK(p); + PROC_WUNLOCK(q); + PROC_WUNLOCK(p); return (0); } @@ -825,16 +824,16 @@ td->td_retval[0] = p->p_pid; p->p_flag &= ~P_CONTINUED; - PROC_LOCK(q); + PROC_WLOCK(q); sigqueue_take(p->p_ksi); - PROC_UNLOCK(q); - PROC_UNLOCK(p); + PROC_WUNLOCK(q); + PROC_WUNLOCK(p); if (status) *status = SIGCONT; return (0); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } if (nfound == 0) { sx_xunlock(&proctree_lock); @@ -845,14 +844,14 @@ td->td_retval[0] = 0; return (0); } - PROC_LOCK(q); + PROC_WLOCK(q); sx_xunlock(&proctree_lock); if (q->p_flag & P_STATCHILD) { q->p_flag &= ~P_STATCHILD; error = 0; } else - error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0); - PROC_UNLOCK(q); + error = rw_sleep(q, &q->p_rwlock, PWAIT | PCATCH, "wait", 0); + PROC_WUNLOCK(q); if (error) return (error); goto loop; @@ -867,13 +866,13 @@ { sx_assert(&proctree_lock, SX_XLOCKED); - PROC_LOCK_ASSERT(child, MA_OWNED); + PROC_LOCK_ASSERT(child, RA_LOCKED); if (child->p_pptr == parent) return; - PROC_LOCK(child->p_pptr); + PROC_WLOCK(child->p_pptr); sigqueue_take(child->p_ksi); - PROC_UNLOCK(child->p_pptr); + PROC_WUNLOCK(child->p_pptr); LIST_REMOVE(child, p_sibling); LIST_INSERT_HEAD(&parent->p_children, child, p_sibling); child->p_pptr = parent; --- //depot/vendor/freebsd/src/sys/kern/kern_fork.c 2007/06/16 23:48:42 +++ //depot/user/kris/contention/sys/kern/kern_fork.c 2007/08/31 20:34:30 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -210,12 +211,12 @@ if ((flags & RFPROC) == 0) { if ((p1->p_flag & P_HADTHREADS) && (flags & (RFCFDG | RFFDG))) { - PROC_LOCK(p1); + PROC_WLOCK(p1); if (thread_single(SINGLE_BOUNDARY)) { - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); return (ERESTART); } - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); } vm_forkproc(td, NULL, NULL, flags); @@ -238,9 +239,9 @@ if ((p1->p_flag & P_HADTHREADS) && (flags & (RFCFDG | RFFDG))) { - PROC_LOCK(p1); + PROC_WLOCK(p1); thread_single_end(); - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); } *procp = NULL; return (0); @@ -260,13 +261,13 @@ * where they will try restart in the parent and will * be aborted in the child. */ - PROC_LOCK(p1); + PROC_WLOCK(p1); if (thread_single(SINGLE_NO_EXIT)) { /* Abort. Someone else is single threading before us. */ - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); return (ERESTART); } - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); /* * All other activity in this process * is now suspended at the user boundary, @@ -279,7 +280,7 @@ #ifdef MAC mac_init_proc(newproc); #endif - knlist_init(&newproc->p_klist, &newproc->p_mtx, NULL, NULL, NULL); + knlist_init(&newproc->p_klist, &newproc->p_rwlock, NULL, NULL, NULL); STAILQ_INIT(&newproc->p_ktr); /* We have to lock the process tree while we look for a pid. */ @@ -309,10 +310,10 @@ if (error == 0) ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, 0); else { - PROC_LOCK(p1); + PROC_RLOCK(p1); ok = chgproccnt(td->td_ucred->cr_ruidinfo, 1, lim_cur(p1, RLIMIT_NPROC)); - PROC_UNLOCK(p1); + PROC_RUNLOCK(p1); } if (!ok) { error = EAGAIN; @@ -415,20 +416,20 @@ LIST_INSERT_HEAD(&allproc, p2, p_list); LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash); - PROC_LOCK(p2); - PROC_LOCK(p1); + PROC_WLOCK(p2); + PROC_RLOCK(p1); sx_xunlock(&allproc_lock); bcopy(&p1->p_startcopy, &p2->p_startcopy, __rangeof(struct proc, p_startcopy, p_endcopy)); - PROC_UNLOCK(p1); + PROC_RUNLOCK(p1); bzero(&p2->p_startzero, __rangeof(struct proc, p_startzero, p_endzero)); p2->p_ucred = crhold(td->td_ucred); - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); /* * Malloc things while we don't hold any locks. @@ -482,8 +483,8 @@ if (pages != 0) vm_thread_new_altkstack(td2, pages); - PROC_LOCK(p2); - PROC_LOCK(p1); + PROC_WLOCK(p2); + PROC_RLOCK(p1); bzero(&td2->td_startzero, __rangeof(struct thread, td_startzero, td_endzero)); @@ -529,8 +530,8 @@ pstats_fork(p1->p_stats, p2->p_stats); - PROC_UNLOCK(p1); - PROC_UNLOCK(p2); + PROC_RUNLOCK(p1); + PROC_WUNLOCK(p2); /* Bump references to the text vnode (for procfs) */ if (p2->p_textvp) @@ -545,9 +546,9 @@ p1->p_peers = p2; p2->p_leader = p1->p_leader; mtx_unlock(&ppeers_lock); - PROC_LOCK(p1->p_leader); + PROC_RLOCK(p1->p_leader); if ((p1->p_leader->p_flag & P_WEXIT) != 0) { - PROC_UNLOCK(p1->p_leader); + PROC_RUNLOCK(p1->p_leader); /* * The task leader is exiting, so process p1 is * going to be killed shortly. Since p1 obviously @@ -561,11 +562,11 @@ * the task leader will wait for this new process * to commit suicide. */ - PROC_LOCK(p2); + PROC_WLOCK(p2); psignal(p2, SIGKILL); - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); } else - PROC_UNLOCK(p1->p_leader); + PROC_RUNLOCK(p1->p_leader); } else { p2->p_peers = NULL; p2->p_leader = p2; @@ -573,8 +574,8 @@ sx_xlock(&proctree_lock); PGRP_LOCK(p1->p_pgrp); - PROC_LOCK(p2); - PROC_LOCK(p1); + PROC_WLOCK(p2); + PROC_WLOCK(p1); /* * Preserve some more flags in subprocess. P_PROFIL has already @@ -628,7 +629,7 @@ * from being swapped. */ _PHOLD(p1); - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); /* * Attach the new process to its parent. @@ -647,7 +648,7 @@ /* Inform accounting that we have forked. */ p2->p_acflag = AFORK; - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); /* * Finish creating the child process. It will return via a different @@ -702,7 +703,7 @@ /* * Now can be swapped. */ - PROC_LOCK(p1); + PROC_WLOCK(p1); _PRELE(p1); /* @@ -710,25 +711,25 @@ */ KNOTE_LOCKED(&p1->p_klist, NOTE_FORK | p2->p_pid); - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); /* * Preserve synchronization semantics of vfork. If waiting for * child to exec or exit, set P_PPWAIT on child, and sleep on our * proc (in case of exit). */ - PROC_LOCK(p2); + PROC_RLOCK(p2); while (p2->p_flag & P_PPWAIT) - msleep(p1, &p2->p_mtx, PWAIT, "ppwait", 0); - PROC_UNLOCK(p2); + rw_sleep(p1, &p2->p_rwlock, PWAIT, "ppwait", 0); + PROC_RUNLOCK(p2); /* * If other threads are waiting, let them continue now. */ if (p1->p_flag & P_HADTHREADS) { - PROC_LOCK(p1); + PROC_WLOCK(p1); thread_single_end(); - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); } /* @@ -747,9 +748,9 @@ #endif uma_zfree(proc_zone, newproc); if (p1->p_flag & P_HADTHREADS) { - PROC_LOCK(p1); + PROC_WLOCK(p1); thread_single_end(); - PROC_UNLOCK(p1); + PROC_WUNLOCK(p1); } pause("fork", hz / 2); return (error); --- //depot/vendor/freebsd/src/sys/kern/kern_idle.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/kern/kern_idle.c 2007/08/31 20:34:30 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #ifdef SMP @@ -71,7 +72,7 @@ if (error) panic("idle_setup: kthread_create error %d\n", error); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_NOLOAD; td = FIRST_THREAD_IN_PROC(p); thread_lock(td); @@ -80,7 +81,7 @@ sched_class(td, PRI_IDLE); sched_prio(td, PRI_MAX_IDLE); thread_unlock(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #ifdef SMP } #endif --- //depot/vendor/freebsd/src/sys/kern/kern_intr.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/kern/kern_intr.c 2007/08/31 20:34:30 @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -1511,9 +1512,9 @@ panic("died while creating standard software ithreads"); p = clk_intr_event->ie_thread->it_thread->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_NOLOAD; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } SYSINIT(start_softintr, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softintr, NULL) --- //depot/vendor/freebsd/src/sys/kern/kern_jail.c 2007/04/13 23:57:04 +++ //depot/user/kris/contention/sys/kern/kern_jail.c 2007/08/31 20:34:30 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -266,13 +267,13 @@ VFS_UNLOCK_GIANT(vfslocked); newcred = crget(); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; setsugid(p); crcopy(newcred, oldcred); newcred->cr_prison = pr; p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); e_unlock: --- //depot/vendor/freebsd/src/sys/kern/kern_kse.c 2007/07/27 09:22:31 +++ //depot/user/kris/contention/sys/kern/kern_kse.c 2007/08/31 20:34:30 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -168,7 +169,7 @@ td->td_mailbox = uap->tmbx; td->td_pflags |= TDP_CAN_UNBIND; } - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); if (td->td_proc->p_flag & P_TRACED) { _PHOLD(td->td_proc); if (tmbx.tm_dflags & TMDF_SSTEP) @@ -184,7 +185,7 @@ } _PRELE(td->td_proc); } - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } return ((error == 0) ? EJUSTRETURN : error); #else /* !KSE */ @@ -214,12 +215,12 @@ p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); if (!(p->p_flag & P_SA)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EINVAL); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); switch (uap->cmd) { case KSE_INTR_SENDSIG: @@ -227,7 +228,7 @@ return (EINVAL); case KSE_INTR_INTERRUPT: case KSE_INTR_RESTART: - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); FOREACH_THREAD_IN_PROC(p, td2) { if (td2->td_mailbox == uap->tmbx) @@ -235,7 +236,7 @@ } if (td2 == NULL) { PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (ESRCH); } thread_lock(td2); @@ -260,12 +261,12 @@ sleepq_abort(td2, td2->td_intrval); thread_unlock(td2); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); break; case KSE_INTR_SIGEXIT: if (uap->data < 1 || uap->data > _SIG_MAXSIG) return (EINVAL); - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, (int)uap->data); break; @@ -280,22 +281,22 @@ if (tmbx == NULL || tmbx == (void *)-1) return (EINVAL); flags = 0; - PROC_LOCK(p); + PROC_WLOCK(p); while ((p->p_flag & P_TRACED) && !(p->p_flag & P_SINGLE_EXIT)) { flags = fuword32(&tmbx->tm_dflags); if (!(flags & TMDF_SUSPEND)) break; PROC_SLOCK(p); thread_stopped(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(td); thread_suspend_one(td); PROC_SUNLOCK(p); mi_switch(SW_VOL, NULL); thread_unlock(td); - PROC_LOCK(p); + PROC_WLOCK(p); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); case KSE_INTR_EXECVE: @@ -307,9 +308,9 @@ if (error == 0) error = kern_execve(td, &iargs, NULL); if (error == 0) { - PROC_LOCK(p); + PROC_WLOCK(p); SIGSETOR(td->td_siglist, args.sigpend); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); kern_sigprocmask(td, SIG_SETMASK, &args.sigmask, NULL, 0); } @@ -361,7 +362,7 @@ * turning into an exit. */ count = 0; - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); FOREACH_UPCALL_IN_PROC(p, ku2) { if ((ku2->ku_flags & KUF_EXITING) == 0) @@ -369,12 +370,12 @@ } if (count == 1 && (p->p_numthreads > 1)) { PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EDEADLK); } ku->ku_flags |= KUF_EXITING; PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * Mark the UTS mailbox as having been finished with. @@ -385,7 +386,7 @@ if (!(td->td_pflags & TDP_SA)) if (suword32(&td->td_mailbox->tm_lwp, 0)) error = EFAULT; - PROC_LOCK(p); + PROC_WLOCK(p); if (error) psignal(p, SIGSEGV); sigqueue_flush(&td->td_sigqueue); @@ -410,7 +411,7 @@ */ thread_unthread(td); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); #if 0 return (0); #else @@ -460,23 +461,24 @@ else { ku->ku_mflags = fuword32(&ku->ku_mailbox->km_flags); if (ku->ku_mflags == -1) { - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGSEGV); } } - PROC_LOCK(p); + PROC_WLOCK(p); if (ku->ku_mflags & KMF_WAITSIGEVENT) { /* UTS wants to wait for signal event */ if (!(p->p_flag & P_SIGEVENT) && !(ku->ku_flags & KUF_DOUPCALL)) { td->td_kflags |= TDK_KSERELSIG; - error = msleep(&p->p_siglist, &p->p_mtx, PPAUSE|PCATCH, - "ksesigwait", (uap->timeout ? tvtohz(&tv) : 0)); + error = rw_sleep(&p->p_siglist, &p->p_rwlock, + PPAUSE|PCATCH, "ksesigwait", + (uap->timeout ? tvtohz(&tv) : 0)); td->td_kflags &= ~(TDK_KSERELSIG | TDK_WAKEUP); } p->p_flag &= ~P_SIGEVENT; sigset = p->p_siglist; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = copyout(&sigset, &ku->ku_mailbox->km_sigscaught, sizeof(sigset)); } else { @@ -485,13 +487,13 @@ (p->p_completed == NULL))) { p->p_upsleeps++; td->td_kflags |= TDK_KSEREL; - error = msleep(&p->p_completed, &p->p_mtx, + error = rw_sleep(&p->p_completed, &p->p_rwlock, PPAUSE|PCATCH, "kserel", (uap->timeout ? tvtohz(&tv) : 0)); td->td_kflags &= ~(TDK_KSEREL | TDK_WAKEUP); p->p_upsleeps--; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } if (ku->ku_flags & KUF_DOUPCALL) { PROC_SLOCK(p); @@ -519,9 +521,9 @@ td2 = NULL; ku = NULL; /* KSE-enabled processes only, please. */ - PROC_LOCK(p); + PROC_WLOCK(p); if (!(p->p_flag & P_SA)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } PROC_SLOCK(p); @@ -534,21 +536,21 @@ if (p->p_upsleeps) { PROC_SUNLOCK(p); wakeup(&p->p_completed); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } ku = TAILQ_FIRST(&p->p_upcalls); } if (ku == NULL) { PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (ESRCH); } mtx_lock_spin(&kse_lock); if ((td2 = ku->ku_owner) == NULL) { mtx_unlock_spin(&kse_lock); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); panic("%s: no owner", __func__); } else if (td2->td_kflags & (TDK_KSEREL | TDK_KSERELSIG)) { mtx_unlock_spin(&kse_lock); @@ -564,7 +566,7 @@ mtx_unlock_spin(&kse_lock); } PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); #else /* !KSE */ return (EOPNOTSUPP); @@ -600,16 +602,16 @@ * suddenly start calling this one * XXX maybe... */ - PROC_LOCK(p); + PROC_WLOCK(p); if ((p->p_flag & (P_SA|P_HADTHREADS)) == P_HADTHREADS) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } if (!(p->p_flag & P_SA)) { first = 1; p->p_flag |= P_SA|P_HADTHREADS; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if ((err = copyin(uap->mbx, &mbx, sizeof(mbx)))) return (err); @@ -632,7 +634,7 @@ } else { /* It's an upcall capable thread */ sa = TDP_SA; - PROC_LOCK(p); + PROC_WLOCK(p); /* * Limit it to NCPU upcall contexts per proc in any case. * numupcalls will soon be numkse or something @@ -641,11 +643,11 @@ * actually call up). */ if (p->p_numupcalls >= ncpus) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EPROCLIM); } p->p_numupcalls++; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } /* @@ -664,7 +666,7 @@ */ if (td->td_standin == NULL) thread_alloc_spare(td); - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); /* * If we are the first time, and a normal thread, @@ -684,7 +686,7 @@ */ TAILQ_INSERT_TAIL(&p->p_upcalls, newku, ku_link); newku->ku_proc = p; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (mbx.km_quantum) /* XXX should this be in the thread? */ p->p_upquantum = max(1, mbx.km_quantum / tick); @@ -776,13 +778,13 @@ */ cpu_set_upcall_kse(newtd, newku->ku_func, newku->ku_mailbox, &newku->ku_stack); - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_flag & P_TRACED) { _PHOLD(p); ptrace_clear_single_step(newtd); _PRELE(p); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(newtd); sched_add(newtd, SRQ_BORING); thread_unlock(newtd); @@ -827,7 +829,7 @@ * For sync signal, it is only possible when the signal is not * caught by userland or process is being debugged. */ - PROC_LOCK(p); + PROC_WLOCK(p); if (td->td_flags & TDF_NEEDSIGCHK) { thread_lock(td); td->td_flags &= ~TDF_NEEDSIGCHK; @@ -839,7 +841,7 @@ } if (willexit) SIGFILLSET(td->td_sigmask); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Export the user/machine context. */ get_mcontext(td, &mc, 0); @@ -866,7 +868,7 @@ error = EFAULT; goto bad; } - PROC_LOCK(p); + PROC_WLOCK(p); if (mbx == (uintptr_t)p->p_completed) { thread_lock(td); p->p_completed = td->td_mailbox; @@ -878,16 +880,16 @@ */ td->td_mailbox = NULL; thread_unlock(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); break; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } td->td_usticks = 0; return (0); bad: - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); return (error); } @@ -906,18 +908,18 @@ for (;;) { mbx = (uintptr_t)p->p_completed; if (suword(addr, mbx)) { - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGSEGV); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EFAULT); } - PROC_LOCK(p); + PROC_WLOCK(p); if (mbx == (uintptr_t)p->p_completed) { p->p_completed = NULL; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); break; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } return (0); } @@ -975,9 +977,9 @@ return (0); error: - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGSEGV); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (-2); } @@ -1063,20 +1065,20 @@ int error; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); ps = p->p_sigacts; mtx_assert(&ps->ps_mtx, MA_OWNED); mtx_unlock(&ps->ps_mtx); SIGADDSET(td->td_sigmask, ksi->ksi_signo); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = copyout(&ksi->ksi_info, &td->td_mailbox->tm_syncsig, sizeof(siginfo_t)); if (error) { - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGSEGV); } - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&ps->ps_mtx); } #include "opt_sched.h" @@ -1149,9 +1151,9 @@ * can suspend it here or just exit. */ if (__predict_false(P_SHOULDSTOP(p))) { - PROC_LOCK(p); + PROC_WLOCK(p); thread_suspend_check(0); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } if (!(td->td_pflags & TDP_SA)) @@ -1191,7 +1193,7 @@ } else { td->td_mailbox = tmbx; td->td_pflags |= TDP_CAN_UNBIND; - PROC_LOCK(p); + PROC_WLOCK(p); if (__predict_false(p->p_flag & P_TRACED)) { flags = fuword32(&tmbx->tm_dflags); if (flags & TMDF_SUSPEND) { @@ -1202,7 +1204,7 @@ thread_unlock(td); } } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } } } @@ -1278,10 +1280,10 @@ } else if (td->td_mailbox && (ku == NULL)) { thread_unlock(td); thread_export_context(td, 1); - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_upsleeps) wakeup(&p->p_completed); - WITNESS_WARN(WARN_PANIC, &p->p_mtx.lock_object, + WITNESS_WARN(WARN_PANIC, &p->p_rwlock.lock_object, "thread exiting in userret"); sigqueue_flush(&td->td_sigqueue); PROC_SLOCK(p); @@ -1294,7 +1296,7 @@ KASSERT(ku != NULL, ("upcall is NULL")); KASSERT(TD_CAN_UNBIND(td) == 0, ("can unbind")); - PROC_LOCK(p); + PROC_RLOCK(p); PROC_SLOCK(p); if (p->p_numthreads > max_threads_per_proc) { max_threads_hits++; @@ -1302,8 +1304,9 @@ if (p->p_numupcalls >= max_threads_per_proc) break; PROC_SUNLOCK(p); - if (msleep(&p->p_numthreads, &p->p_mtx, PPAUSE|PCATCH, - "maxthreads", hz/10) != EWOULDBLOCK) { + if (rw_sleep(&p->p_numthreads, &p->p_rwlock, + PPAUSE|PCATCH, "maxthreads", + hz/10) != EWOULDBLOCK) { PROC_SLOCK(p); break; } else @@ -1311,7 +1314,7 @@ } } PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (td->td_pflags & TDP_UPCALLING) { uts_crit = 0; @@ -1336,13 +1339,13 @@ if (!(ku->ku_mflags & KMF_NOUPCALL)) { cpu_set_upcall_kse(td, ku->ku_func, ku->ku_mailbox, &ku->ku_stack); - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_flag & P_TRACED) { _PHOLD(p); ptrace_clear_single_step(td); _PRELE(p); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = suword32(&ku->ku_mailbox->km_lwp, td->td_tid); if (error) @@ -1375,9 +1378,9 @@ * the process. * how do we do that? */ - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGSEGV); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * Optimisation: @@ -1406,7 +1409,7 @@ struct kse_upcall *ku; struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); KASSERT(P_SHOULDSTOP(p), ("process not stopped")); if (!(p->p_flag & P_SA)) --- //depot/vendor/freebsd/src/sys/kern/kern_kthread.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/kern/kern_kthread.c 2007/08/31 20:34:30 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -94,12 +95,12 @@ *newpp = p2; /* this is a non-swapped system process */ - PROC_LOCK(p2); + PROC_WLOCK(p2); p2->p_flag |= P_SYSTEM | P_KTHREAD; mtx_lock(&p2->p_sigacts->ps_mtx); p2->p_sigacts->ps_flag |= PS_NOCLDWAIT; mtx_unlock(&p2->p_sigacts->ps_mtx); - PROC_UNLOCK(p2); + PROC_WUNLOCK(p2); /* set up arg0 for 'ps', et al */ va_start(ap, fmt); @@ -135,9 +136,9 @@ * is harvested. */ sx_xlock(&proctree_lock); - PROC_LOCK(p); + PROC_WLOCK(p); proc_reparent(p, initproc); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sx_xunlock(&proctree_lock); /* @@ -160,14 +161,15 @@ * Make sure this is indeed a system process and we can safely * use the p_siglist field. */ - PROC_LOCK(p); + PROC_WLOCK(p); if ((p->p_flag & P_KTHREAD) == 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } SIGADDSET(p->p_siglist, SIGSTOP); wakeup(p); - return msleep(&p->p_siglist, &p->p_mtx, PPAUSE | PDROP, "suspkt", timo); + return (rw_sleep(&p->p_siglist, &p->p_rwlock, PPAUSE | PDROP, "suspkt", + timo)); } int @@ -177,13 +179,13 @@ * Make sure this is indeed a system process and we can safely * use the p_siglist field. */ - PROC_LOCK(p); + PROC_WLOCK(p); if ((p->p_flag & P_KTHREAD) == 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } SIGDELSET(p->p_siglist, SIGSTOP); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); wakeup(&p->p_siglist); return (0); } @@ -191,10 +193,10 @@ void kthread_suspend_check(struct proc *p) { - PROC_LOCK(p); + PROC_RLOCK(p); while (SIGISMEMBER(p->p_siglist, SIGSTOP)) { wakeup(&p->p_siglist); - msleep(&p->p_siglist, &p->p_mtx, PPAUSE, "ktsusp", 0); + rw_sleep(&p->p_siglist, &p->p_rwlock, PPAUSE, "ktsusp", 0); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } --- //depot/vendor/freebsd/src/sys/kern/kern_ktrace.c 2007/08/29 21:22:37 +++ //depot/user/kris/contention/sys/kern/kern_ktrace.c 2007/09/14 21:34:44 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -622,7 +623,7 @@ vrele_count = 0; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_tracevp == vp) { if (ktrcanset(td, p)) { mtx_lock(&ktrace_mtx); @@ -636,7 +637,7 @@ } else error = EPERM; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } sx_sunlock(&allproc_lock); if (vrele_count > 0) { @@ -668,12 +669,12 @@ PGRP_UNLOCK(pg); nfound = 0; LIST_FOREACH(p, &pg->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_RLOCK(p); if (p_cansee(td, p) != 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); nfound++; if (descend) ret |= ktrsetchildren(td, p, ops, facs, vp); @@ -689,7 +690,7 @@ /* * by pid */ - p = pfind(uap->pid); + p = pfindr(uap->pid); if (p == NULL) { sx_sunlock(&proctree_lock); error = ESRCH; @@ -700,7 +701,7 @@ * The slock of the proctree lock will keep this process * from going away, so unlocking the proc here is ok. */ - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error) { sx_sunlock(&proctree_lock); goto done; @@ -773,9 +774,9 @@ struct vnode *tracevp = NULL; struct ucred *tracecred = NULL; - PROC_LOCK(p); + PROC_WLOCK(p); if (!ktrcanset(td, p)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } mtx_lock(&ktrace_mtx); @@ -807,7 +808,7 @@ } } mtx_unlock(&ktrace_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (tracevp != NULL) { int vfslocked; @@ -955,7 +956,7 @@ cred = NULL; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_tracevp == vp) { mtx_lock(&ktrace_mtx); p->p_tracevp = NULL; @@ -965,7 +966,7 @@ mtx_unlock(&ktrace_mtx); vrele_count++; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (cred != NULL) { crfree(cred); cred = NULL; @@ -997,7 +998,7 @@ struct proc *targetp; { - PROC_LOCK_ASSERT(targetp, MA_OWNED); + PROC_LOCK_ASSERT(targetp, RA_LOCKED); if (targetp->p_traceflag & KTRFAC_ROOT && priv_check(td, PRIV_KTRACE)) return (0); --- //depot/vendor/freebsd/src/sys/kern/kern_linker.c 2007/05/31 11:53:40 +++ //depot/user/kris/contention/sys/kern/kern_linker.c 2007/06/01 20:49:22 @@ -286,10 +286,8 @@ if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) return; - mtx_lock(&Giant); for (oidp = start; oidp < stop; oidp++) sysctl_register_oid(*oidp); - mtx_unlock(&Giant); } static void @@ -303,10 +301,8 @@ if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0) return; - mtx_lock(&Giant); for (oidp = start; oidp < stop; oidp++) sysctl_unregister_oid(*oidp); - mtx_unlock(&Giant); } static int --- //depot/vendor/freebsd/src/sys/kern/kern_lock.c 2007/05/18 15:07:28 +++ //depot/user/kris/contention/sys/kern/kern_lock.c 2007/08/31 20:34:30 @@ -66,6 +66,7 @@ #endif static void lock_lockmgr(struct lock_object *lock, int how); static int unlock_lockmgr(struct lock_object *lock); +static int locked_lockmgr(struct lock_object *lock); struct lock_class lock_class_lockmgr = { .lc_name = "lockmgr", @@ -75,6 +76,7 @@ #endif .lc_lock = lock_lockmgr, .lc_unlock = unlock_lockmgr, + .lc_locked = locked_lockmgr, }; /* @@ -96,6 +98,13 @@ panic("lockmgr locks do not support sleep interlocking"); } +int +locked_lockmgr(struct lock_object *lock) +{ + + panic("lockmgr locks do not support sleep interlocking"); +} + #define COUNT(td, x) if ((td)) (td)->td_locks += (x) #define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \ LK_SHARE_NONZERO | LK_WAIT_NONZERO) --- //depot/vendor/freebsd/src/sys/kern/kern_mib.c 2007/05/31 22:54:01 +++ //depot/user/kris/contention/sys/kern/kern_mib.c 2007/06/01 20:49:22 @@ -142,13 +142,13 @@ SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW, kernelname, sizeof kernelname, "Name of kernel file booted"); -SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD, +SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD | CTLFLAG_MPSAFE, &mp_ncpus, 0, "Number of active CPUs"); SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD, 0, BYTE_ORDER, "System byte order"); -SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD, +SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, PAGE_SIZE, "System memory page size"); static int --- //depot/vendor/freebsd/src/sys/kern/kern_mutex.c 2007/07/18 20:49:25 +++ //depot/user/kris/contention/sys/kern/kern_mutex.c 2007/08/31 20:34:30 @@ -91,6 +91,8 @@ static void lock_spin(struct lock_object *lock, int how); static int unlock_mtx(struct lock_object *lock); static int unlock_spin(struct lock_object *lock); +static int locked_mtx(struct lock_object *lock); +static int locked_spin(struct lock_object *lock); /* * Lock classes for sleep and spin mutexes. @@ -103,6 +105,7 @@ #endif .lc_lock = lock_mtx, .lc_unlock = unlock_mtx, + .lc_locked = locked_mtx, }; struct lock_class lock_class_mtx_spin = { .lc_name = "spin mutex", @@ -112,6 +115,7 @@ #endif .lc_lock = lock_spin, .lc_unlock = unlock_spin, + .lc_locked = locked_spin, }; /* @@ -166,6 +170,22 @@ panic("spin locks can only use msleep_spin"); } +int +locked_mtx(struct lock_object *lock) +{ + struct mtx *m; + + m = (struct mtx *)lock; + return (mtx_owned(m)); +} + +int +locked_spin(struct lock_object *lock) +{ + + panic("spin locks can only use msleep_spin"); +} + /* * Function versions of the inlined __mtx_* macros. These are used by * modules and can also be called from assembly language if needed. @@ -415,12 +435,11 @@ if (td == NULL) return; - printf( "spin lock %p (%s) held by %p (tid %d) too long\n", - m, m->lock_object.lo_name, td, td->td_tid); #ifdef WITNESS witness_display_spinlock(&m->lock_object, td); #endif - panic("spin lock held too long"); + panic("spin lock %p (%s) held by %p (tid %d) too long", + m, m->lock_object.lo_name, td, td->td_tid); } #ifdef SMP @@ -776,7 +795,6 @@ mtx_init(&Giant, "Giant", NULL, MTX_DEF | MTX_RECURSE); mtx_init(&blocked_lock, "blocked lock", NULL, MTX_SPIN); blocked_lock.mtx_lock = 0xdeadc0de; /* Always blocked. */ - mtx_init(&proc0.p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); mtx_init(&proc0.p_slock, "process slock", NULL, MTX_SPIN | MTX_RECURSE); mtx_init(&devmtx, "cdev", NULL, MTX_DEF); mtx_lock(&Giant); --- //depot/vendor/freebsd/src/sys/kern/kern_physio.c 2005/01/06 23:37:37 +++ //depot/user/kris/contention/sys/kern/kern_physio.c 2007/08/31 20:34:30 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include --- //depot/vendor/freebsd/src/sys/kern/kern_proc.c 2007/06/09 21:51:31 +++ //depot/user/kris/contention/sys/kern/kern_proc.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -175,8 +176,8 @@ p = (struct proc *)mem; p->p_sched = (struct p_sched *)&p[1]; td = thread_alloc(); - bzero(&p->p_mtx, sizeof(struct mtx)); - mtx_init(&p->p_mtx, "process lock", NULL, MTX_DEF | MTX_DUPOK); + bzero(&p->p_rwlock, sizeof(struct rwlock)); + rw_init_flags(&p->p_rwlock, "process lock", RW_DUPOK); mtx_init(&p->p_slock, "process slock", NULL, MTX_SPIN | MTX_RECURSE); p->p_stats = pstats_alloc(); proc_linkup(p, td); @@ -197,7 +198,7 @@ p = (struct proc *)mem; pstats_free(p->p_stats); thread_free(FIRST_THREAD_IN_PROC(p)); - mtx_destroy(&p->p_mtx); + rw_destroy(&p->p_rwlock); if (p->p_ksi != NULL) ksiginfo_free(p->p_ksi); #else @@ -226,9 +227,8 @@ * returning processes in the PRS_NEW state, we allow callers to avoid * testing for that condition to avoid dereferencing p_ucred, et al. */ -struct proc * -pfind(pid) - register pid_t pid; +static struct proc * +pfind_common(register pid_t pid, int wlock) { register struct proc *p; @@ -239,13 +239,30 @@ p = NULL; break; } - PROC_LOCK(p); + if (wlock) + PROC_WLOCK(p); + else + PROC_RLOCK(p); break; } sx_sunlock(&allproc_lock); return (p); } +struct proc * +pfind(register pid_t pid) +{ + + return (pfind_common(pid, 1)); +} + +struct proc * +pfindr(register pid_t pid) +{ + + return (pfind_common(pid, 0)); +} + /* * Locate a process group by number. * The caller must hold proctree_lock. @@ -302,9 +319,9 @@ */ mtx_init(&sess->s_mtx, "session", NULL, MTX_DEF); mtx_lock(&Giant); /* XXX TTY */ - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag &= ~P_CONTROLT; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); PGRP_LOCK(pgrp); sess->s_leader = p; sess->s_sid = p->p_pid; @@ -352,7 +369,7 @@ { sx_assert(&proctree_lock, SX_XLOCKED); - PROC_LOCK_ASSERT(p, MA_NOTOWNED); + PROC_LOCK_ASSERT(p, RA_UNLOCKED); PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED); SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED); @@ -380,7 +397,7 @@ struct pgrp *savepgrp; sx_assert(&proctree_lock, SX_XLOCKED); - PROC_LOCK_ASSERT(p, MA_NOTOWNED); + PROC_LOCK_ASSERT(p, RA_UNLOCKED); PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); PGRP_LOCK_ASSERT(p->p_pgrp, MA_NOTOWNED); SESS_LOCK_ASSERT(p->p_session, MA_NOTOWNED); @@ -398,10 +415,10 @@ mtx_lock(&Giant); /* XXX TTY */ PGRP_LOCK(pgrp); PGRP_LOCK(savepgrp); - PROC_LOCK(p); + PROC_WLOCK(p); LIST_REMOVE(p, p_pglist); p->p_pgrp = pgrp; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); LIST_INSERT_HEAD(&pgrp->pg_members, p, p_pglist); PGRP_UNLOCK(savepgrp); PGRP_UNLOCK(pgrp); @@ -423,10 +440,10 @@ savepgrp = p->p_pgrp; mtx_lock(&Giant); /* XXX TTY */ PGRP_LOCK(savepgrp); - PROC_LOCK(p); + PROC_WLOCK(p); LIST_REMOVE(p, p_pglist); p->p_pgrp = NULL; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); PGRP_UNLOCK(savepgrp); mtx_unlock(&Giant); /* XXX TTY */ if (LIST_EMPTY(&savepgrp->pg_members)) @@ -504,7 +521,7 @@ register struct session *mysession; sx_assert(&proctree_lock, SX_LOCKED); - PROC_LOCK_ASSERT(p, MA_NOTOWNED); + PROC_LOCK_ASSERT(p, RA_UNLOCKED); PGRP_LOCK_ASSERT(pgrp, MA_NOTOWNED); SESS_LOCK_ASSERT(pgrp->pg_session, MA_NOTOWNED); @@ -527,12 +544,9 @@ if (hispgrp == pgrp || hispgrp->pg_session != mysession) continue; - PROC_LOCK(p); - if (p->p_state == PRS_ZOMBIE) { - PROC_UNLOCK(p); + /* Lockless read. */ + if (p->p_state == PRS_ZOMBIE) continue; - } - PROC_UNLOCK(p); pgadjustjobc(hispgrp, entering); } } @@ -551,18 +565,16 @@ PGRP_LOCK_ASSERT(pg, MA_OWNED); LIST_FOREACH(p, &pg->pg_members, p_pglist) { - PROC_LOCK(p); + /* Lockless read. */ if (P_SHOULDSTOP(p)) { - PROC_UNLOCK(p); LIST_FOREACH(p, &pg->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGHUP); psignal(p, SIGCONT); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } return; } - PROC_UNLOCK(p); } } @@ -631,7 +643,7 @@ kp->ki_structsize = sizeof(*kp); kp->ki_paddr = p; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); kp->ki_addr =/* p->p_addr; */0; /* XXXKSE */ kp->ki_args = p->p_args; kp->ki_textvp = p->p_textvp; @@ -874,7 +886,7 @@ sx_slock(&allproc_lock); LIST_FOREACH(p, &zombproc, p_list) if (p->p_pid == pid) { - PROC_LOCK(p); + PROC_WLOCK(p); break; } sx_sunlock(&allproc_lock); @@ -896,7 +908,7 @@ struct proc *np; pid_t pid = p->p_pid; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_RLOCKED); fill_kinfo_proc_only(p, &kinfo_proc); if (flags & KERN_PROC_NOTHREADS) { @@ -921,23 +933,25 @@ sizeof(kinfo_proc)); PROC_SUNLOCK(p); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (error) return (error); - if (flags & KERN_PROC_ZOMBMASK) + if (flags & KERN_PROC_ZOMBMASK) { np = zpfind(pid); - else { + if (np != NULL) + PROC_DOWNGRADE(np); + } else { if (pid == 0) return (0); - np = pfind(pid); + np = pfindr(pid); } if (np == NULL) return EAGAIN; if (np != p) { - PROC_UNLOCK(np); + PROC_RUNLOCK(np); return EAGAIN; } - PROC_UNLOCK(np); + PROC_RUNLOCK(np); return (0); } @@ -964,11 +978,11 @@ error = sysctl_wire_old_buffer(req, 0); if (error) return (error); - p = pfind((pid_t)name[0]); + p = pfindr((pid_t)name[0]); if (!p) return (ESRCH); if ((error = p_cansee(curthread, p))) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } error = sysctl_out_proc(p, req, flags); @@ -1015,14 +1029,14 @@ continue; } PROC_SUNLOCK(p); - PROC_LOCK(p); + PROC_RLOCK(p); KASSERT(p->p_ucred != NULL, ("process credential is NULL for non-NEW proc")); /* * Show a user only appropriate processes. */ if (p_cansee(curthread, p)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } /* @@ -1033,7 +1047,7 @@ case KERN_PROC_GID: if (p->p_ucred->cr_gid != (gid_t)name[0]) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } break; @@ -1042,14 +1056,14 @@ /* could do this by traversing pgrp */ if (p->p_pgrp == NULL || p->p_pgrp->pg_id != (pid_t)name[0]) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } break; case KERN_PROC_RGID: if (p->p_ucred->cr_rgid != (gid_t)name[0]) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } break; @@ -1057,7 +1071,7 @@ case KERN_PROC_SESSION: if (p->p_session == NULL || p->p_session->s_sid != (pid_t)name[0]) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } break; @@ -1065,7 +1079,7 @@ case KERN_PROC_TTY: if ((p->p_flag & P_CONTROLT) == 0 || p->p_session == NULL) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } SESS_LOCK(p->p_session); @@ -1073,7 +1087,7 @@ dev2udev(p->p_session->s_ttyp->t_dev) != (dev_t)name[0]) { SESS_UNLOCK(p->p_session); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } SESS_UNLOCK(p->p_session); @@ -1081,14 +1095,14 @@ case KERN_PROC_UID: if (p->p_ucred->cr_uid != (uid_t)name[0]) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } break; case KERN_PROC_RUID: if (p->p_ucred->cr_ruid != (uid_t)name[0]) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } break; @@ -1168,23 +1182,23 @@ if (namelen != 1) return (EINVAL); - p = pfind((pid_t)name[0]); + p = pfindr((pid_t)name[0]); if (!p) return (ESRCH); if ((error = p_cansee(curthread, p)) != 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } if (req->newptr && curproc != p) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EPERM); } pa = p->p_args; pargs_hold(pa); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (req->oldptr != NULL && pa != NULL) error = SYSCTL_OUT(req, pa->ar_args, pa->ar_length); pargs_drop(pa); @@ -1199,10 +1213,10 @@ pargs_free(newpa); return (error); } - PROC_LOCK(p); + PROC_WLOCK(p); pa = p->p_args; p->p_args = newpa; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); pargs_drop(pa); return (0); } @@ -1226,11 +1240,11 @@ if (*pidp == -1) { /* -1 means this process */ p = req->td->td_proc; } else { - p = pfind(*pidp); + p = pfindr(*pidp); if (p == NULL) return (ESRCH); if ((error = p_cansee(curthread, p)) != 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } } @@ -1238,7 +1252,7 @@ vp = p->p_textvp; vref(vp); if (*pidp != -1) - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = vn_fullpath(req->td, vp, &retbuf, &freebuf); vrele(vp); if (error) @@ -1262,52 +1276,58 @@ return (EINVAL); name = (int *)arg1; - if ((p = pfind((pid_t)name[0])) == NULL) + if ((p = pfindr((pid_t)name[0])) == NULL) return (ESRCH); if ((error = p_cansee(curthread, p))) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } sv_name = p->p_sysent->sv_name; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (sysctl_handle_string(oidp, sv_name, 0, req)); } static SYSCTL_NODE(_kern, KERN_PROC, proc, CTLFLAG_RD, 0, "Process table"); -SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, CTLFLAG_RD|CTLTYPE_STRUCT, +SYSCTL_PROC(_kern_proc, KERN_PROC_ALL, all, + CTLFLAG_RD|CTLTYPE_STRUCT|CTLFLAG_MPSAFE, 0, 0, sysctl_kern_proc, "S,proc", "Return entire process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_GID, gid, CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_PGRP, pgrp, + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_RGID, rgid, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_RGID, rgid, + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_SESSION, sid, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_SESSION, sid, + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_TTY, tty, CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_UID, uid, CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_RUID, ruid, + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_PID, pid, CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); -static SYSCTL_NODE(_kern_proc, KERN_PROC_PROC, proc, CTLFLAG_RD, +static SYSCTL_NODE(_kern_proc, KERN_PROC_PROC, proc, + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Return process table, no threads"); static SYSCTL_NODE(_kern_proc, KERN_PROC_ARGS, args, - CTLFLAG_RW | CTLFLAG_ANYBODY, + CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_args, "Process argument list"); static SYSCTL_NODE(_kern_proc, KERN_PROC_PATHNAME, pathname, CTLFLAG_RD, @@ -1317,28 +1337,29 @@ sysctl_kern_proc_sv_name, "Process syscall vector name (ABI type)"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_GID | KERN_PROC_INC_THREAD), gid_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_PGRP | KERN_PROC_INC_THREAD), pgrp_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_RGID | KERN_PROC_INC_THREAD), rgid_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_SESSION | KERN_PROC_INC_THREAD), - sid_td, CTLFLAG_RD, sysctl_kern_proc, "Process table"); + sid_td, CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_TTY | KERN_PROC_INC_THREAD), tty_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_UID | KERN_PROC_INC_THREAD), uid_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_RUID | KERN_PROC_INC_THREAD), ruid_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_PID | KERN_PROC_INC_THREAD), pid_td, - CTLFLAG_RD, sysctl_kern_proc, "Process table"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, "Process table"); static SYSCTL_NODE(_kern_proc, (KERN_PROC_PROC | KERN_PROC_INC_THREAD), proc_td, - CTLFLAG_RD, sysctl_kern_proc, "Return process table, no threads"); + CTLFLAG_RD|CTLFLAG_MPSAFE, sysctl_kern_proc, + "Return process table, no threads"); --- //depot/vendor/freebsd/src/sys/kern/kern_prot.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/kern/kern_prot.c 2007/08/31 20:34:30 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -88,9 +89,9 @@ td->td_retval[0] = p->p_pid; #if defined(COMPAT_43) - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[1] = p->p_pptr->p_pid; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); #endif return (0); } @@ -106,9 +107,9 @@ { struct proc *p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = p->p_pptr->p_pid; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } @@ -125,9 +126,9 @@ { struct proc *p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); td->td_retval[0] = p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } @@ -145,19 +146,19 @@ if (uap->pid == 0) { p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); } else { - p = pfind(uap->pid); + p = pfindr(uap->pid); if (p == NULL) return (ESRCH); error = p_cansee(td, p); if (error) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } } td->td_retval[0] = p->p_pgrp->pg_id; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } @@ -177,19 +178,19 @@ if (uap->pid == 0) { p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); } else { - p = pfind(uap->pid); + p = pfindr(uap->pid); if (p == NULL) return (ESRCH); error = p_cansee(td, p); if (error) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } } td->td_retval[0] = p->p_session->s_sid; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } @@ -383,31 +384,31 @@ sx_xlock(&proctree_lock); if (uap->pid != 0 && uap->pid != curp->p_pid) { - if ((targp = pfind(uap->pid)) == NULL) { + if ((targp = pfindr(uap->pid)) == NULL) { error = ESRCH; goto done; } if (!inferior(targp)) { - PROC_UNLOCK(targp); + PROC_RUNLOCK(targp); error = ESRCH; goto done; } if ((error = p_cansee(td, targp))) { - PROC_UNLOCK(targp); + PROC_RUNLOCK(targp); goto done; } if (targp->p_pgrp == NULL || targp->p_session != curp->p_session) { - PROC_UNLOCK(targp); + PROC_RUNLOCK(targp); error = EPERM; goto done; } if (targp->p_flag & P_EXEC) { - PROC_UNLOCK(targp); + PROC_RUNLOCK(targp); error = EACCES; goto done; } - PROC_UNLOCK(targp); + PROC_RUNLOCK(targp); } else targp = curp; if (SESS_LEADER(targp)) { @@ -478,7 +479,7 @@ AUDIT_ARG(uid, uid); newcred = crget(); uip = uifind(uid); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -559,13 +560,13 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(uip); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(uip); crfree(newcred); return (error); @@ -590,7 +591,7 @@ AUDIT_ARG(euid, euid); newcred = crget(); euip = uifind(euid); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -614,13 +615,13 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(euip); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(euip); crfree(newcred); return (error); @@ -643,7 +644,7 @@ gid = uap->gid; AUDIT_ARG(gid, gid); newcred = crget(); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -715,12 +716,12 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -742,7 +743,7 @@ egid = uap->egid; AUDIT_ARG(egid, egid); newcred = crget(); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -762,12 +763,12 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -804,7 +805,7 @@ return (EINVAL); AUDIT_ARG(groupset, groups, ngrp); newcred = crget(); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -836,12 +837,12 @@ } setsugid(p); p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -869,7 +870,7 @@ newcred = crget(); euip = uifind(euid); ruip = uifind(ruid); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -900,14 +901,14 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(ruip); uifree(euip); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(ruip); uifree(euip); crfree(newcred); @@ -934,7 +935,7 @@ AUDIT_ARG(egid, egid); AUDIT_ARG(rgid, rgid); newcred = crget(); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -965,12 +966,12 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -1005,7 +1006,7 @@ newcred = crget(); euip = uifind(euid); ruip = uifind(ruid); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -1040,14 +1041,14 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(ruip); uifree(euip); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uifree(ruip); uifree(euip); crfree(newcred); @@ -1082,7 +1083,7 @@ AUDIT_ARG(rgid, rgid); AUDIT_ARG(sgid, sgid); newcred = crget(); - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; #ifdef MAC @@ -1117,12 +1118,12 @@ setsugid(p); } p->p_ucred = newcred; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(oldcred); return (0); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); return (error); } @@ -1200,9 +1201,8 @@ * a user without an exec - programs cannot know *everything* * that libc *might* have put in their data segment. */ - PROC_LOCK(p); + /* Lockless read. */ td->td_retval[0] = (p->p_flag & P_SUGID) ? 1 : 0; - PROC_UNLOCK(p); return (0); } @@ -1215,14 +1215,14 @@ p = td->td_proc; switch (uap->flag) { case 0: - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag &= ~P_SUGID; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); case 1: - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_SUGID; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); default: return (EINVAL); @@ -1392,7 +1392,7 @@ /* Wrap cr_cansee() for all functionality. */ KASSERT(td == curthread, ("%s: td not curthread", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); return (cr_cansee(td->td_ucred, p->p_ucred)); } @@ -1421,7 +1421,7 @@ { int error; - PROC_LOCK_ASSERT(proc, MA_OWNED); + PROC_LOCK_ASSERT(proc, RA_LOCKED); /* * Jail semantics limit the scope of signalling to proc in the * same jail as cred, if cred is in jail. @@ -1499,7 +1499,7 @@ { KASSERT(td == curthread, ("%s: td not curthread", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if (td->td_proc == p) return (0); @@ -1541,7 +1541,7 @@ int error; KASSERT(td == curthread, ("%s: td not curthread", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if (td->td_proc == p) return (0); if ((error = prison_check(td->td_ucred, p->p_ucred))) @@ -1593,7 +1593,7 @@ int credentialchanged, error, grpsubset, i, uidsubset; KASSERT(td == curthread, ("%s: td not curthread", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if (!unprivileged_proc_debug) { error = priv_check(td, PRIV_DEBUG_UNPRIV); if (error) @@ -1719,7 +1719,7 @@ int error; KASSERT(td == curthread, ("%s: td not curthread", __func__)); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if ((error = prison_check(td->td_ucred, p->p_ucred))) return (error); #ifdef MAC @@ -1871,9 +1871,9 @@ p = td->td_proc; cred = td->td_ucred; - PROC_LOCK(p); + PROC_RLOCK(p); td->td_ucred = crhold(p->p_ucred); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (cred != NULL) crfree(cred); } @@ -1897,11 +1897,11 @@ if (uap->namelen > MAXLOGNAME) uap->namelen = MAXLOGNAME; - PROC_LOCK(p); + PROC_RLOCK(p); SESS_LOCK(p->p_session); bcopy(p->p_session->s_login, login, uap->namelen); SESS_UNLOCK(p->p_session); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = copyout(login, uap->namebuf, uap->namelen); return(error); } @@ -1929,12 +1929,12 @@ if (error == ENAMETOOLONG) error = EINVAL; else if (!error) { - PROC_LOCK(p); + PROC_WLOCK(p); SESS_LOCK(p->p_session); (void) memcpy(p->p_session->s_login, logintmp, sizeof(logintmp)); SESS_UNLOCK(p->p_session); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } return (error); } @@ -1943,7 +1943,7 @@ setsugid(struct proc *p) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); p->p_flag |= P_SUGID; if (!(p->p_pfsflags & PF_ISUGID)) p->p_stops = 0; --- //depot/vendor/freebsd/src/sys/kern/kern_resource.c 2007/07/17 01:12:20 +++ //depot/user/kris/contention/sys/kern/kern_resource.c 2007/08/31 20:34:30 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -101,12 +102,12 @@ if (uap->who == 0) low = td->td_proc->p_nice; else { - p = pfind(uap->who); + p = pfindr(uap->who); if (p == NULL) break; if (p_cansee(td, p) == 0) low = p->p_nice; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } break; @@ -124,12 +125,12 @@ } sx_sunlock(&proctree_lock); LIST_FOREACH(p, &pg->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_RLOCK(p); if (!p_cansee(td, p)) { if (p->p_nice < low) low = p->p_nice; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } PGRP_UNLOCK(pg); break; @@ -142,13 +143,13 @@ /* Do not bother to check PRS_NEW processes */ if (p->p_state == PRS_NEW) continue; - PROC_LOCK(p); + PROC_RLOCK(p); if (!p_cansee(td, p) && p->p_ucred->cr_uid == uap->who) { if (p->p_nice < low) low = p->p_nice; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } sx_sunlock(&allproc_lock); break; @@ -183,16 +184,16 @@ switch (uap->which) { case PRIO_PROCESS: if (uap->who == 0) { - PROC_LOCK(curp); + PROC_WLOCK(curp); error = donice(td, curp, uap->prio); - PROC_UNLOCK(curp); + PROC_WUNLOCK(curp); } else { p = pfind(uap->who); if (p == 0) break; if (p_cansee(td, p) == 0) error = donice(td, p, uap->prio); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } found++; break; @@ -211,12 +212,12 @@ } sx_sunlock(&proctree_lock); LIST_FOREACH(p, &pg->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_WLOCK(p); if (!p_cansee(td, p)) { error = donice(td, p, uap->prio); found++; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } PGRP_UNLOCK(pg); break; @@ -226,13 +227,13 @@ uap->who = td->td_ucred->cr_uid; sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_ucred->cr_uid == uap->who && !p_cansee(td, p)) { error = donice(td, p, uap->prio); found++; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } sx_sunlock(&allproc_lock); break; @@ -254,7 +255,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if ((error = p_cansched(td, p))) return (error); if (n > PRIO_MAX) @@ -300,7 +301,7 @@ * since there is no efficient way to look up a LWP yet. */ p = curp; - PROC_LOCK(p); + PROC_RLOCK(p); switch (uap->function) { case RTP_LOOKUP: @@ -316,7 +317,7 @@ else error = ESRCH; PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (copyout(&rtp, uap->rtp, sizeof(struct rtprio))); case RTP_SET: if ((error = p_cansched(td, p)) || (error = cierror)) @@ -355,7 +356,7 @@ error = EINVAL; break; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } @@ -389,9 +390,9 @@ curp = td->td_proc; if (uap->pid == 0) { p = curp; - PROC_LOCK(p); + PROC_RLOCK(p); } else { - p = pfind(uap->pid); + p = pfindr(uap->pid); if (p == NULL) return (ESRCH); } @@ -429,7 +430,7 @@ } } PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (copyout(&rtp, uap->rtp, sizeof(struct rtprio))); case RTP_SET: if ((error = p_cansched(td, p)) || (error = cierror)) @@ -474,7 +475,7 @@ error = EINVAL; break; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (error); } @@ -573,9 +574,9 @@ if (uap->which >= RLIM_NLIMITS) return (EINVAL); p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); lim_rlimit(p, uap->which, &rl); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); /* * XXX would be more correct to convert only RLIM_INFINITY to the @@ -621,7 +622,7 @@ struct proc *p; p = arg; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); /* * Check if the process exceeds its cpu resource allocation. If * it reaches the max, arrange to kill the process in ast(). @@ -674,13 +675,13 @@ oldssiz.rlim_cur = 0; p = td->td_proc; newlim = lim_alloc(); - PROC_LOCK(p); + PROC_WLOCK(p); oldlim = p->p_limit; alimp = &oldlim->pl_rlimit[which]; if (limp->rlim_cur > alimp->rlim_max || limp->rlim_max > alimp->rlim_max) if ((error = priv_check(td, PRIV_PROC_SETRLIMIT))) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); lim_free(newlim); return (error); } @@ -739,7 +740,7 @@ td->td_proc->p_sysent->sv_fixlimit(limp, which); *alimp = *limp; p->p_limit = newlim; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); lim_free(oldlim); if (which == RLIMIT_STACK) { @@ -793,9 +794,9 @@ if (uap->which >= RLIM_NLIMITS) return (EINVAL); p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); lim_rlimit(p, uap->which, &rlim); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = copyout(&rlim, uap->rlp, sizeof(struct rlimit)); return (error); } @@ -811,7 +812,7 @@ struct timeval *sp; { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); calcru1(p, &p->p_crux, up, sp); } @@ -826,7 +827,7 @@ struct thread *td; uint64_t u; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); /* * If we are getting stats for the current process, then add in the @@ -955,7 +956,7 @@ struct proc *p; p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); switch (who) { case RUSAGE_SELF: @@ -969,10 +970,10 @@ break; default: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -1089,7 +1090,7 @@ lim_fork(struct proc *p1, struct proc *p2) { p2->p_limit = lim_hold(p1->p_limit); - callout_init_mtx(&p2->p_limco, &p2->p_mtx, 0); + callout_init_lock(&p2->p_limco, &p2->p_rwlock, 0); if (p1->p_cpulimit != RLIM_INFINITY) callout_reset(&p2->p_limco, hz, lim_cb, p2); } @@ -1151,7 +1152,7 @@ lim_rlimit(struct proc *p, int which, struct rlimit *rlp) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); KASSERT(which >= 0 && which < RLIM_NLIMITS, ("request for invalid resource limit")); *rlp = p->p_limit->pl_rlimit[which]; @@ -1336,6 +1337,11 @@ { rlim_t new; + if (max == RLIM_INFINITY) { + *hiwat = to; + return (1); + } + UIDINFO_LOCK(uip); new = uip->ui_sbsize + to - *hiwat; /* Don't allow them to exceed max, but allow subtraction. */ --- //depot/vendor/freebsd/src/sys/kern/kern_rwlock.c 2007/07/20 08:48:10 +++ //depot/user/kris/contention/sys/kern/kern_rwlock.c 2007/08/31 20:34:30 @@ -61,6 +61,7 @@ #endif static void lock_rw(struct lock_object *lock, int how); static int unlock_rw(struct lock_object *lock); +static int locked_rw(struct lock_object *lock); struct lock_class lock_class_rw = { .lc_name = "rw", @@ -70,6 +71,7 @@ #endif .lc_lock = lock_rw, .lc_unlock = unlock_rw, + .lc_locked = locked_rw, }; /* @@ -130,6 +132,15 @@ } } +int +locked_rw(struct lock_object *lock) +{ + struct rwlock *rw; + + rw = (struct rwlock *)lock; + return (rw_wowned(rw)); +} + void rw_init_flags(struct rwlock *rw, const char *name, int opts) { @@ -214,6 +225,34 @@ __rw_wunlock(rw, curthread, file, line); } +int +_rw_try_wlock(struct rwlock *rw, const char *file, int line) +{ + uintptr_t tid; + + MPASS(curthread != NULL); + + if (rw_wlocked(rw) && (rw->lock_object.lo_flags & RW_RECURSE)) { + rw->rw_recurse++; + atomic_set_ptr(&rw->rw_lock, RW_LOCK_RECURSED); + if (LOCK_LOG_TEST(&rw->lock_object, 0)) + CTR2(KTR_LOCK, "%s: %p recursing", __func__, rw); + return (1); + } + + tid = (uintptr_t)curthread; + if (_rw_write_lock(rw, tid)) { + LOCK_LOG_TRY("WLOCK", &rw->lock_object, 0, 1, file, line); + WITNESS_LOCK(&rw->lock_object, LOP_EXCLUSIVE | LOP_TRYLOCK, + file, line); + curthread->td_locks++; + return (1); + } + + LOCK_LOG_TRY("WLOCK", &rw->lock_object, 0, 0, file, line); + return (0); +} + void _rw_rlock(struct rwlock *rw, const char *file, int line) { @@ -494,6 +533,24 @@ } } +int +_rw_try_rlock(struct rwlock *rw, const char *file, int line) +{ + uintptr_t x; + + x = rw->rw_lock; + if ((x & RW_LOCK_READ) && atomic_cmpset_acq_ptr(&rw->rw_lock, x, + x + RW_ONE_READER)) { + LOCK_LOG_TRY("RLOCK", &rw->lock_object, 0, 1, file, line); + WITNESS_LOCK(&rw->lock_object, LOP_TRYLOCK, file, line); + curthread->td_locks++; + return (1); + } + + LOCK_LOG_TRY("RLOCK", &rw->lock_object, 0, 0, file, line); + return (0); +} + /* * This function is called when we are unable to obtain a write lock on the * first try. This means that at least one other thread holds either a @@ -946,6 +1003,20 @@ } #endif /* INVARIANT_SUPPORT */ +/* + * Intialize system rw lock. This is called from the MD startup code prior to + * mi_startup(). The per-CPU data space needs to be setup before this is called. + */ +void +rwlock_init(void) +{ + + /* + * Initialize locks. + */ + rw_init_flags(&proc0.p_rwlock, "process lock", RW_DUPOK); +} + #ifdef DDB void db_show_rwlock(struct lock_object *lock) --- //depot/vendor/freebsd/src/sys/kern/kern_shutdown.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/kern/kern_shutdown.c 2007/08/31 20:34:30 @@ -59,6 +59,7 @@ #include #include #include +#include #include #include /* smp_active */ #include @@ -185,9 +186,9 @@ /* Send a signal to init(8) and have it shutdown the world */ if (initproc != NULL) { - PROC_LOCK(initproc); + PROC_WLOCK(initproc); psignal(initproc, SIGINT); - PROC_UNLOCK(initproc); + PROC_WUNLOCK(initproc); } else { /* No init(8) running, so simply reboot */ boot(RB_NOSYNC); --- //depot/vendor/freebsd/src/sys/kern/kern_sig.c 2007/07/19 08:53:02 +++ //depot/user/kris/contention/sys/kern/kern_sig.c 2007/08/31 20:34:30 @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -387,7 +388,7 @@ KASSERT(sq->sq_flags & SQ_INIT, ("sigqueue not inited")); if (p != NULL) - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); while ((ksi = TAILQ_FIRST(&sq->sq_list)) != NULL) { TAILQ_REMOVE(&sq->sq_list, ksi, ksi_link); @@ -506,7 +507,7 @@ sigqueue_t worklist; struct thread *td0; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sigqueue_init(&worklist, NULL); sigqueue_move_set(&p->p_sigqueue, &worklist, set); @@ -550,7 +551,7 @@ int cursig(struct thread *td) { - PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + PROC_LOCK_ASSERT(td->td_proc, RA_LOCKED); mtx_assert(&td->td_proc->p_sigacts->ps_mtx, MA_OWNED); THREAD_LOCK_ASSERT(td, MA_NOTOWNED); return (SIGPENDING(td) ? issignal(td) : 0); @@ -573,7 +574,7 @@ p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); /* * If our mask changed we may have to move signal that were @@ -658,7 +659,7 @@ if (!_SIG_VALID(sig)) return (EINVAL); - PROC_LOCK(p); + PROC_WLOCK(p); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); if (oact) { @@ -684,7 +685,7 @@ if ((sig == SIGKILL || sig == SIGSTOP) && act->sa_handler != SIG_DFL) { mtx_unlock(&ps->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EINVAL); } @@ -790,7 +791,7 @@ #endif } mtx_unlock(&ps->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -921,14 +922,14 @@ register int i; struct sigacts *ps; - PROC_LOCK(p); + PROC_WLOCK(p); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); for (i = 1; i <= NSIG; i++) if (sigprop(i) & SA_IGNORE && i != SIGCONT) SIGADDSET(ps->ps_sigignore, i); mtx_unlock(&ps->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } /* @@ -946,7 +947,7 @@ * through td_sigmask (unless they were caught, * and are now ignored by default). */ - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); td = FIRST_THREAD_IN_PROC(p); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); @@ -993,7 +994,7 @@ { int error; - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); if (oset != NULL) *oset = td->td_sigmask; @@ -1021,7 +1022,7 @@ break; } } - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (error); } @@ -1178,7 +1179,7 @@ ets.tv_nsec = 0; SIG_CANTMASK(waitset); - PROC_LOCK(p); + PROC_WLOCK(p); ps = p->p_sigacts; savedmask = td->td_sigmask; if (timeout) { @@ -1253,7 +1254,7 @@ td->td_sigmask = savedmask; SIGSETNAND(td->td_sigmask, waitset); signotify(td); - error = msleep(&ps, &p->p_mtx, PPAUSE|PCATCH, "sigwait", hz); + error = rw_sleep(&ps, &p->p_rwlock, PPAUSE|PCATCH, "sigwait", hz); if (timeout) { if (error == ERESTART) { /* timeout can not be restarted. */ @@ -1289,7 +1290,7 @@ if (sig == SIGKILL) sigexit(td, sig); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } @@ -1306,10 +1307,10 @@ struct proc *p = td->td_proc; sigset_t pending; - PROC_LOCK(p); + PROC_RLOCK(p); pending = p->p_sigqueue.sq_signals; SIGSETOR(pending, td->td_sigqueue.sq_signals); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (copyout(&pending, uap->set, sizeof(sigset_t))); } @@ -1327,10 +1328,10 @@ struct proc *p = td->td_proc; sigset_t pending; - PROC_LOCK(p); + PROC_RLOCK(p); pending = p->p_sigqueue.sq_signals; SIGSETOR(pending, td->td_sigqueue.sq_signals); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); SIG2OSIG(pending, td->td_retval[0]); return (0); } @@ -1398,10 +1399,10 @@ OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); - PROC_LOCK(p); + PROC_WLOCK(p); SIG2OSIG(td->td_sigmask, td->td_retval[0]); SIGSETOR(td->td_sigmask, set); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -1420,11 +1421,11 @@ OSIG2SIG(uap->mask, set); SIG_CANTMASK(set); - PROC_LOCK(p); + PROC_WLOCK(p); SIG2OSIG(td->td_sigmask, td->td_retval[0]); SIGSETLO(td->td_sigmask, set); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } #endif /* COMPAT_43 */ @@ -1465,15 +1466,15 @@ * save it here and mark the sigacts structure * to indicate this. */ - PROC_LOCK(p); + PROC_WLOCK(p); td->td_oldsigmask = td->td_sigmask; td->td_pflags |= TDP_OLDMASK; SIG_CANTMASK(mask); td->td_sigmask = mask; signotify(td); - while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "pause", 0) == 0) + while (rw_sleep(&p->p_sigacts, &p->p_rwlock, PPAUSE|PCATCH, "pause", 0) == 0) /* void */; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* always return EINTR rather than ERESTART... */ return (EINTR); } @@ -1497,16 +1498,16 @@ struct proc *p = td->td_proc; sigset_t mask; - PROC_LOCK(p); + PROC_WLOCK(p); td->td_oldsigmask = td->td_sigmask; td->td_pflags |= TDP_OLDMASK; OSIG2SIG(uap->mask, mask); SIG_CANTMASK(mask); SIGSETLO(td->td_sigmask, mask); signotify(td); - while (msleep(&p->p_sigacts, &p->p_mtx, PPAUSE|PCATCH, "opause", 0) == 0) + while (rw_sleep(&p->p_sigacts, &p->p_rwlock, PPAUSE|PCATCH, "opause", 0) == 0) /* void */; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* always return EINTR rather than ERESTART... */ return (EINTR); } @@ -1628,10 +1629,10 @@ */ sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || p == td->td_proc || p->p_state == PRS_NEW) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } if (p_cansignal(td, p, sig) == 0) { @@ -1639,7 +1640,7 @@ if (sig) psignal(p, sig); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } sx_sunlock(&allproc_lock); } else { @@ -1659,10 +1660,10 @@ } sx_sunlock(&proctree_lock); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_pid <= 1 || p->p_flag & P_SYSTEM || p->p_state == PRS_NEW ) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } if (p_cansignal(td, p, sig) == 0) { @@ -1670,7 +1671,7 @@ if (sig) psignal(p, sig); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } PGRP_UNLOCK(pgrp); } @@ -1706,7 +1707,7 @@ error = p_cansignal(td, p, uap->signum); if (error == 0 && uap->signum) psignal(p, uap->signum); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } AUDIT_ARG(pid, uap->pid); @@ -1782,7 +1783,7 @@ ksi.ksi_value.sival_ptr = uap->value; error = tdsignal(p, NULL, ksi.ksi_signo, &ksi); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } @@ -1820,10 +1821,10 @@ if (pgrp) { PGRP_LOCK_ASSERT(pgrp, MA_OWNED); LIST_FOREACH(p, &pgrp->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_WLOCK(p); if (checkctty == 0 || p->p_flag & P_CONTROLT) psignal(p, sig); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } } } @@ -1853,7 +1854,7 @@ if (td->td_pflags & TDP_SA) { if (td->td_mailbox == NULL) thread_user_enter(td); - PROC_LOCK(p); + PROC_WLOCK(p); SIGDELSET(td->td_sigmask, sig); thread_lock(td); /* @@ -1865,10 +1866,10 @@ td->td_upcall->ku_flags |= KUF_DOUPCALL; thread_unlock(td); } else { - PROC_LOCK(p); + PROC_WLOCK(p); } #else - PROC_LOCK(p); + PROC_WLOCK(p); #endif ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); @@ -1898,10 +1899,10 @@ } else { mtx_unlock(&ps->ps_mtx); SIGADDSET(td->td_sigmask, sig); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = copyout(&ksi->ksi_info, &td->td_mailbox->tm_syncsig, sizeof(siginfo_t)); - PROC_LOCK(p); + PROC_WLOCK(p); /* UTS memory corrupted */ if (error) sigexit(td, SIGSEGV); @@ -1941,7 +1942,7 @@ p->p_sig = sig; /* XXX to verify code */ tdsignal(p, td, sig, ksi); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } static struct thread * @@ -1949,7 +1950,7 @@ { struct thread *td, *signal_td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); /* * Check if current thread can handle the signal without @@ -1999,7 +2000,7 @@ { struct thread *td = NULL; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); KASSERT(!KSI_ONQ(ksi), ("psignal_event: ksi on queue")); @@ -2048,7 +2049,7 @@ int intrval; int ret = 0; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if (!_SIG_VALID(sig)) #ifdef KSE @@ -2139,9 +2140,9 @@ PROC_SUNLOCK(p); if (p->p_flag & P_CONTINUED) { p->p_flag &= ~P_CONTINUED; - PROC_LOCK(p->p_pptr); + PROC_WLOCK(p->p_pptr); sigqueue_take(p->p_ksi); - PROC_UNLOCK(p->p_pptr); + PROC_WUNLOCK(p->p_pptr); } } @@ -2216,9 +2217,9 @@ PROC_SUNLOCK(p); p->p_flag |= P_CONTINUED; p->p_xstat = SIGCONT; - PROC_LOCK(p->p_pptr); + PROC_WLOCK(p->p_pptr); childproc_continued(p); - PROC_UNLOCK(p->p_pptr); + PROC_WUNLOCK(p->p_pptr); PROC_SLOCK(p); } if (action == SIG_DFL) { @@ -2356,7 +2357,7 @@ struct proc *p = td->td_proc; register int prop; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); THREAD_LOCK_ASSERT(td, MA_OWNED); prop = sigprop(sig); @@ -2421,7 +2422,7 @@ { struct thread *td2; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); FOREACH_THREAD_IN_PROC(p, td2) { @@ -2447,9 +2448,9 @@ { struct proc *p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, - &p->p_mtx.lock_object, "Stopping for traced signal"); + &p->p_rwlock.lock_object, "Stopping for traced signal"); thread_lock(td); td->td_flags |= TDF_XSIG; @@ -2511,7 +2512,7 @@ p = td->td_proc; ps = p->p_sigacts; mtx_assert(&ps->ps_mtx, MA_OWNED); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); for (;;) { int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); @@ -2634,7 +2635,7 @@ break; /* == ignore */ mtx_unlock(&ps->ps_mtx); WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, - &p->p_mtx.lock_object, "Catching SIGSTOP"); + &p->p_rwlock.lock_object, "Catching SIGSTOP"); p->p_flag |= P_STOPPED_SIG; p->p_xstat = sig; PROC_SLOCK(p); @@ -2681,7 +2682,7 @@ { int n; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); n = p->p_suspcount; if (p == curproc) @@ -2689,10 +2690,10 @@ if ((p->p_flag & P_STOPPED_SIG) && (n == p->p_numthreads)) { PROC_SUNLOCK(p); p->p_flag &= ~P_WAITED; - PROC_LOCK(p->p_pptr); + PROC_WLOCK(p->p_pptr); childproc_stopped(p, (p->p_flag & P_TRACED) ? CLD_TRAPPED : CLD_STOPPED); - PROC_UNLOCK(p->p_pptr); + PROC_WUNLOCK(p->p_pptr); PROC_SLOCK(p); } } @@ -2715,7 +2716,7 @@ KASSERT(sig != 0, ("postsig")); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); ps = p->p_sigacts; mtx_assert(&ps->ps_mtx, MA_OWNED); ksiginfo_init(&ksi); @@ -2819,7 +2820,7 @@ char *why; { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); CTR3(KTR_PROC, "killproc: proc %p (pid %d, %s)", p, p->p_pid, p->p_comm); log(LOG_ERR, "pid %d (%s), uid %d, was killed: %s\n", p->p_pid, p->p_comm, @@ -2842,7 +2843,7 @@ { struct proc *p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); p->p_acflag |= AXSIG; /* * We must be single-threading to generate a core dump. This @@ -2872,7 +2873,7 @@ sig &~ WCOREFLAG, sig & WCOREFLAG ? " (core dumped)" : ""); } else - PROC_UNLOCK(p); + PROC_WUNLOCK(p); exit1(td, W_EXITCODE(0, sig)); /* NOTREACHED */ } @@ -2884,8 +2885,8 @@ static void sigparent(struct proc *p, int reason, int status) { - PROC_LOCK_ASSERT(p, MA_OWNED); - PROC_LOCK_ASSERT(p->p_pptr, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); + PROC_LOCK_ASSERT(p->p_pptr, RA_LOCKED); if (p->p_ksi != NULL) { p->p_ksi->ksi_signo = SIGCHLD; @@ -2904,8 +2905,8 @@ { struct sigacts *ps; - PROC_LOCK_ASSERT(p, MA_OWNED); - PROC_LOCK_ASSERT(p->p_pptr, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); + PROC_LOCK_ASSERT(p->p_pptr, RA_LOCKED); /* * Wake up parent sleeping in kern_wait(), also send @@ -3054,12 +3055,12 @@ off_t limit; int vfslocked; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MPASS((p->p_flag & P_HADTHREADS) == 0 || p->p_singlethread == td); _STOPEVENT(p, S_CORE, 0); if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EFAULT); } @@ -3072,7 +3073,7 @@ * if it is larger than the limit. */ limit = (off_t)lim_cur(p, RLIMIT_CORE); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (limit == 0) return (EFBIG); @@ -3126,9 +3127,9 @@ VOP_SETATTR(vp, &vattr, cred, td); VOP_UNLOCK(vp, 0, td); vn_finished_write(mp); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_acflag |= ACORE; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = p->p_sysent->sv_coredump ? p->p_sysent->sv_coredump(td, vp, limit) : @@ -3164,9 +3165,9 @@ { struct proc *p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGSYS); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (ENOSYS); } @@ -3188,20 +3189,20 @@ return; } if (sigio->sio_pgid > 0) { - PROC_LOCK(sigio->sio_proc); + PROC_WLOCK(sigio->sio_proc); if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred)) psignal(sigio->sio_proc, sig); - PROC_UNLOCK(sigio->sio_proc); + PROC_WUNLOCK(sigio->sio_proc); } else if (sigio->sio_pgid < 0) { struct proc *p; PGRP_LOCK(sigio->sio_pgrp); LIST_FOREACH(p, &sigio->sio_pgrp->pg_members, p_pglist) { - PROC_LOCK(p); + PROC_WLOCK(p); if (CANSIGIO(sigio->sio_ucred, p->p_ucred) && (checkctty == 0 || (p->p_flag & P_CONTROLT))) psignal(p, sig); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } PGRP_UNLOCK(sigio->sio_pgrp); } --- //depot/vendor/freebsd/src/sys/kern/kern_sx.c 2007/07/06 13:22:45 +++ //depot/user/kris/contention/sys/kern/kern_sx.c 2007/08/31 20:34:30 @@ -108,6 +108,7 @@ #endif static void lock_sx(struct lock_object *lock, int how); static int unlock_sx(struct lock_object *lock); +static int locked_sx(struct lock_object *lock); struct lock_class lock_class_sx = { .lc_name = "sx", @@ -117,6 +118,7 @@ #endif .lc_lock = lock_sx, .lc_unlock = unlock_sx, + .lc_locked = locked_sx, }; #ifndef INVARIANTS @@ -151,6 +153,15 @@ } } +int +locked_sx(struct lock_object *lock) +{ + struct sx *sx; + + sx = (struct sx *)lock; + return (sx_xlocked(sx)); +} + void sx_sysinit(void *arg) { --- //depot/vendor/freebsd/src/sys/kern/kern_sysctl.c 2007/09/02 10:03:16 +++ //depot/user/kris/contention/sys/kern/kern_sysctl.c 2007/09/14 21:34:44 @@ -69,7 +69,12 @@ #define SYSCTL_LOCK() sx_xlock(&sysctllock) #define SYSCTL_UNLOCK() sx_xunlock(&sysctllock) -#define SYSCTL_INIT() sx_init(&sysctllock, "sysctl lock") +#define SYSCTL_INIT() sx_init_flags(&sysctllock, "sysctl lock", SX_RECURSE) + +/* Protects against modification of the sysctl tree */ +struct sx sysctl_tree_sx; + +#define SYSCTL_TREE_INIT() sx_init_flags(&sysctl_tree_sx, "sysctl_tree", SX_RECURSE); static int sysctl_root(SYSCTL_HANDLER_ARGS); @@ -101,6 +106,7 @@ struct sysctl_oid *p; struct sysctl_oid *q; + SYSCTL_TREE_XLOCK(); /* * First check if another oid with the same name already * exists in the parent's list. @@ -109,10 +115,10 @@ if (p != NULL) { if ((p->oid_kind & CTLTYPE) == CTLTYPE_NODE) { p->oid_refcnt++; - return; + goto out; } else { printf("can't re-use a leaf (%s)!\n", p->oid_name); - return; + goto out; } } /* @@ -149,6 +155,9 @@ SLIST_INSERT_AFTER(q, oidp, oid_link); else SLIST_INSERT_HEAD(parent, oidp, oid_link); +out: + SYSCTL_TREE_XUNLOCK(); + return; } void @@ -157,6 +166,7 @@ struct sysctl_oid *p; int error; + SYSCTL_TREE_XLOCK(); error = ENOENT; if (oidp->oid_number == OID_AUTO) { error = EINVAL; @@ -178,6 +188,7 @@ */ if (error) printf("%s: failed to unregister sysctl\n", __func__); + SYSCTL_TREE_XUNLOCK(); } /* Initialize a new context to keep track of dynamically added sysctls. */ @@ -199,6 +210,7 @@ struct sysctl_ctx_entry *e, *e1; int error; + SYSCTL_TREE_XLOCK(); error = 0; /* * First perform a "dry run" to check if it's ok to remove oids. @@ -224,8 +236,10 @@ sysctl_register_oid(e1->entry); e1 = TAILQ_PREV(e1, sysctl_ctx_list, link); } - if (error) + if (error) { + SYSCTL_TREE_XUNLOCK(); return(EBUSY); + } /* Now really delete the entries */ e = TAILQ_FIRST(clist); while (e != NULL) { @@ -237,6 +251,7 @@ free(e, M_SYSCTLOID); e = e1; } + SYSCTL_TREE_XUNLOCK(); return (error); } @@ -246,11 +261,13 @@ { struct sysctl_ctx_entry *e; + SYSCTL_TREE_XLOCK(); if (clist == NULL || oidp == NULL) return(NULL); e = malloc(sizeof(struct sysctl_ctx_entry), M_SYSCTLOID, M_WAITOK); e->entry = oidp; TAILQ_INSERT_HEAD(clist, e, link); + SYSCTL_TREE_XUNLOCK(); return (e); } @@ -262,10 +279,12 @@ if (clist == NULL || oidp == NULL) return(NULL); + SYSCTL_TREE_XLOCK(); TAILQ_FOREACH(e, clist, link) { if(e->entry == oidp) - return(e); + break; } + SYSCTL_TREE_XUNLOCK(); return (e); } @@ -281,13 +300,17 @@ if (clist == NULL || oidp == NULL) return (EINVAL); + SYSCTL_TREE_XLOCK(); e = sysctl_ctx_entry_find(clist, oidp); if (e != NULL) { TAILQ_REMOVE(clist, e, link); free(e, M_SYSCTLOID); + SYSCTL_TREE_XUNLOCK(); return (0); - } else + } else { + SYSCTL_TREE_XUNLOCK(); return (ENOENT); + } } /* @@ -304,6 +327,7 @@ if (oidp == NULL) return(EINVAL); + SYSCTL_TREE_XLOCK(); if ((oidp->oid_kind & CTLFLAG_DYN) == 0) { printf("can't remove non-dynamic nodes!\n"); return (EINVAL); @@ -318,11 +342,15 @@ if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { if (oidp->oid_refcnt == 1) { SLIST_FOREACH(p, SYSCTL_CHILDREN(oidp), oid_link) { - if (!recurse) + if (!recurse) { + SYSCTL_TREE_XUNLOCK(); return (ENOTEMPTY); + } error = sysctl_remove_oid(p, del, recurse); - if (error) + if (error) { + SYSCTL_TREE_XUNLOCK(); return (error); + } } if (del) free(SYSCTL_CHILDREN(oidp), M_SYSCTLOID); @@ -334,6 +362,7 @@ if (oidp->oid_refcnt == 0) { printf("Warning: bad oid_refcnt=%u (%s)!\n", oidp->oid_refcnt, oidp->oid_name); + SYSCTL_TREE_XUNLOCK(); return (EINVAL); } sysctl_unregister_oid(oidp); @@ -345,6 +374,7 @@ free(oidp, M_SYSCTLOID); } } + SYSCTL_TREE_XUNLOCK(); return (0); } @@ -364,6 +394,7 @@ /* You have to hook up somewhere.. */ if (parent == NULL) return(NULL); + SYSCTL_TREE_XLOCK(); /* Check if the node already exists, otherwise create it */ oidp = sysctl_find_oidname(name, parent); if (oidp != NULL) { @@ -372,9 +403,11 @@ /* Update the context */ if (clist != NULL) sysctl_ctx_entry_add(clist, oidp); + SYSCTL_TREE_XUNLOCK(); return (oidp); } else { printf("can't re-use a leaf (%s)!\n", name); + SYSCTL_TREE_XUNLOCK(); return (NULL); } } @@ -411,6 +444,7 @@ sysctl_ctx_entry_add(clist, oidp); /* Register this oid */ sysctl_register_oid(oidp); + SYSCTL_TREE_XUNLOCK(); return (oidp); } @@ -424,13 +458,17 @@ if (oid->oid_parent == parent) return (0); + SYSCTL_TREE_XLOCK(); oidp = sysctl_find_oidname(oid->oid_name, parent); - if (oidp != NULL) + if (oidp != NULL) { + SYSCTL_TREE_XUNLOCK(); return (EEXIST); + } sysctl_unregister_oid(oid); oid->oid_parent = parent; oid->oid_number = OID_AUTO; sysctl_register_oid(oid); + SYSCTL_TREE_XUNLOCK(); return (0); } @@ -445,6 +483,8 @@ struct sysctl_oid **oidp; SYSCTL_INIT(); + SYSCTL_TREE_INIT(); + SET_FOREACH(oidp, sysctl_set) sysctl_register_oid(*oidp); } @@ -790,6 +830,21 @@ static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD, sysctl_sysctl_oiddescr, ""); +static int +sysctl_sysctl_oidcount(SYSCTL_HANDLER_ARGS) +{ + struct sysctl_oid *oid; + int error; + + error = sysctl_find_oid(arg1, arg2, &oid, NULL, req); + if (error) + return (error); + + error = SYSCTL_OUT(req, &oid->oid_counter, sizeof(oid->oid_counter)); + return (error); +} +static SYSCTL_NODE(_sysctl, 6, oidcount, CTLFLAG_RD, sysctl_sysctl_oidcount, ""); + /* * Default "handler" functions. */ @@ -1253,19 +1308,25 @@ if (error) return (error); + if ((oid->oid_kind & CTLFLAG_MPSAFE) == 0) + mtx_lock(&Giant); if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { /* * You can't call a sysctl when it's a node, but has * no handler. Inform the user that it's a node. * The indx may or may not be the same as namelen. */ - if (oid->oid_handler == NULL) - return (EISDIR); + if (oid->oid_handler == NULL) { + error = EISDIR; + goto done; + } } /* Is this sysctl writable? */ - if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) - return (EPERM); + if (req->newptr && !(oid->oid_kind & CTLFLAG_WR)) { + error = EPERM; + goto done; + } KASSERT(req->td != NULL, ("sysctl_root(): req->td == NULL")); @@ -1274,7 +1335,7 @@ lvl = (oid->oid_kind & CTLMASK_SECURE) >> CTLSHIFT_SECURE; error = securelevel_gt(req->td->td_ucred, lvl); if (error) - return (error); + goto done; } /* Is this sysctl writable by only privileged users? */ @@ -1284,12 +1345,15 @@ else error = priv_check(req->td, PRIV_SYSCTL_WRITE); if (error) - return (error); + goto done; } - if (!oid->oid_handler) - return (EINVAL); + if (!oid->oid_handler) { + error = EINVAL; + goto done; + } + oid->oid_counter++; if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) { arg1 = (int *)arg1 + indx; arg2 -= indx; @@ -1300,11 +1364,14 @@ #ifdef MAC error = mac_check_system_sysctl(req->td->td_ucred, oid, arg1, arg2, req); - if (error != 0) - return (error); + if (error != 0) + goto done; #endif error = oid->oid_handler(oid, arg1, arg2, req); +done: + if ((oid->oid_kind & CTLFLAG_MPSAFE) == 0) + mtx_unlock(&Giant); return (error); } @@ -1331,8 +1398,7 @@ if (error) return (error); - mtx_lock(&Giant); - + SYSCTL_TREE_SLOCK(); error = userland_sysctl(td, name, uap->namelen, uap->old, uap->oldlenp, 0, uap->new, uap->newlen, &j, 0); @@ -1344,7 +1410,7 @@ error = i; } done2: - mtx_unlock(&Giant); + SYSCTL_TREE_SUNLOCK(); return (error); } --- //depot/vendor/freebsd/src/sys/kern/kern_thr.c 2007/08/16 05:32:06 +++ //depot/user/kris/contention/sys/kern/kern_thr.c 2007/08/31 20:34:30 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -224,7 +225,7 @@ } } - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); td->td_proc->p_flag |= P_HADTHREADS; newtd->td_sigmask = td->td_sigmask; PROC_SLOCK(p); @@ -234,7 +235,7 @@ sched_fork_thread(td, newtd); thread_unlock(td); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(newtd); if (rtp != NULL) { if (!(td->td_pri_class == PRI_TIMESHARE && @@ -277,7 +278,7 @@ kern_umtx_wake(td, uap->state, INT_MAX); } - PROC_LOCK(p); + PROC_WLOCK(p); sigqueue_flush(&td->td_sigqueue); PROC_SLOCK(p); @@ -291,7 +292,7 @@ /* NOTREACHED */ } PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -305,7 +306,7 @@ p = td->td_proc; error = 0; - PROC_LOCK(p); + PROC_WLOCK(p); if (uap->id == -1) { if (uap->sig != 0 && !_SIG_VALID(uap->sig)) { error = EINVAL; @@ -334,7 +335,7 @@ else tdsignal(p, ttd, uap->sig, NULL); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } @@ -350,7 +351,7 @@ if (uap->pid == td->td_proc->p_pid) { p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); } else if ((p = pfind(uap->pid)) == NULL) { return (ESRCH); } @@ -387,7 +388,7 @@ tdsignal(p, ttd, uap->sig, NULL); } } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } @@ -431,18 +432,18 @@ return (0); } - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); if ((td->td_flags & TDF_THRWAKEUP) == 0) - error = msleep((void *)td, &td->td_proc->p_mtx, PCATCH, "lthr", - hz); + error = rw_sleep((void *)td, &td->td_proc->p_rwlock, PCATCH, + "lthr", hz); if (td->td_flags & TDF_THRWAKEUP) { thread_lock(td); td->td_flags &= ~TDF_THRWAKEUP; thread_unlock(td); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (0); } - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); if (error == EWOULDBLOCK) error = ETIMEDOUT; else if (error == ERESTART) { @@ -465,17 +466,17 @@ } p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); ttd = thread_find(p, uap->id); if (ttd == NULL) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (ESRCH); } thread_lock(ttd); ttd->td_flags |= TDF_THRWAKEUP; thread_unlock(ttd); wakeup((void *)ttd); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } @@ -495,7 +496,7 @@ if (error) return (error); } - PROC_LOCK(p); + PROC_WLOCK(p); if (uap->id == td->td_tid) ttd = td; else @@ -504,6 +505,6 @@ strcpy(ttd->td_name, name); else error = ESRCH; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (error); } --- //depot/vendor/freebsd/src/sys/kern/kern_thread.c 2007/07/27 09:22:31 +++ //depot/user/kris/contention/sys/kern/kern_thread.c 2007/08/31 20:34:30 @@ -36,10 +36,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -204,6 +206,7 @@ sleepq_free(td->td_sleepqueue); umtx_thread_fini(td); vm_thread_dispose(td); + seltdfini(td); } /* @@ -372,7 +375,7 @@ PROC_SLOCK_ASSERT(p, MA_OWNED); mtx_assert(&Giant, MA_NOTOWNED); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); KASSERT(p != NULL, ("thread exiting without a process")); CTR3(KTR_PROC, "thread_exit: thread %p (pid %ld, %s)", td, (long)p->p_pid, p->p_comm); @@ -463,7 +466,7 @@ panic ("thread_exit: Last thread exiting on its own"); } } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(td); /* Save our tick information with both the thread and proc locked */ ruxagg(&p->p_rux, td); @@ -608,7 +611,7 @@ td = curthread; p = td->td_proc; mtx_assert(&Giant, MA_NOTOWNED); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); KASSERT((td != NULL), ("curthread is NULL")); if ((p->p_flag & P_HADTHREADS) == 0) @@ -769,7 +772,7 @@ td = curthread; p = td->td_proc; mtx_assert(&Giant, MA_NOTOWNED); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); while (P_SHOULDSTOP(p) || ((p->p_flag & P_TRACED) && (td->td_flags & TDF_DBSUSPEND))) { if (P_SHOULDSTOP(p) == P_STOPPED_SINGLE) { @@ -812,7 +815,7 @@ thread_unlock(p->p_singlethread); } } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(td); /* * When a thread suspends, it just @@ -828,7 +831,7 @@ if (return_instead == 0) td->td_flags &= ~TDF_BOUNDARY; thread_unlock(td); - PROC_LOCK(p); + PROC_WLOCK(p); if (return_instead == 0) p->p_boundary_count--; } @@ -842,7 +845,7 @@ p = td->td_proc; KASSERT(!TD_IS_SUSPENDED(td), ("already suspended")); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); /* * We implement thread_suspend_one in stages here to avoid @@ -850,7 +853,7 @@ */ thread_stopped(p); p->p_suspcount++; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(td); TD_SET_SUSPENDED(td); PROC_SUNLOCK(p); @@ -858,7 +861,7 @@ mi_switch(SW_VOL, NULL); thread_unlock(td); PICKUP_GIANT(); - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); } @@ -895,7 +898,7 @@ { struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); if (!P_SHOULDSTOP(p)) { FOREACH_THREAD_IN_PROC(p, td) { @@ -929,7 +932,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); p->p_flag &= ~(P_STOPPED_SINGLE | P_SINGLE_EXIT | P_SINGLE_BOUNDARY); PROC_SLOCK(p); p->p_singlethread = NULL; @@ -956,7 +959,7 @@ { struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK(p); FOREACH_THREAD_IN_PROC(p, td) { if (td->td_tid == tid) --- //depot/vendor/freebsd/src/sys/kern/kern_time.c 2007/06/09 21:51:31 +++ //depot/user/kris/contention/sys/kern/kern_time.c 2007/08/31 20:34:30 @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -212,19 +213,19 @@ getnanotime(ats); break; case CLOCK_VIRTUAL: - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); calcru(p, &user, &sys); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); TIMEVAL_TO_TIMESPEC(&user, ats); break; case CLOCK_PROF: - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); calcru(p, &user, &sys); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); timevaladd(&user, &sys); TIMEVAL_TO_TIMESPEC(&user, ats); break; @@ -545,9 +546,9 @@ * has passed return 0, else return difference between * current time and time for the timer to go off. */ - PROC_LOCK(p); + PROC_RLOCK(p); *aitv = p->p_realtimer; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (timevalisset(&aitv->it_value)) { getmicrouptime(&ctv); if (timevalcmp(&aitv->it_value, &ctv, <)) @@ -608,7 +609,7 @@ return (EINVAL); if (which == ITIMER_REAL) { - PROC_LOCK(p); + PROC_WLOCK(p); if (timevalisset(&p->p_realtimer.it_value)) callout_stop(&p->p_itcallout); getmicrouptime(&ctv); @@ -619,7 +620,7 @@ } *oitv = p->p_realtimer; p->p_realtimer = *aitv; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (timevalisset(&oitv->it_value)) { if (timevalcmp(&oitv->it_value, &ctv, <)) timevalclear(&oitv->it_value); @@ -654,13 +655,13 @@ struct timeval ctv, ntv; p = (struct proc *)arg; - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGALRM); if (!timevalisset(&p->p_realtimer.it_interval)) { timevalclear(&p->p_realtimer.it_value); if (p->p_flag & P_WEXIT) wakeup(&p->p_itcallout); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return; } for (;;) { @@ -672,7 +673,7 @@ timevalsub(&ntv, &ctv); callout_reset(&p->p_itcallout, tvtohz(&ntv) - 1, realitexpire, p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return; } } @@ -988,12 +989,12 @@ if (error != 0) goto out; - PROC_LOCK(p); + PROC_WLOCK(p); if (preset_id != -1) { KASSERT(preset_id >= 0 && preset_id < 3, ("invalid preset_id")); id = preset_id; if (p->p_itimers->its_timers[id] != NULL) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = 0; goto out; } @@ -1006,7 +1007,7 @@ if (p->p_itimers->its_timers[id] == NULL) break; if (id == TIMER_MAX) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = EAGAIN; goto out; } @@ -1039,7 +1040,7 @@ it->it_ksi.ksi_value = it->it_sigev.sigev_value; it->it_ksi.ksi_timerid = id; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); *timerid = id; return (0); @@ -1067,7 +1068,7 @@ { struct itimer *it; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if ((p->p_itimers == NULL) || (timerid >= TIMER_MAX) || (it = p->p_itimers->its_timers[timerid]) == NULL) { return (NULL); @@ -1086,13 +1087,13 @@ struct proc *p = td->td_proc; struct itimer *it; - PROC_LOCK(p); + PROC_RLOCK(p); it = itimer_find(p, timerid); if (it == NULL) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EINVAL); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); it->it_flags |= ITF_DELETING; while (it->it_usecount > 0) { @@ -1103,11 +1104,11 @@ CLOCK_CALL(it->it_clockid, timer_delete, (it)); ITIMER_UNLOCK(it); - PROC_LOCK(p); + PROC_WLOCK(p); if (KSI_ONQ(&it->it_ksi)) sigqueue_take(&it->it_ksi); p->p_itimers->its_timers[timerid] = NULL; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uma_zfree(itimer_zone, it); return (0); } @@ -1137,13 +1138,13 @@ else ovalp = NULL; - PROC_LOCK(p); + PROC_RLOCK(p); if (uap->timerid < 3 || (it = itimer_find(p, uap->timerid)) == NULL) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = EINVAL; } else { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); itimer_enter(it); error = CLOCK_CALL(it->it_clockid, timer_settime, (it, uap->flags, &val, ovalp)); @@ -1169,13 +1170,13 @@ struct itimerspec val; int error; - PROC_LOCK(p); + PROC_RLOCK(p); if (uap->timerid < 3 || (it = itimer_find(p, uap->timerid)) == NULL) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = EINVAL; } else { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); itimer_enter(it); error = CLOCK_CALL(it->it_clockid, timer_gettime, (it, &val)); @@ -1199,15 +1200,15 @@ struct itimer *it; int error ; - PROC_LOCK(p); + PROC_RLOCK(p); if (uap->timerid < 3 || (it = itimer_find(p, uap->timerid)) == NULL) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = EINVAL; } else { td->td_retval[0] = it->it_overrun_last; ITIMER_UNLOCK(it); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); error = 0; } return (error); @@ -1314,7 +1315,7 @@ { struct itimer *it; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); it = itimer_find(p, timerid); if (it != NULL) { ksi->ksi_overrun = it->it_overrun; @@ -1394,7 +1395,7 @@ if (it->it_sigev.sigev_notify == SIGEV_SIGNAL || it->it_sigev.sigev_notify == SIGEV_THREAD_ID) { - PROC_LOCK(p); + PROC_WLOCK(p); if (!KSI_ONQ(&it->it_ksi)) { it->it_ksi.ksi_errno = 0; ret = psignal_event(p, &it->it_sigev, &it->it_ksi); @@ -1418,7 +1419,7 @@ else it->it_ksi.ksi_errno = ERANGE; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } } @@ -1434,13 +1435,13 @@ TAILQ_INIT(&its->its_worklist); for (i = 0; i < TIMER_MAX; i++) its->its_timers[i] = NULL; - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_itimers == NULL) { p->p_itimers = its; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); free(its, M_SUBPROC); } } --- //depot/vendor/freebsd/src/sys/kern/kern_timeout.c 2007/08/31 19:02:43 +++ //depot/user/kris/contention/sys/kern/kern_timeout.c 2007/09/14 21:34:44 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -55,9 +56,9 @@ static int avg_gcalls; SYSCTL_INT(_debug, OID_AUTO, to_avg_gcalls, CTLFLAG_RD, &avg_gcalls, 0, "Average number of Giant callouts made per softclock call. Units = 1/1000"); -static int avg_mtxcalls; -SYSCTL_INT(_debug, OID_AUTO, to_avg_mtxcalls, CTLFLAG_RD, &avg_mtxcalls, 0, - "Average number of mtx callouts made per softclock call. Units = 1/1000"); +static int avg_lockcalls; +SYSCTL_INT(_debug, OID_AUTO, to_avg_lockcalls, CTLFLAG_RD, &avg_lockcalls, 0, + "Average number of lock callouts made per softclock call. Units = 1/1000"); static int avg_mpcalls; SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0, "Average number of MP callouts made per softclock call. Units = 1/1000"); @@ -82,12 +83,12 @@ * If curr_callout is non-NULL, threads waiting in * callout_drain() will be woken up as soon as the * relevant callout completes. - * curr_cancelled - Changing to 1 with both callout_lock and c_mtx held - * guarantees that the current callout will not run. + * curr_cancelled - Changing to 1 with both callout_lock and c_lock + * held guarantees that the current callout will not run. * The softclock() function sets this to 0 before it - * drops callout_lock to acquire c_mtx, and it calls + * drops callout_lock to acquire c_lock, and it calls * the handler only if curr_cancelled is still 0 after - * c_mtx is successfully acquired. + * c_lock is successfully acquired. * callout_wait - If a thread is waiting in callout_drain(), then * callout_wait is nonzero. Set only when * curr_callout is non-NULL. @@ -170,7 +171,7 @@ int steps; /* #steps since we last allowed interrupts */ int depth; int mpcalls; - int mtxcalls; + int lockcalls; int gcalls; #ifdef DIAGNOSTIC struct bintime bt1, bt2; @@ -184,7 +185,7 @@ #endif /* MAX_SOFTCLOCK_STEPS */ mpcalls = 0; - mtxcalls = 0; + lockcalls = 0; gcalls = 0; depth = 0; steps = 0; @@ -215,14 +216,19 @@ } else { void (*c_func)(void *); void *c_arg; - struct mtx *c_mtx; + struct lock_class *class; + struct lock_object *c_lock; int c_flags; nextsoftcheck = TAILQ_NEXT(c, c_links.tqe); TAILQ_REMOVE(bucket, c, c_links.tqe); c_func = c->c_func; c_arg = c->c_arg; - c_mtx = c->c_mtx; + c_lock = c->c_lock; + if (c_lock == NULL) + class = NULL; + else + class = LOCK_CLASS(c_lock); c_flags = c->c_flags; if (c->c_flags & CALLOUT_LOCAL_ALLOC) { c->c_func = NULL; @@ -237,7 +243,7 @@ } curr_cancelled = 0; mtx_unlock_spin(&callout_lock); - if (c_mtx != NULL) { + if (c_lock != NULL) { if (c_flags & CALLOUT_NETGIANT) { mtx_lock(&Giant); gcalls++; @@ -245,26 +251,27 @@ " %p func %p arg %p", c, c_func, c_arg); } - mtx_lock(c_mtx); + class->lc_lock(c_lock, 1); /* * The callout may have been cancelled * while we switched locks. */ if (curr_cancelled) { - mtx_unlock(c_mtx); + class->lc_unlock(c_lock); goto skip; } /* The callout cannot be stopped now. */ curr_cancelled = 1; - if (c_mtx == &Giant) { + if (c_lock == + (struct lock_object *)&Giant) { gcalls++; CTR3(KTR_CALLOUT, "callout %p func %p arg %p", c, c_func, c_arg); } else { - mtxcalls++; - CTR3(KTR_CALLOUT, "callout mtx" + lockcalls++; + CTR3(KTR_CALLOUT, "callout lock" " %p func %p arg %p", c, c_func, c_arg); } @@ -298,7 +305,7 @@ } #endif if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0) - mtx_unlock(c_mtx); + class->lc_unlock(c_lock); if (c_flags & CALLOUT_NETGIANT) mtx_unlock(&Giant); skip: @@ -321,7 +328,7 @@ } avg_depth += (depth * 1000 - avg_depth) >> 8; avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8; - avg_mtxcalls += (mtxcalls * 1000 - avg_mtxcalls) >> 8; + avg_lockcalls += (lockcalls * 1000 - avg_lockcalls) >> 8; avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8; nextsoftcheck = NULL; mtx_unlock_spin(&callout_lock); @@ -421,8 +428,13 @@ int cancelled = 0; #ifdef notyet /* Some callers of timeout() do not hold Giant. */ - if (c->c_mtx != NULL) - mtx_assert(c->c_mtx, MA_OWNED); + if (c->c_lock != NULL) { + struct lock_class *class; + + class = LOCK_CLASS(c->c_lock); + if (!class->lc_locked(c->c_lock)) + panic("Lock %s not locked", c->c_lock->lo_name); + } #endif mtx_lock_spin(&callout_lock); @@ -432,7 +444,7 @@ * currently in progress. If there is a mutex then we * can cancel the callout if it has not really started. */ - if (c->c_mtx != NULL && !curr_cancelled) + if (c->c_lock != NULL && !curr_cancelled) cancelled = curr_cancelled = 1; if (callout_wait) { /* @@ -491,17 +503,21 @@ struct callout *c; int safe; { - int use_mtx, sq_locked; + int use_lock, sq_locked; + + if (!safe && c->c_lock != NULL) { + struct lock_class *class; - if (!safe && c->c_mtx != NULL) { + class = LOCK_CLASS(c->c_lock); #ifdef notyet /* Some callers do not hold Giant for Giant-locked callouts. */ - mtx_assert(c->c_mtx, MA_OWNED); - use_mtx = 1; + if (!class->lc_locked(c->c_lock)) + panic("Lock %s not locked", c->c_lock->lo_name); + use_lock = 1; #else - use_mtx = mtx_owned(c->c_mtx); + use_lock = class->lc_locked(c->c_lock); #endif } else { - use_mtx = 0; + use_lock = 0; } sq_locked = 0; @@ -574,7 +590,7 @@ PICKUP_GIANT(); mtx_lock_spin(&callout_lock); } - } else if (use_mtx && !curr_cancelled) { + } else if (use_lock && !curr_cancelled) { /* * The current callout is waiting for it's * mutex which we hold. Cancel the callout @@ -623,27 +639,26 @@ { bzero(c, sizeof *c); if (mpsafe) { - c->c_mtx = NULL; + c->c_lock = NULL; c->c_flags = CALLOUT_RETURNUNLOCKED; } else { - c->c_mtx = &Giant; - c->c_flags = 0; + c->c_lock = (struct lock_object *)&Giant; } } void -callout_init_mtx(c, mtx, flags) +_callout_init_lock(c, lock, flags) struct callout *c; - struct mtx *mtx; + struct lock_object *lock; int flags; { bzero(c, sizeof *c); - c->c_mtx = mtx; + c->c_lock = lock; KASSERT((flags & ~(CALLOUT_RETURNUNLOCKED|CALLOUT_NETGIANT)) == 0, - ("callout_init_mtx: bad flags %d", flags)); + ("callout_init_lock: bad flags %d", flags)); /* CALLOUT_RETURNUNLOCKED makes no sense without a mutex. */ - KASSERT(mtx != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0, - ("callout_init_mtx: CALLOUT_RETURNUNLOCKED with no mutex")); + KASSERT(lock != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0, + ("callout_init_lock: CALLOUT_RETURNUNLOCKED with no mutex")); c->c_flags = flags & (CALLOUT_RETURNUNLOCKED|CALLOUT_NETGIANT); } --- //depot/vendor/freebsd/src/sys/kern/kern_umtx.c 2007/06/06 07:37:03 +++ //depot/user/kris/contention/sys/kern/kern_umtx.c 2007/09/09 14:41:20 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,9 @@ #define TYPE_PP_UMUTEX 4 #define TYPE_CV 5 +#define umtxq_lock(key) mtx_lock(&umtxq_getchain(key)->uc_lock); +#define umtxq_unlock(key) mtx_unlock(&umtxq_getchain(key)->uc_lock); + /* Key to represent a unique userland synchronous object */ struct umtx_key { int hash; @@ -197,8 +201,6 @@ static void umtxq_sysinit(void *); static void umtxq_hash(struct umtx_key *key); static struct umtxq_chain *umtxq_getchain(struct umtx_key *key); -static void umtxq_lock(struct umtx_key *key); -static void umtxq_unlock(struct umtx_key *key); static void umtxq_busy(struct umtx_key *key); static void umtxq_unbusy(struct umtx_key *key); static void umtxq_insert(struct umtx_q *uq); @@ -314,30 +316,6 @@ } /* - * Lock a chain. - */ -static inline void -umtxq_lock(struct umtx_key *key) -{ - struct umtxq_chain *uc; - - uc = umtxq_getchain(key); - mtx_lock(&uc->uc_lock); -} - -/* - * Unlock a chain. - */ -static inline void -umtxq_unlock(struct umtx_key *key) -{ - struct umtxq_chain *uc; - - uc = umtxq_getchain(key); - mtx_unlock(&uc->uc_lock); -} - -/* * Insert a thread onto the umtx queue. */ static inline void @@ -1433,14 +1411,14 @@ * For process private PI-mutex, we can find owner * thread and boost its priority safely. */ - PROC_LOCK(curproc); + PROC_RLOCK(curproc); td1 = thread_find(curproc, owner); mtx_lock_spin(&umtx_lock); if (td1 != NULL && pi->pi_owner == NULL) { uq1 = td1->td_umtxq; umtx_pi_setowner(pi, td1); } - PROC_UNLOCK(curproc); + PROC_RUNLOCK(curproc); } else { mtx_lock_spin(&umtx_lock); } --- //depot/vendor/freebsd/src/sys/kern/p1003_1b.c 2007/03/05 13:12:17 +++ //depot/user/kris/contention/sys/kern/p1003_1b.c 2007/08/31 20:34:30 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -122,7 +123,7 @@ if (uap->pid == 0) { targetp = td->td_proc; targettd = td; - PROC_LOCK(targetp); + PROC_WLOCK(targetp); } else { targetp = pfind(uap->pid); if (targetp == NULL) @@ -135,7 +136,7 @@ e = ksched_setparam(ksched, targettd, (const struct sched_param *)&sched_param); } - PROC_UNLOCK(targetp); + PROC_WUNLOCK(targetp); return (e); } @@ -150,9 +151,9 @@ if (uap->pid == 0) { targetp = td->td_proc; targettd = td; - PROC_LOCK(targetp); + PROC_RLOCK(targetp); } else { - targetp = pfind(uap->pid); + targetp = pfindr(uap->pid); if (targetp == NULL) { return (ESRCH); } @@ -163,7 +164,7 @@ if (e == 0) { e = ksched_getparam(ksched, targettd, &sched_param); } - PROC_UNLOCK(targetp); + PROC_RUNLOCK(targetp); if (e == 0) e = copyout(&sched_param, uap->param, sizeof(sched_param)); return (e); @@ -189,7 +190,7 @@ if (uap->pid == 0) { targetp = td->td_proc; targettd = td; - PROC_LOCK(targetp); + PROC_WLOCK(targetp); } else { targetp = pfind(uap->pid); if (targetp == NULL) @@ -202,7 +203,7 @@ e = ksched_setscheduler(ksched, targettd, uap->policy, (const struct sched_param *)&sched_param); } - PROC_UNLOCK(targetp); + PROC_WUNLOCK(targetp); return (e); } @@ -216,9 +217,9 @@ if (uap->pid == 0) { targetp = td->td_proc; targettd = td; - PROC_LOCK(targetp); + PROC_RLOCK(targetp); } else { - targetp = pfind(uap->pid); + targetp = pfindr(uap->pid); if (targetp == NULL) { e = ESRCH; goto done2; @@ -231,7 +232,7 @@ e = ksched_getscheduler(ksched, targettd, &policy); td->td_retval[0] = policy; } - PROC_UNLOCK(targetp); + PROC_RUNLOCK(targetp); done2: return (e); @@ -290,13 +291,13 @@ if (pid == 0) { targettd = td; targetp = td->td_proc; - PROC_LOCK(targetp); + PROC_RLOCK(targetp); } else { targetp = td->td_proc; - PROC_LOCK(targetp); + PROC_RLOCK(targetp); targettd = thread_find(targetp, pid); if (targettd == NULL) { - PROC_UNLOCK(targetp); + PROC_RUNLOCK(targetp); return (ESRCH); } } @@ -304,7 +305,7 @@ e = p_cansee(td, targetp); if (e == 0) e = ksched_rr_get_interval(ksched, targettd, ts); - PROC_UNLOCK(targetp); + PROC_RUNLOCK(targetp); return (e); } --- //depot/vendor/freebsd/src/sys/kern/sched_4bsd.c 2007/07/18 20:49:25 +++ //depot/user/kris/contention/sys/kern/sched_4bsd.c 2007/08/31 20:34:30 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -677,7 +678,7 @@ { struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); p->p_nice = nice; FOREACH_THREAD_IN_PROC(p, td) { --- //depot/vendor/freebsd/src/sys/kern/sched_ule.c 2007/08/20 06:36:50 +++ //depot/user/kris/contention/sys/kern/sched_ule.c 2007/08/31 20:34:30 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -1893,7 +1894,7 @@ { struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); PROC_SLOCK_ASSERT(p, MA_OWNED); p->p_nice = nice; --- //depot/vendor/freebsd/src/sys/kern/subr_bus.c 2007/07/27 12:03:05 +++ //depot/user/kris/contention/sys/kern/subr_bus.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -522,9 +523,9 @@ selwakeup(&devsoftc.sel); p = devsoftc.async_proc; if (p != NULL) { - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGIO); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } } --- //depot/vendor/freebsd/src/sys/kern/subr_lock.c 2007/09/14 01:17:56 +++ //depot/user/kris/contention/sys/kern/subr_lock.c 2007/09/14 21:34:44 @@ -69,6 +69,9 @@ int lock_prof_enable = 0; SYSCTL_INT(_debug_lock_prof, OID_AUTO, enable, CTLFLAG_RW, &lock_prof_enable, 0, "Enable lock profiling"); +int lock_sample_rate = 1023; +SYSCTL_INT(_debug_lock_prof, OID_AUTO, rate, CTLFLAG_RW, + &lock_sample_rate, 1023, "Record profiling data for 1/(n+1) events (n must be 2^a-1)"); /* * lprof_buf is a static pool of profiling records to avoid possible @@ -255,6 +258,14 @@ void _lock_profile_obtain_lock_success(struct lock_object *lo, int contested, uint64_t waittime, const char *file, int line) { struct lock_profile_object *l = &lo->lo_profile_obj; + uint64_t time; + + time = nanoseconds(); + + if (time & lock_sample_rate) { + l->lpo_acqtime = 0; + return; + } lo->lo_profile_obj.lpo_contest_holding = 0; @@ -263,7 +274,8 @@ l->lpo_filename = file; l->lpo_lineno = line; - l->lpo_acqtime = nanoseconds(); + l->lpo_acqtime = time; + if (waittime && (l->lpo_acqtime > waittime)) l->lpo_waittime = l->lpo_acqtime - waittime; else --- //depot/vendor/freebsd/src/sys/kern/subr_param.c 2005/10/16 04:01:06 +++ //depot/user/kris/contention/sys/kern/subr_param.c 2006/06/10 20:54:45 @@ -51,11 +51,7 @@ */ #ifndef HZ -# if defined(__amd64__) || defined(__i386__) || defined(__ia64__) || defined(__sparc64__) -# define HZ 1000 -# else -# define HZ 100 -# endif +# define HZ 100 #endif #define NPROC (20 + 16 * maxusers) #ifndef NBUF --- //depot/vendor/freebsd/src/sys/kern/subr_prf.c 2007/03/08 06:46:41 +++ //depot/user/kris/contention/sys/kern/subr_prf.c 2007/08/31 20:34:30 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -138,16 +139,16 @@ mtx_lock(&Giant); p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); if ((p->p_flag & P_CONTROLT) == 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); retval = 0; goto out; } SESS_LOCK(p->p_session); pca.tty = p->p_session->s_ttyp; SESS_UNLOCK(p->p_session); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (pca.tty == NULL) { retval = 0; goto out; @@ -178,11 +179,11 @@ if (pri != -1) flags |= TOLOG; if (p != NULL) { - PROC_LOCK(p); + PROC_RLOCK(p); if (p->p_flag & P_CONTROLT && p->p_session->s_ttyvp) { sess = p->p_session; SESS_LOCK(sess); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); SESSHOLD(sess); tp = sess->s_ttyp; SESS_UNLOCK(sess); @@ -191,7 +192,7 @@ else tp = NULL; } else - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } pca.pri = pri; pca.tty = tp; --- //depot/vendor/freebsd/src/sys/kern/subr_prof.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/kern/subr_prof.c 2007/08/31 20:34:30 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -344,24 +345,24 @@ return (0); if (state == GMON_PROF_OFF) { gp->state = state; - PROC_LOCK(&proc0); + PROC_WLOCK(&proc0); stopprofclock(&proc0); - PROC_UNLOCK(&proc0); + PROC_WUNLOCK(&proc0); stopguprof(gp); } else if (state == GMON_PROF_ON) { gp->state = GMON_PROF_OFF; stopguprof(gp); gp->profrate = profhz; - PROC_LOCK(&proc0); + PROC_WLOCK(&proc0); startprofclock(&proc0); - PROC_UNLOCK(&proc0); + PROC_WUNLOCK(&proc0); gp->state = state; #ifdef GUPROF } else if (state == GMON_PROF_HIRES) { gp->state = GMON_PROF_OFF; - PROC_LOCK(&proc0); + PROC_WLOCK(&proc0); stopprofclock(&proc0); - PROC_UNLOCK(&proc0); + PROC_WUNLOCK(&proc0); startguprof(gp); gp->state = state; #endif @@ -416,12 +417,12 @@ p = td->td_proc; if (uap->scale == 0) { - PROC_LOCK(p); + PROC_WLOCK(p); stopprofclock(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } - PROC_LOCK(p); + PROC_WLOCK(p); upp = &td->td_proc->p_stats->p_prof; PROC_SLOCK(p); upp->pr_off = uap->offset; @@ -430,7 +431,7 @@ upp->pr_size = uap->size; PROC_SUNLOCK(p); startprofclock(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -504,9 +505,9 @@ if (ticks == 0) return; - PROC_LOCK(p); + PROC_WLOCK(p); if (!(p->p_flag & P_PROFIL)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return; } p->p_profthreads++; @@ -520,16 +521,16 @@ addr = prof->pr_base + i; PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (copyin(addr, &v, sizeof(v)) == 0) { v += ticks; if (copyout(&v, addr, sizeof(v)) == 0) { - PROC_LOCK(p); + PROC_WLOCK(p); goto out; } } stop = 1; - PROC_LOCK(p); + PROC_WLOCK(p); out: if (--p->p_profthreads == 0) { @@ -540,7 +541,7 @@ } if (stop) stopprofclock(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } #if (defined(__amd64__) || defined(__i386__)) && \ --- //depot/vendor/freebsd/src/sys/kern/subr_sleepqueue.c 2007/09/13 09:17:30 +++ //depot/user/kris/contention/sys/kern/subr_sleepqueue.c 2007/09/14 21:34:44 @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -387,7 +388,7 @@ mtx_unlock_spin(&sc->sc_lock); /* See if there are any pending signals for this thread. */ - PROC_LOCK(p); + PROC_WLOCK(p); ps = p->p_sigacts; mtx_lock(&ps->ps_mtx); sig = cursig(td); @@ -407,7 +408,7 @@ * without this, we could lose a race. */ mtx_lock_spin(&sc->sc_lock); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(td); if (ret == 0) { if (!(td->td_flags & TDF_INTERRUPT)) { --- //depot/vendor/freebsd/src/sys/kern/subr_trap.c 2007/06/12 23:32:21 +++ //depot/user/kris/contention/sys/kern/subr_trap.c 2007/08/31 20:34:30 @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -82,13 +83,13 @@ p->p_comm); #ifdef DIAGNOSTIC /* Check that we called signotify() enough. */ - PROC_LOCK(p); + PROC_RLOCK(p); thread_lock(td); if (SIGPENDING(td) && ((td->td_flags & TDF_NEEDSIGCHK) == 0 || (td->td_flags & TDF_ASTPENDING) == 0)) printf("failed to set signal flags properly for ast()\n"); thread_unlock(td); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); #endif #ifdef KTRACE @@ -109,9 +110,9 @@ * at this time.. If we miss it, we miss it.. no big deal. */ if (P_SHOULDSTOP(p)) { - PROC_LOCK(p); + PROC_WLOCK(p); thread_suspend_check(0); /* Can suspend or kill */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } #ifdef KSE @@ -211,9 +212,9 @@ td->td_pflags &= ~TDP_OWEUPC; } if (sflag & PS_ALRMPEND) { - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGVTALRM); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } #if defined(DEV_NPX) && !defined(SMP) if (PCPU_GET(curpcb)->pcb_flags & PCB_NPXTRAP) { @@ -229,9 +230,9 @@ } #endif if (sflag & PS_PROFPEND) { - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGPROF); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } #ifdef MAC if (sflag & PS_MACPEND) @@ -253,12 +254,12 @@ #endif } if (flags & TDF_NEEDSIGCHK) { - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); while ((sig = cursig(td)) != 0) postsig(sig); mtx_unlock(&p->p_sigacts->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } userret(td, framep); --- //depot/vendor/freebsd/src/sys/kern/subr_witness.c 2007/06/16 23:33:01 +++ //depot/user/kris/contention/sys/kern/subr_witness.c 2007/08/31 20:34:30 @@ -286,7 +286,7 @@ { "pipe mutex", &lock_class_mtx_sleep }, { "sigio lock", &lock_class_mtx_sleep }, { "process group", &lock_class_mtx_sleep }, - { "process lock", &lock_class_mtx_sleep }, + { "process lock", &lock_class_rw }, { "session", &lock_class_mtx_sleep }, { "uidinfo hash", &lock_class_mtx_sleep }, { "uidinfo struct", &lock_class_mtx_sleep }, --- //depot/vendor/freebsd/src/sys/kern/sys_generic.c 2007/07/04 23:03:16 +++ //depot/user/kris/contention/sys/kern/sys_generic.c 2007/08/31 20:34:30 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -69,17 +70,59 @@ #include #endif +#include + static MALLOC_DEFINE(M_IOCTLOPS, "ioctlops", "ioctl data buffer"); static MALLOC_DEFINE(M_SELECT, "select", "select() buffer"); MALLOC_DEFINE(M_IOV, "iov", "large iov's"); static int pollscan(struct thread *, struct pollfd *, u_int); +static int pollrescan(struct thread *); static int selscan(struct thread *, fd_mask **, fd_mask **, int); +static int selrescan(struct thread *, fd_mask **, fd_mask **); +static void selfdalloc(struct thread *, void *); +static void selfdfree(struct seltd *, struct selfd *); static int dofileread(struct thread *, int, struct file *, struct uio *, off_t, int); static int dofilewrite(struct thread *, int, struct file *, struct uio *, off_t, int); static void doselwakeup(struct selinfo *, int); +static void seltdinit(struct thread *); +static int seltdwait(struct thread *, int); +static void seltdclear(struct thread *); + +/* + * One seltd per-thread allocated on demand as needed. + * + * t - protected by st_mtx + * k - Only accessed by curthread or read-only + */ +struct seltd { + STAILQ_HEAD(, selfd) st_selq; /* (k) List of selfds. */ + struct selfd *st_free1; /* (k) free fd for read set. */ + struct selfd *st_free2; /* (k) free fd for write set. */ + struct mtx st_mtx; /* Protects struct seltd */ + struct cv st_wait; /* (t) Wait channel. */ + int st_flags; /* (t) SELTD_ flags. */ +}; + +#define SELTD_PENDING 0x0001 /* We have pending events. */ +#define SELTD_RESCAN 0x0002 /* Doing a rescan. */ + +/* + * One selfd allocated per-thread per-file-descriptor. + * f - protected by sf_mtx + */ +struct selfd { + STAILQ_ENTRY(selfd) sf_link; /* (k) fds owned by this td. */ + TAILQ_ENTRY(selfd) sf_threads; /* (f) fds on this selinfo. */ + struct selinfo *sf_si; /* (f) selinfo when linked. */ + struct mtx *sf_mtx; /* Pointer to selinfo mtx. */ + struct seltd *sf_td; /* (k) owning seltd. */ + void *sf_cookie; /* (k) fd or pollfd. */ +}; + +static uma_zone_t selfd_zone; #ifndef _SYS_SYSPROTO_H_ struct read_args { @@ -486,9 +529,9 @@ error = 0; /* Socket layer is responsible for issuing SIGPIPE. */ if (fp->f_type != DTYPE_SOCKET && error == EPIPE) { - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); psignal(td->td_proc, SIGPIPE); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } cnt -= auio->uio_resid; @@ -604,21 +647,17 @@ FILEDESC_XUNLOCK(fdp); goto out; case FIONBIO: - FILE_LOCK(fp); if ((tmp = *(int *)data)) - fp->f_flag |= FNONBLOCK; + atomic_set_int(&fp->f_flag, FNONBLOCK); else - fp->f_flag &= ~FNONBLOCK; - FILE_UNLOCK(fp); + atomic_clear_int(&fp->f_flag, FNONBLOCK); data = (void *)&tmp; break; case FIOASYNC: - FILE_LOCK(fp); if ((tmp = *(int *)data)) - fp->f_flag |= FASYNC; + atomic_set_int(&fp->f_flag, FASYNC); else - fp->f_flag &= ~FASYNC; - FILE_UNLOCK(fp); + atomic_clear_int(&fp->f_flag, FASYNC); data = (void *)&tmp; break; } @@ -629,14 +668,6 @@ return (error); } -/* - * sellock and selwait are initialized in selectinit() via SYSINIT. - */ -struct mtx sellock; -struct cv selwait; -u_int nselcoll; /* Select collisions since boot */ -SYSCTL_UINT(_kern, OID_AUTO, nselcoll, CTLFLAG_RD, &nselcoll, 0, ""); - #ifndef _SYS_SYSPROTO_H_ struct select_args { int nd; @@ -678,7 +709,7 @@ fd_mask *ibits[3], *obits[3], *selbits, *sbp; struct timeval atv, rtv, ttv; int error, timo; - u_int ncoll, nbufbytes, ncpbytes, nfdbits; + u_int nbufbytes, ncpbytes, nfdbits; if (nd < 0) return (EINVAL); @@ -723,7 +754,7 @@ sbp += ncpbytes / sizeof *sbp; \ error = copyin(name, ibits[x], ncpbytes); \ if (error != 0) \ - goto done_nosellock; \ + goto done; \ } \ } while (0) getbits(fd_in, 0); @@ -737,7 +768,7 @@ atv = *tvp; if (itimerfix(&atv)) { error = EINVAL; - goto done_nosellock; + goto done; } getmicrouptime(&rtv); timevaladd(&atv, &rtv); @@ -746,58 +777,31 @@ atv.tv_usec = 0; } timo = 0; - TAILQ_INIT(&td->td_selq); - mtx_lock(&sellock); -retry: - ncoll = nselcoll; - thread_lock(td); - td->td_flags |= TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - - error = selscan(td, ibits, obits, nd); - mtx_lock(&sellock); - if (error || td->td_retval[0]) - goto done; - if (atv.tv_sec || atv.tv_usec) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) - goto done; - ttv = atv; - timevalsub(&ttv, &rtv); - timo = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); + seltdinit(td); + /* Iterate until the timeout expires or descriptors become ready. */ + for (;;) { + error = selscan(td, ibits, obits, nd); + if (error || td->td_retval[0] != 0) + break; + if (atv.tv_sec || atv.tv_usec) { + getmicrouptime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) + break; + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); + } + error = seltdwait(td, timo); + if (error) + break; + error = selrescan(td, ibits, obits); + if (error || td->td_retval[0] != 0) + break; } - - /* - * An event of interest may occur while we do not hold - * sellock, so check TDF_SELECT and the number of - * collisions and rescan the file descriptors if - * necessary. - */ - thread_lock(td); - if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { - thread_unlock(td); - goto retry; - } - thread_unlock(td); - - if (timo > 0) - error = cv_timedwait_sig(&selwait, &sellock, timo); - else - error = cv_wait_sig(&selwait, &sellock); - - if (error == 0) - goto retry; + seltdclear(td); done: - clear_selinfo_list(td); - thread_lock(td); - td->td_flags &= ~TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - -done_nosellock: /* select is not restarted after signals... */ if (error == ERESTART) error = EINTR; @@ -820,7 +824,61 @@ return (error); } +/* + * Traverse the list of fds attached to this thread's seltd and check for + * completion. + */ static int +selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits) +{ + struct seltd *stp; + struct selfd *sfp; + struct selfd *sfn; + struct selinfo *si; + struct file *fp; + int msk, fd; + int n = 0; + /* Note: backend also returns POLLHUP/POLLERR if appropriate. */ + static int flag[3] = { POLLRDNORM, POLLWRNORM, POLLRDBAND }; + struct filedesc *fdp = td->td_proc->p_fd; + + stp = td->td_sel; + FILEDESC_SLOCK(fdp); + STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) { + fd = (int)(uintptr_t)sfp->sf_cookie; + si = sfp->sf_si; + selfdfree(stp, sfp); + /* If the selinfo wasn't cleared the event didn't fire. */ + if (si != NULL) + continue; + if ((fp = fget_locked(fdp, fd)) == NULL) { + FILEDESC_SUNLOCK(fdp); + return (EBADF); + } + for (msk = 0; msk < 3; msk++) { + if (ibits[msk] == NULL) + continue; + if ((ibits[msk][fd/NFDBITS] & + ((fd_mask) 1 << (fd % NFDBITS))) == 0) + continue; + if (fo_poll(fp, flag[msk], td->td_ucred, td)) { + obits[msk][(fd)/NFDBITS] |= + ((fd_mask)1 << ((fd) % NFDBITS)); + n++; + } + } + } + FILEDESC_SUNLOCK(fdp); + stp->st_flags = 0; + td->td_retval[0] = n; + return (0); +} + +/* + * Perform the initial filedescriptor scan and register ourselves with + * each selinfo. + */ +static int selscan(td, ibits, obits, nfd) struct thread *td; fd_mask **ibits, **obits; @@ -848,6 +906,7 @@ FILEDESC_SUNLOCK(fdp); return (EBADF); } + selfdalloc(td, (void *)(uintptr_t)fd); if (fo_poll(fp, flag[msk], td->td_ucred, td)) { obits[msk][(fd)/NFDBITS] |= @@ -878,7 +937,7 @@ struct pollfd smallbits[32]; struct timeval atv, rtv, ttv; int error = 0, timo; - u_int ncoll, nfds; + u_int nfds; size_t ni; nfds = uap->nfds; @@ -890,14 +949,13 @@ * least enough for the current limits. We want to be reasonably * safe, but not overly restrictive. */ - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if ((nfds > lim_cur(td->td_proc, RLIMIT_NOFILE)) && (nfds > FD_SETSIZE)) { - PROC_UNLOCK(td->td_proc); - error = EINVAL; - goto done2; + PROC_RUNLOCK(td->td_proc); + return (EINVAL); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); ni = nfds * sizeof(struct pollfd); if (ni > sizeof(smallbits)) bits = malloc(ni, M_TEMP, M_WAITOK); @@ -905,13 +963,13 @@ bits = smallbits; error = copyin(uap->fds, bits, ni); if (error) - goto done_nosellock; + goto done; if (uap->timeout != INFTIM) { atv.tv_sec = uap->timeout / 1000; atv.tv_usec = (uap->timeout % 1000) * 1000; if (itimerfix(&atv)) { error = EINVAL; - goto done_nosellock; + goto done; } getmicrouptime(&rtv); timevaladd(&atv, &rtv); @@ -920,56 +978,31 @@ atv.tv_usec = 0; } timo = 0; - TAILQ_INIT(&td->td_selq); - mtx_lock(&sellock); -retry: - ncoll = nselcoll; - thread_lock(td); - td->td_flags |= TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - - error = pollscan(td, bits, nfds); - mtx_lock(&sellock); - if (error || td->td_retval[0]) - goto done; - if (atv.tv_sec || atv.tv_usec) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) - goto done; - ttv = atv; - timevalsub(&ttv, &rtv); - timo = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); + seltdinit(td); + /* Iterate until the timeout expires or descriptors become ready. */ + for (;;) { + error = pollscan(td, bits, nfds); + if (error || td->td_retval[0] != 0) + break; + if (atv.tv_sec || atv.tv_usec) { + getmicrouptime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) + break; + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); + } + error = seltdwait(td, timo); + if (error) + break; + error = pollrescan(td); + if (error || td->td_retval[0] != 0) + break; } - /* - * An event of interest may occur while we do not hold - * sellock, so check TDF_SELECT and the number of collisions - * and rescan the file descriptors if necessary. - */ - thread_lock(td); - if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { - thread_unlock(td); - goto retry; - } - thread_unlock(td); - - if (timo > 0) - error = cv_timedwait_sig(&selwait, &sellock, timo); - else - error = cv_wait_sig(&selwait, &sellock); - - if (error == 0) - goto retry; + seltdclear(td); done: - clear_selinfo_list(td); - thread_lock(td); - td->td_flags &= ~TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - -done_nosellock: /* poll is not restarted after signals... */ if (error == ERESTART) error = EINTR; @@ -983,17 +1016,60 @@ out: if (ni > sizeof(smallbits)) free(bits, M_TEMP); -done2: return (error); } static int +pollrescan(struct thread *td) +{ + struct seltd *stp; + struct selfd *sfp; + struct selfd *sfn; + struct selinfo *si; + struct filedesc *fdp; + struct file *fp; + struct pollfd *fd; + int n; + + n = 0; + fdp = td->td_proc->p_fd; + stp = td->td_sel; + FILEDESC_SLOCK(fdp); + STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) { + fd = (struct pollfd *)sfp->sf_cookie; + si = sfp->sf_si; + selfdfree(stp, sfp); + /* If the selinfo wasn't cleared the event didn't fire. */ + if (si != NULL) + continue; + fp = fdp->fd_ofiles[fd->fd]; + if (fp == NULL) { + fd->revents = POLLNVAL; + n++; + continue; + } + /* + * Note: backend also returns POLLHUP and + * POLLERR if appropriate. + */ + fd->revents = fo_poll(fp, fd->events, td->td_ucred, td); + if (fd->revents != 0) + n++; + } + FILEDESC_SUNLOCK(fdp); + stp->st_flags = 0; + td->td_retval[0] = n; + return (0); +} + + +static int pollscan(td, fds, nfd) struct thread *td; struct pollfd *fds; u_int nfd; { - register struct filedesc *fdp = td->td_proc->p_fd; + struct filedesc *fdp = td->td_proc->p_fd; int i; struct file *fp; int n = 0; @@ -1015,6 +1091,7 @@ * Note: backend also returns POLLHUP and * POLLERR if appropriate. */ + selfdalloc(td, fds); fds->revents = fo_poll(fp, fds->events, td->td_ucred, td); if (fds->revents != 0) @@ -1048,23 +1125,90 @@ } /* - * Remove the references to the thread from all of the objects we were - * polling. - * - * This code assumes that the underlying owner of the selinfo structure will - * hold sellock before it changes it, and that it will unlink itself from our - * list if it goes away. + * XXX This was created specifically to support netncp and netsmb. This + * allows the caller to specify a socket to wait for events on. It returns + * 0 if any events matched and an error otherwise. There is no way to + * determine which events fired. + */ +int +selsocket(struct socket *so, int events, struct timeval *tvp, struct thread *td) +{ + struct timeval atv, rtv, ttv; + int error, timo; + + if (tvp != NULL) { + atv = *tvp; + if (itimerfix(&atv)) + return (EINVAL); + getmicrouptime(&rtv); + timevaladd(&atv, &rtv); + } else { + atv.tv_sec = 0; + atv.tv_usec = 0; + } + + timo = 0; + seltdinit(td); + /* + * Iterate until the timeout expires or the socket becomes ready. + */ + for (;;) { + selfdalloc(td, NULL); + error = sopoll(so, events, NULL, td); + /* error here is actually the ready events. */ + if (error) + return (0); + if (atv.tv_sec || atv.tv_usec) { + getmicrouptime(&rtv); + if (timevalcmp(&rtv, &atv, >=)) { + seltdclear(td); + return (EWOULDBLOCK); + } + ttv = atv; + timevalsub(&ttv, &rtv); + timo = ttv.tv_sec > 24 * 60 * 60 ? + 24 * 60 * 60 * hz : tvtohz(&ttv); + } + error = seltdwait(td, timo); + seltdclear(td); + if (error) + break; + } + /* XXX Duplicates ncp/smb behavior. */ + if (error == ERESTART) + error = 0; + return (error); +} + +/* + * Preallocate two selfds associated with 'cookie'. Some fo_poll routines + * have two select sets, one for read and another for write. */ -void -clear_selinfo_list(td) - struct thread *td; +static void +selfdalloc(struct thread *td, void *cookie) { - struct selinfo *si; + struct seltd *stp; + + stp = td->td_sel; + if (stp->st_free1 == NULL) + stp->st_free1 = uma_zalloc(selfd_zone, M_WAITOK|M_ZERO); + stp->st_free1->sf_td = stp; + stp->st_free1->sf_cookie = cookie; + if (stp->st_free2 == NULL) + stp->st_free2 = uma_zalloc(selfd_zone, M_WAITOK|M_ZERO); + stp->st_free2->sf_td = stp; + stp->st_free2->sf_cookie = cookie; +} - mtx_assert(&sellock, MA_OWNED); - TAILQ_FOREACH(si, &td->td_selq, si_thrlist) - si->si_thread = NULL; - TAILQ_INIT(&td->td_selq); +static void +selfdfree(struct seltd *stp, struct selfd *sfp) +{ + STAILQ_REMOVE(&stp->st_selq, sfp, selfd, sf_link); + mtx_lock(sfp->sf_mtx); + if (sfp->sf_si) + TAILQ_REMOVE(&sfp->sf_si->si_tdlist, sfp, sf_threads); + mtx_unlock(sfp->sf_mtx); + uma_zfree(selfd_zone, sfp); } /* @@ -1075,26 +1219,46 @@ struct thread *selector; struct selinfo *sip; { + struct selfd *sfp; + struct seltd *stp; + struct mtx *mtxp; - mtx_lock(&sellock); + stp = selector->td_sel; + /* + * Don't record when doing a rescan. + */ + if (stp->st_flags & SELTD_RESCAN) + return; + /* + * Grab one of the preallocated descriptors. + */ + sfp = NULL; + if ((sfp = stp->st_free1) != NULL) + stp->st_free1 = NULL; + else if ((sfp = stp->st_free2) != NULL) + stp->st_free2 = NULL; + else + panic("selrecord: No free selfd on selq"); + mtxp = mtx_pool_find(mtxpool_sleep, sip); + /* + * Initialize the sfp and queue it in the thread. + */ + sfp->sf_si = sip; + sfp->sf_mtx = mtxp; + STAILQ_INSERT_TAIL(&stp->st_selq, sfp, sf_link); /* - * If the selinfo's thread pointer is NULL then take ownership of it. - * - * If the thread pointer is not NULL and it points to another - * thread, then we have a collision. - * - * If the thread pointer is not NULL and points back to us then leave - * it alone as we've already added pointed it at us and added it to - * our list. + * Now that we've locked the sip, check for initialization. */ - if (sip->si_thread == NULL) { - sip->si_thread = selector; - TAILQ_INSERT_TAIL(&selector->td_selq, sip, si_thrlist); - } else if (sip->si_thread != selector) { - sip->si_flags |= SI_COLL; + mtx_lock(mtxp); + if (sip->si_mtx == NULL) { + sip->si_mtx = mtxp; + TAILQ_INIT(&sip->si_tdlist); } - - mtx_unlock(&sellock); + /* + * Add this thread to the list of selfds listening on this selinfo. + */ + TAILQ_INSERT_TAIL(&sip->si_tdlist, sfp, sf_threads); + mtx_unlock(sip->si_mtx); } /* Wake up a selecting thread. */ @@ -1122,36 +1286,115 @@ struct selinfo *sip; int pri; { - struct thread *td; + struct selfd *sfp; + struct selfd *sfn; + struct seltd *stp; + + /* If it's not initialized there can't be any waiters. */ + if (sip->si_mtx == NULL) + return; + /* + * Locking the selinfo locks all selfds associated with it. + */ + mtx_lock(sip->si_mtx); + TAILQ_FOREACH_SAFE(sfp, &sip->si_tdlist, sf_threads, sfn) { + /* + * Once we remove this sfp from the list and clear the + * sf_si seltdclear will know to ignore this si. + */ + TAILQ_REMOVE(&sip->si_tdlist, sfp, sf_threads); + sfp->sf_si = NULL; + stp = sfp->sf_td; + mtx_lock(&stp->st_mtx); + stp->st_flags |= SELTD_PENDING; + cv_broadcastpri(&stp->st_wait, pri); + mtx_unlock(&stp->st_mtx); + } + mtx_unlock(sip->si_mtx); +} + +static void +seltdinit(struct thread *td) +{ + struct seltd *stp; + + if ((stp = td->td_sel) != NULL) + goto out; + td->td_sel = stp = malloc(sizeof(*stp), M_SELECT, M_WAITOK|M_ZERO); + mtx_init(&stp->st_mtx, "sellck", NULL, MTX_DEF); + cv_init(&stp->st_wait, "select"); +out: + stp->st_flags = 0; + STAILQ_INIT(&stp->st_selq); +} + +static int +seltdwait(struct thread *td, int timo) +{ + struct seltd *stp; + int error; - mtx_lock(&sellock); - td = sip->si_thread; - if ((sip->si_flags & SI_COLL) != 0) { - nselcoll++; - sip->si_flags &= ~SI_COLL; - cv_broadcastpri(&selwait, pri); + stp = td->td_sel; + /* + * An event of interest may occur while we do not hold the seltd + * locked so check the pending flag before we sleep. + */ + mtx_lock(&stp->st_mtx); + /* + * Any further calls to selrecord will be a rescan. + */ + stp->st_flags |= SELTD_RESCAN; + if (stp->st_flags & SELTD_PENDING) { + mtx_unlock(&stp->st_mtx); + return (0); } - if (td == NULL) { - mtx_unlock(&sellock); + if (timo > 0) + error = cv_timedwait_sig(&stp->st_wait, &stp->st_mtx, timo); + else + error = cv_wait_sig(&stp->st_wait, &stp->st_mtx); + mtx_unlock(&stp->st_mtx); + + return (error); +} + +void +seltdfini(struct thread *td) +{ + struct seltd *stp; + + stp = td->td_sel; + if (stp == NULL) return; - } - TAILQ_REMOVE(&td->td_selq, sip, si_thrlist); - sip->si_thread = NULL; - thread_lock(td); - td->td_flags &= ~TDF_SELECT; - thread_unlock(td); - sleepq_remove(td, &selwait); - mtx_unlock(&sellock); + if (stp->st_free1) + uma_zfree(selfd_zone, stp->st_free1); + if (stp->st_free2) + uma_zfree(selfd_zone, stp->st_free2); + td->td_sel = NULL; + free(stp, M_SELECT); +} + +/* + * Remove the references to the thread from all of the objects we were + * polling. + */ +static void +seltdclear(struct thread *td) +{ + struct seltd *stp; + struct selfd *sfp; + struct selfd *sfn; + + stp = td->td_sel; + STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) + selfdfree(stp, sfp); + stp->st_flags = 0; } static void selectinit(void *); -SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, selectinit, NULL) - -/* ARGSUSED*/ +SYSINIT(select, SI_SUB_SYSCALLS, SI_ORDER_ANY, selectinit, NULL); static void -selectinit(dummy) - void *dummy; +selectinit(void *dummy __unused) { - cv_init(&selwait, "select"); - mtx_init(&sellock, "sellck", NULL, MTX_DEF); + selfd_zone = uma_zcreate("selfd", sizeof(struct selfd), NULL, NULL, + NULL, NULL, UMA_ALIGN_PTR, 0); } --- //depot/vendor/freebsd/src/sys/kern/sys_pipe.c 2007/05/27 17:37:19 +++ //depot/user/kris/contention/sys/kern/sys_pipe.c 2007/08/16 16:17:38 @@ -154,7 +154,7 @@ .fo_kqfilter = pipe_kqfilter, .fo_stat = pipe_stat, .fo_close = pipe_close, - .fo_flags = DFLAG_PASSABLE + .fo_flags = DFLAG_PASSABLE | DFLAG_MPSAFE }; static void filt_pipedetach(struct knote *kn); @@ -363,12 +363,7 @@ * to avoid races against processes which manage to dup() the read * side while we are blocked trying to allocate the write side. */ - FILE_LOCK(rf); - rf->f_flag = FREAD | FWRITE; - rf->f_type = DTYPE_PIPE; - rf->f_data = rpipe; - rf->f_ops = &pipeops; - FILE_UNLOCK(rf); + finit(rf, FREAD | FWRITE, DTYPE_PIPE, rpipe, &pipeops); error = falloc(td, &wf, &fd); if (error) { fdclose(fdp, rf, td->td_retval[0], td); @@ -378,12 +373,7 @@ return (error); } /* An extra reference on `wf' has been held for us by falloc(). */ - FILE_LOCK(wf); - wf->f_flag = FREAD | FWRITE; - wf->f_type = DTYPE_PIPE; - wf->f_data = wpipe; - wf->f_ops = &pipeops; - FILE_UNLOCK(wf); + finit(wf, FREAD | FWRITE, DTYPE_PIPE, wpipe, &pipeops); fdrop(wf, td); td->td_retval[1] = fd; fdrop(rf, td); @@ -524,8 +514,9 @@ PIPE_LOCK_ASSERT(cpipe, MA_OWNED); if (cpipe->pipe_state & PIPE_SEL) { - cpipe->pipe_state &= ~PIPE_SEL; selwakeuppri(&cpipe->pipe_sel, PSOCK); + if (!SEL_WAITING(&cpipe->pipe_sel)) + cpipe->pipe_state &= ~PIPE_SEL; } if ((cpipe->pipe_state & PIPE_ASYNC) && cpipe->pipe_sigio) pgsigio(&cpipe->pipe_sigio, SIGIO, 0); @@ -1350,12 +1341,14 @@ if (revents == 0) { if (events & (POLLIN | POLLRDNORM)) { selrecord(td, &rpipe->pipe_sel); - rpipe->pipe_state |= PIPE_SEL; + if (SEL_WAITING(&rpipe->pipe_sel)) + rpipe->pipe_state |= PIPE_SEL; } if (events & (POLLOUT | POLLWRNORM)) { selrecord(td, &wpipe->pipe_sel); - wpipe->pipe_state |= PIPE_SEL; + if (SEL_WAITING(&wpipe->pipe_sel)) + wpipe->pipe_state |= PIPE_SEL; } } #ifdef MAC --- //depot/vendor/freebsd/src/sys/kern/sys_process.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/kern/sys_process.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -103,7 +104,7 @@ #define PROC_ACTION(action) do { \ int error; \ \ - PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); \ + PROC_LOCK_ASSERT(td->td_proc, RA_LOCKED); \ if ((td->td_proc->p_sflag & PS_INMEM) == 0) \ error = EIO; \ else \ @@ -514,7 +515,7 @@ write = 0; if (req == PT_TRACE_ME) { p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); } else { if (pid <= PID_MAX) { if ((p = pfind(pid)) == NULL) { @@ -526,7 +527,7 @@ /* this is slow, should be optimized */ sx_slock(&allproc_lock); FOREACH_PROC_IN_SYSTEM(p) { - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); FOREACH_THREAD_IN_PROC(p, td2) { if (td2->td_tid == pid) @@ -535,7 +536,7 @@ PROC_SUNLOCK(p); if (td2 != NULL) break; /* proc lock held */ - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } sx_sunlock(&allproc_lock); if (p == NULL) { @@ -752,17 +753,17 @@ if (p->p_oppid != p->p_pptr->p_pid) { struct proc *pp; - PROC_LOCK(p->p_pptr); + PROC_WLOCK(p->p_pptr); sigqueue_take(p->p_ksi); - PROC_UNLOCK(p->p_pptr); + PROC_WUNLOCK(p->p_pptr); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); pp = pfind(p->p_oppid); if (pp == NULL) pp = initproc; else - PROC_UNLOCK(pp); - PROC_LOCK(p); + PROC_WUNLOCK(pp); + PROC_WLOCK(p); proc_reparent(p, pp); if (pp == initproc) p->p_sigparent = SIGCHLD; @@ -822,7 +823,7 @@ /* FALLTHROUGH */ case PT_READ_I: case PT_READ_D: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); tmp = 0; /* write = 0 set above */ iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp; @@ -850,7 +851,7 @@ } if (!write) td->td_retval[0] = tmp; - PROC_LOCK(p); + PROC_WLOCK(p); break; case PT_IO: @@ -892,7 +893,7 @@ error = EINVAL; goto out; } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = proc_rwmem(p, &uio); #ifdef COMPAT_IA32 if (wrap32) @@ -900,7 +901,7 @@ else #endif piod->piod_len -= uio.uio_resid; - PROC_LOCK(p); + PROC_WLOCK(p); break; case PT_KILL: @@ -967,10 +968,10 @@ break; } num = imin(p->p_numthreads, data); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); buf = malloc(num * sizeof(lwpid_t), M_TEMP, M_WAITOK); tmp = 0; - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); FOREACH_THREAD_IN_PROC(p, td2) { if (tmp >= num) @@ -978,20 +979,20 @@ buf[tmp++] = td2->td_tid; } PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = copyout(buf, addr, tmp * sizeof(lwpid_t)); free(buf, M_TEMP); if (!error) td->td_retval[0] = tmp; - PROC_LOCK(p); + PROC_WLOCK(p); break; default: #ifdef __HAVE_PTRACE_MACHDEP if (req >= PT_FIRSTMACH) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); error = cpu_ptrace(td2, req, addr, data); - PROC_LOCK(p); + PROC_WLOCK(p); } else #endif /* Unknown request. */ @@ -1003,7 +1004,7 @@ /* Drop our hold on this process now that the request has completed. */ _PRELE(p); fail: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (proctree_locked) sx_xunlock(&proctree_lock); return (error); @@ -1020,13 +1021,13 @@ stopevent(struct proc *p, unsigned int event, unsigned int val) { - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); p->p_step = 1; do { p->p_xstat = val; p->p_xthread = NULL; p->p_stype = event; /* Which event caused the stop? */ wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */ - msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0); + rw_sleep(&p->p_step, &p->p_rwlock, PWAIT, "stopevent", 0); } while (p->p_step); } --- //depot/vendor/freebsd/src/sys/kern/sys_socket.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/kern/sys_socket.c 2007/08/31 20:34:30 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,7 @@ .fo_kqfilter = soo_kqfilter, .fo_stat = soo_stat, .fo_close = soo_close, - .fo_flags = DFLAG_PASSABLE + .fo_flags = DFLAG_PASSABLE | DFLAG_MPSAFE }; /* ARGSUSED */ @@ -102,9 +103,9 @@ #endif error = sosend(so, 0, uio, 0, 0, 0, uio->uio_td); if (error == EPIPE && (so->so_options & SO_NOSIGPIPE) == 0) { - PROC_LOCK(uio->uio_td->td_proc); + PROC_WLOCK(uio->uio_td->td_proc); psignal(uio->uio_td->td_proc, SIGPIPE); - PROC_UNLOCK(uio->uio_td->td_proc); + PROC_WUNLOCK(uio->uio_td->td_proc); } return (error); } --- //depot/vendor/freebsd/src/sys/kern/sysv_shm.c 2007/03/05 13:12:17 +++ //depot/user/kris/contention/sys/kern/sysv_shm.c 2007/08/31 20:34:30 @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include @@ -414,10 +415,10 @@ * This is just a hint to vm_map_find() about where to * put it. */ - PROC_LOCK(p); + PROC_RLOCK(p); attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr + lim_max(p, RLIMIT_DATA)); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } vm_object_reference(shmseg->u.shm_internal); --- //depot/vendor/freebsd/src/sys/kern/tty.c 2007/07/20 09:45:18 +++ //depot/user/kris/contention/sys/kern/tty.c 2007/08/31 20:34:30 @@ -82,6 +82,7 @@ #include #include #include +#include #include #if defined(COMPAT_43TTY) #include @@ -847,12 +848,12 @@ case TIOCSLTC: #endif sx_slock(&proctree_lock); - PROC_LOCK(p); + PROC_RLOCK(p); while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) && !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) && !SIGISMEMBER(td->td_sigmask, SIGTTOU)) { pgrp = p->p_pgrp; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); if (pgrp->pg_jobc == 0) { sx_sunlock(&proctree_lock); return (EIO); @@ -866,9 +867,9 @@ if (error) return (error); sx_slock(&proctree_lock); - PROC_LOCK(p); + PROC_RLOCK(p); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sx_sunlock(&proctree_lock); break; } @@ -1202,9 +1203,9 @@ ttyref(tp); /* ttyrel(): kern_proc.c:pgdelete() */ p->p_session->s_ttyp = tp; SESS_UNLOCK(p->p_session); - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_CONTROLT; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); sx_sunlock(&proctree_lock); break; case TIOCSPGRP: { /* set pgrp of tty */ @@ -1657,9 +1658,9 @@ struct proc *p; p = tp->t_session->s_leader; - PROC_LOCK(p); + PROC_WLOCK(p); psignal(p, SIGHUP); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } sx_sunlock(&proctree_lock); } @@ -1746,16 +1747,16 @@ if (isbackground(p, tp)) { splx(s); sx_slock(&proctree_lock); - PROC_LOCK(p); + PROC_RLOCK(p); if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) || SIGISMEMBER(td->td_sigmask, SIGTTIN) || (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sx_sunlock(&proctree_lock); return (EIO); } pg = p->p_pgrp; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); PGRP_LOCK(pg); sx_sunlock(&proctree_lock); pgsignal(pg, SIGTTIN, 1); @@ -2006,9 +2007,10 @@ SIGEMPTYSET(oldmask); s = spltty(); if (wait) { - PROC_LOCK(p); + /* XXXPJD: Locking needed? */ + PROC_RLOCK(p); oldmask = td->td_siglist; - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) while (tp->t_outq.c_cc > hiwat) { @@ -2019,13 +2021,13 @@ splx(s); return (0); } - PROC_LOCK(p); + PROC_WLOCK(p); if (!SIGSETEQ(td->td_siglist, oldmask)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); splx(s); return (0); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); SET(tp->t_state, TS_SO_OLOWAT); tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz); } @@ -2078,18 +2080,18 @@ * Hang the process if it's in the background. */ sx_slock(&proctree_lock); - PROC_LOCK(p); + PROC_RLOCK(p); if (isbackground(p, tp) && ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) && !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) && !SIGISMEMBER(td->td_sigmask, SIGTTOU)) { if (p->p_pgrp->pg_jobc == 0) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sx_sunlock(&proctree_lock); error = EIO; goto out; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); PGRP_LOCK(p->p_pgrp); sx_sunlock(&proctree_lock); pgsignal(p->p_pgrp, SIGTTOU, 1); @@ -2099,7 +2101,7 @@ goto out; goto loop; } else { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); sx_sunlock(&proctree_lock); } /* @@ -2616,12 +2618,12 @@ else rss = pgtok(vmspace_resident_count(pick->p_vmspace)); PROC_SUNLOCK(pick); - PROC_LOCK(pick); + PROC_WLOCK(pick); PGRP_UNLOCK(tp->t_pgrp); rufetchcalc(pick, &ru, &utime, &stime); pid = pick->p_pid; bcopy(pick->p_comm, comm, sizeof(comm)); - PROC_UNLOCK(pick); + PROC_WUNLOCK(pick); /* Print command, pid, state, utime, stime, %cpu, and rss. */ ttyprintf(tp, --- //depot/vendor/freebsd/src/sys/kern/uipc_mqueue.c 2007/06/12 00:18:44 +++ //depot/user/kris/contention/sys/kern/uipc_mqueue.c 2007/08/31 20:34:30 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -1721,10 +1722,10 @@ nt = mq->mq_notifier; if (nt->nt_sigev.sigev_notify != SIGEV_NONE) { p = nt->nt_proc; - PROC_LOCK(p); + PROC_WLOCK(p); if (!KSI_ONQ(&nt->nt_ksi)) psignal_event(p, &nt->nt_sigev, &nt->nt_ksi); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } mq->mq_notifier = NULL; } @@ -1890,7 +1891,7 @@ struct mqueue_notifier *nt; mtx_assert(&mq->mq_mutex, MA_OWNED); - PROC_LOCK(p); + PROC_WLOCK(p); nt = notifier_search(p, fd); if (nt != NULL) { if (mq->mq_notifier == nt) @@ -1898,7 +1899,7 @@ sigqueue_take(&nt->nt_ksi); notifier_delete(p, nt); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } /* @@ -1999,12 +2000,8 @@ mqnode_addref(pn); sx_xunlock(&mqfs_data.mi_lock); - FILE_LOCK(fp); - fp->f_flag = (flags & (FREAD | FWRITE | O_NONBLOCK)); - fp->f_type = DTYPE_MQUEUE; - fp->f_data = pn; - fp->f_ops = &mqueueops; - FILE_UNLOCK(fp); + finit(fp, flags & (FREAD | FWRITE | O_NONBLOCK), DTYPE_MQUEUE, pn, + &mqueueops); FILEDESC_XLOCK(fdp); if (fdp->fd_ofiles[fd] == fp) @@ -2097,6 +2094,7 @@ struct mqueue *mq; struct file *fp; struct mq_attr attr, oattr; + u_int oflag, flag; int error; if (uap->attr) { @@ -2112,13 +2110,15 @@ oattr.mq_maxmsg = mq->mq_maxmsg; oattr.mq_msgsize = mq->mq_msgsize; oattr.mq_curmsgs = mq->mq_curmsgs; - FILE_LOCK(fp); - oattr.mq_flags = (O_NONBLOCK & fp->f_flag); if (uap->attr) { - fp->f_flag &= ~O_NONBLOCK; - fp->f_flag |= (attr.mq_flags & O_NONBLOCK); - } - FILE_UNLOCK(fp); + do { + oflag = flag = fp->f_flag; + flag &= ~O_NONBLOCK; + flag |= (attr.mq_flags & O_NONBLOCK); + } while (atomic_cmpset_int(&fp->f_flag, oflag, flag) == 0); + } else + oflag = fp->f_flag; + oattr.mq_flags = (O_NONBLOCK & oflag); fdrop(fp, td); if (uap->oattr) error = copyout(&oattr, uap->oattr, sizeof(oattr)); @@ -2202,11 +2202,11 @@ if (mq->mq_notifier != NULL) { error = EBUSY; } else { - PROC_LOCK(p); + PROC_WLOCK(p); nt = notifier_search(p, uap->mqd); if (nt == NULL) { if (newnt == NULL) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); mtx_unlock(&mq->mq_mutex); newnt = notifier_alloc(); goto again; @@ -2231,7 +2231,7 @@ } nt->nt_sigev = ev; mq->mq_notifier = nt; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * if there is no receivers and message queue * is not empty, we should send notification --- //depot/vendor/freebsd/src/sys/kern/uipc_sockbuf.c 2007/05/31 11:53:40 +++ //depot/user/kris/contention/sys/kern/uipc_sockbuf.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -176,7 +177,8 @@ SOCKBUF_LOCK_ASSERT(sb); selwakeuppri(&sb->sb_sel, PSOCK); - sb->sb_flags &= ~SB_SEL; + if (!SEL_WAITING(&sb->sb_sel)) + sb->sb_flags &= ~SB_SEL; if (sb->sb_flags & SB_WAIT) { sb->sb_flags &= ~SB_WAIT; wakeup(&sb->sb_cc); @@ -288,9 +290,9 @@ if (cc > sb_max_adj) return (0); if (td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); sbsize_limit = lim_cur(td->td_proc, RLIMIT_SBSIZE); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } else sbsize_limit = RLIM_INFINITY; if (!chgsbsize(so->so_cred->cr_uidinfo, &sb->sb_hiwat, cc, --- //depot/vendor/freebsd/src/sys/kern/uipc_socket.c 2007/06/04 18:28:45 +++ //depot/user/kris/contention/sys/kern/uipc_socket.c 2007/07/27 14:28:37 @@ -2489,12 +2489,14 @@ (POLLIN | POLLINIGNEOF | POLLPRI | POLLRDNORM | POLLRDBAND)) { selrecord(td, &so->so_rcv.sb_sel); - so->so_rcv.sb_flags |= SB_SEL; + if (SEL_WAITING(&so->so_rcv.sb_sel)) + so->so_rcv.sb_flags |= SB_SEL; } if (events & (POLLOUT | POLLWRNORM)) { selrecord(td, &so->so_snd.sb_sel); - so->so_snd.sb_flags |= SB_SEL; + if (SEL_WAITING(&so->so_snd.sb_sel)) + so->so_snd.sb_flags |= SB_SEL; } } --- //depot/vendor/freebsd/src/sys/kern/uipc_syscalls.c 2007/08/27 05:22:40 +++ //depot/user/kris/contention/sys/kern/uipc_syscalls.c 2007/08/31 20:34:30 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -180,12 +181,7 @@ if (error) { fdclose(fdp, fp, fd, td); } else { - FILE_LOCK(fp); - fp->f_data = so; /* already has ref count */ - fp->f_flag = FREAD|FWRITE; - fp->f_type = DTYPE_SOCKET; - fp->f_ops = &socketops; - FILE_UNLOCK(fp); + finit(fp, FREAD | FWRITE, DTYPE_SOCKET, so, &socketops); td->td_retval[0] = fd; } fdrop(fp, td); @@ -423,12 +419,7 @@ if (pgid != 0) fsetown(pgid, &so->so_sigio); - FILE_LOCK(nfp); - nfp->f_data = so; /* nfp has ref count from falloc */ - nfp->f_flag = fflag; - nfp->f_type = DTYPE_SOCKET; - nfp->f_ops = &socketops; - FILE_UNLOCK(nfp); + finit(nfp, fflag, DTYPE_SOCKET, so, &socketops); /* Sync socket nonblocking/async state with file flags */ tmp = fflag & FNONBLOCK; (void) fo_ioctl(nfp, FIONBIO, &tmp, td->td_ucred, td); @@ -640,16 +631,8 @@ if (error) goto free4; } - FILE_LOCK(fp1); - fp1->f_flag = FREAD|FWRITE; - fp1->f_type = DTYPE_SOCKET; - fp1->f_ops = &socketops; - FILE_UNLOCK(fp1); - FILE_LOCK(fp2); - fp2->f_flag = FREAD|FWRITE; - fp2->f_type = DTYPE_SOCKET; - fp2->f_ops = &socketops; - FILE_UNLOCK(fp2); + finit(fp1, FREAD | FWRITE, DTYPE_SOCKET, fp1->f_data, &socketops); + finit(fp2, FREAD | FWRITE, DTYPE_SOCKET, fp2->f_data, &socketops); so1 = so2 = NULL; error = copyout(sv, uap->rsv, 2 * sizeof (int)); if (error) @@ -794,9 +777,9 @@ /* Generation of SIGPIPE can be controlled per socket */ if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && !(flags & MSG_NOSIGNAL)) { - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); psignal(td->td_proc, SIGPIPE); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } if (error == 0) @@ -2270,12 +2253,7 @@ so->so_qstate &= ~SQ_COMP; so->so_head = NULL; ACCEPT_UNLOCK(); - FILE_LOCK(nfp); - nfp->f_data = so; - nfp->f_flag = fflag; - nfp->f_type = DTYPE_SOCKET; - nfp->f_ops = &socketops; - FILE_UNLOCK(nfp); + finit(nfp, fflag, DTYPE_SOCKET, so, &socketops); error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name); if (error) goto noconnection; @@ -2378,9 +2356,9 @@ /* Generation of SIGPIPE can be controlled per socket. */ if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && !(uap->flags & MSG_NOSIGNAL)) { - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); psignal(td->td_proc, SIGPIPE); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } if (error == 0) @@ -2485,9 +2463,9 @@ /* Generation of SIGPIPE can be controlled per socket */ if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) && !(uap->flags & MSG_NOSIGNAL)) { - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); psignal(td->td_proc, SIGPIPE); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } } if (error == 0) --- //depot/vendor/freebsd/src/sys/kern/uipc_usrreq.c 2007/07/26 17:02:32 +++ //depot/user/kris/contention/sys/kern/uipc_usrreq.c 2007/08/16 16:17:38 @@ -233,10 +233,11 @@ static void unp_drop(struct unpcb *, int); static void unp_gc(__unused void *, int); static void unp_scan(struct mbuf *, void (*)(struct file *)); -static void unp_mark(struct file *); static void unp_discard(struct file *); static void unp_freerights(struct file **, int); static int unp_internalize(struct mbuf **, struct thread *); +static void unp_internalize_fp(struct file *); +static void unp_externalize_fp(struct file *); static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *); /* @@ -586,9 +587,9 @@ unp_drop(ref, ECONNRESET); UNP_PCB_UNLOCK(ref); } + local_unp_rights = unp_rights; UNP_GLOBAL_WUNLOCK(); unp->unp_socket->so_pcb = NULL; - local_unp_rights = unp_rights; saved_unp_addr = unp->unp_addr; unp->unp_addr = NULL; unp->unp_refcount--; @@ -1600,10 +1601,7 @@ panic("unp_externalize fdalloc failed"); fp = *rp++; td->td_proc->p_fd->fd_ofiles[f] = fp; - FILE_LOCK(fp); - fp->f_msgcount--; - FILE_UNLOCK(fp); - unp_rights--; + unp_externalize_fp(fp); *fdp++ = f; } FILEDESC_XUNLOCK(td->td_proc->p_fd); @@ -1765,11 +1763,8 @@ for (i = 0; i < oldfds; i++) { fp = fdescp->fd_ofiles[*fdp++]; *rp++ = fp; - FILE_LOCK(fp); - fp->f_count++; - fp->f_msgcount++; - FILE_UNLOCK(fp); - unp_rights++; + fhold(fp); + unp_internalize_fp(fp); } FILEDESC_SUNLOCK(fdescp); break; @@ -1860,230 +1855,198 @@ return (m); } +static struct unpcb * +fptounp(struct file *fp) +{ + struct socket *so; + + if (fp->f_type != DTYPE_SOCKET) + return (NULL); + if ((so = fp->f_data) == NULL) + return (NULL); + if (so->so_proto->pr_domain != &localdomain) + return (NULL); + return sotounpcb(so); +} + +static void +unp_discard(struct file *fp) +{ + + unp_externalize_fp(fp); + (void) closef(fp, (struct thread *)NULL); +} + +static void +unp_internalize_fp(struct file *fp) +{ + struct unpcb *unp; + + UNP_GLOBAL_WLOCK(); + if ((unp = fptounp(fp)) != NULL) { + unp->unp_file = fp; + unp->unp_msgcount++; + } + unp_rights++; + UNP_GLOBAL_WUNLOCK(); +} + +static void +unp_externalize_fp(struct file *fp) +{ + struct unpcb *unp; + + UNP_GLOBAL_WLOCK(); + if ((unp = fptounp(fp)) != NULL) + unp->unp_msgcount--; + unp_rights--; + UNP_GLOBAL_WUNLOCK(); +} + /* * unp_defer indicates whether additional work has been defered for a future * pass through unp_gc(). It is thread local and does not require explicit * synchronization. */ -static int unp_defer; +static int unp_marked; +static int unp_unreachable; + +static void +unp_accessable(struct file *fp) +{ + struct unpcb *unp; + + unp = fptounp(fp); + if (fp == NULL) + return; + if (unp->unp_gcflag & UNPGC_REF) + return; + unp->unp_gcflag &= ~UNPGC_DEAD; + unp->unp_gcflag |= UNPGC_REF; + unp_marked++; +} + +static void +unp_gc_process(struct unpcb *unp) +{ + struct socket *soa; + struct socket *so; + struct file *fp; -static int unp_taskcount; -SYSCTL_INT(_net_local, OID_AUTO, taskcount, CTLFLAG_RD, &unp_taskcount, 0, ""); + /* Already processed. */ + if (unp->unp_gcflag & UNPGC_SCANNED) + return; + fp = unp->unp_file; + /* + * Check for a socket potentially in a cycle. It must be in a + * queue as indicated by msgcount, and this must equal the file + * reference count. Note that when msgcount is 0 the file is NULL. + */ + if (unp->unp_msgcount != 0 && fp->f_count != 0 && + fp->f_count == unp->unp_msgcount) { + unp->unp_gcflag |= UNPGC_DEAD; + unp_unreachable++; + return; + } + /* + * Mark all sockets we reference with RIGHTS. + */ + so = unp->unp_socket; + SOCKBUF_LOCK(&so->so_rcv); + unp_scan(so->so_rcv.sb_mb, unp_accessable); + SOCKBUF_UNLOCK(&so->so_rcv); + /* + * Mark all sockets in our accept queue. + */ + ACCEPT_LOCK(); + TAILQ_FOREACH(soa, &so->so_comp, so_list) { + SOCKBUF_LOCK(&soa->so_rcv); + unp_scan(soa->so_rcv.sb_mb, unp_accessable); + SOCKBUF_UNLOCK(&soa->so_rcv); + } + ACCEPT_UNLOCK(); + unp->unp_gcflag |= UNPGC_SCANNED; +} static int unp_recycled; SYSCTL_INT(_net_local, OID_AUTO, recycled, CTLFLAG_RD, &unp_recycled, 0, ""); +static int unp_taskcount; +SYSCTL_INT(_net_local, OID_AUTO, taskcount, CTLFLAG_RD, &unp_taskcount, 0, ""); + static void unp_gc(__unused void *arg, int pending) { - struct file *fp, *nextfp; - struct socket *so; - struct file **extra_ref, **fpp; - int nunref, i; - int nfiles_snap; - int nfiles_slack = 20; + struct unp_head *heads[] = { &unp_dhead, &unp_shead, NULL }; + struct unp_head **head; + struct file **unref; + struct unpcb *unp; + int i; unp_taskcount++; - unp_defer = 0; + UNP_GLOBAL_RLOCK(); + /* + * First clear all gc flags from previous runs. + */ + for (head = heads; *head != NULL; head++) + LIST_FOREACH(unp, *head, unp_link) + unp->unp_gcflag &= ~(UNPGC_REF|UNPGC_DEAD); /* - * Before going through all this, set all FDs to be NOT deferred and - * NOT externally accessible. + * Scan marking all reachable sockets with UNPGC_REF. Once a socket + * is reachable all of the sockets it references are reachable. + * Stop the scan once we do a complete loop without discovering + * a new reachable socket. */ - sx_slock(&filelist_lock); - LIST_FOREACH(fp, &filehead, f_list) - fp->f_gcflag &= ~(FMARK|FDEFER); do { - KASSERT(unp_defer >= 0, ("unp_gc: unp_defer %d", unp_defer)); - LIST_FOREACH(fp, &filehead, f_list) { - FILE_LOCK(fp); - /* - * If the file is not open, skip it -- could be a - * file in the process of being opened, or in the - * process of being closed. If the file is - * "closing", it may have been marked for deferred - * consideration. Clear the flag now if so. - */ - if (fp->f_count == 0) { - if (fp->f_gcflag & FDEFER) - unp_defer--; - fp->f_gcflag &= ~(FMARK|FDEFER); - FILE_UNLOCK(fp); - continue; + unp_unreachable = 0; + unp_marked = 0; + for (head = heads; *head != NULL; head++) + LIST_FOREACH(unp, *head, unp_link) + unp_gc_process(unp); + } while (unp_marked); + UNP_GLOBAL_RUNLOCK(); + if (unp_unreachable == 0) + return; + /* + * Allocate space for a local list of dead unpcbs. + */ + unref = malloc(unp_unreachable * sizeof(struct file *), + M_TEMP, M_WAITOK); + /* + * Iterate looking for sockets which have been specifically marked + * as as unreachable and store them locally. + */ + UNP_GLOBAL_RLOCK(); + for (i = 0, head = heads; *head != NULL; head++) + LIST_FOREACH(unp, *head, unp_link) + if (unp->unp_gcflag & UNPGC_DEAD) { + unref[i++] = unp->unp_file; + KASSERT(unp->unp_file != NULL, + ("unp_gc: Invalid unpcb.")); + KASSERT(i <= unp_unreachable, + ("unp_gc: incorrect unreachable count.")); } - /* - * If we already marked it as 'defer' in a - * previous pass, then try to process it this - * time and un-mark it. - */ - if (fp->f_gcflag & FDEFER) { - fp->f_gcflag &= ~FDEFER; - unp_defer--; - } else { - /* - * If it's not deferred, then check if it's - * already marked.. if so skip it - */ - if (fp->f_gcflag & FMARK) { - FILE_UNLOCK(fp); - continue; - } - /* - * If all references are from messages in - * transit, then skip it. it's not externally - * accessible. - */ - if (fp->f_count == fp->f_msgcount) { - FILE_UNLOCK(fp); - continue; - } - /* - * If it got this far then it must be - * externally accessible. - */ - fp->f_gcflag |= FMARK; - } - /* - * Either it was deferred, or it is externally - * accessible and not already marked so. Now check - * if it is possibly one of OUR sockets. - */ - if (fp->f_type != DTYPE_SOCKET || - (so = fp->f_data) == NULL) { - FILE_UNLOCK(fp); - continue; - } - if (so->so_proto->pr_domain != &localdomain || - (so->so_proto->pr_flags & PR_RIGHTS) == 0) { - FILE_UNLOCK(fp); - continue; - } - - /* - * Tell any other threads that do a subsequent - * fdrop() that we are scanning the message - * buffers. - */ - fp->f_gcflag |= FWAIT; - FILE_UNLOCK(fp); - - /* - * So, Ok, it's one of our sockets and it IS - * externally accessible (or was deferred). Now we - * look to see if we hold any file descriptors in its - * message buffers. Follow those links and mark them - * as accessible too. - */ - SOCKBUF_LOCK(&so->so_rcv); - unp_scan(so->so_rcv.sb_mb, unp_mark); - SOCKBUF_UNLOCK(&so->so_rcv); - - /* - * Wake up any threads waiting in fdrop(). - */ - FILE_LOCK(fp); - fp->f_gcflag &= ~FWAIT; - wakeup(&fp->f_gcflag); - FILE_UNLOCK(fp); - } - } while (unp_defer); - sx_sunlock(&filelist_lock); + UNP_GLOBAL_RUNLOCK(); + /* + * All further operation is now done on a local list. We first ref + * all sockets to avoid closing them until all are flushed. + */ + for (i = 0; i < unp_unreachable; i++) + fhold(unref[i]); /* - * XXXRW: The following comments need updating for a post-SMPng and - * deferred unp_gc() world, but are still generally accurate. - * - * We grab an extra reference to each of the file table entries that - * are not otherwise accessible and then free the rights that are - * stored in messages on them. - * - * The bug in the orginal code is a little tricky, so I'll describe - * what's wrong with it here. - * - * It is incorrect to simply unp_discard each entry for f_msgcount - * times -- consider the case of sockets A and B that contain - * references to each other. On a last close of some other socket, - * we trigger a gc since the number of outstanding rights (unp_rights) - * is non-zero. If during the sweep phase the gc code unp_discards, - * we end up doing a (full) closef on the descriptor. A closef on A - * results in the following chain. Closef calls soo_close, which - * calls soclose. Soclose calls first (through the switch - * uipc_usrreq) unp_detach, which re-invokes unp_gc. Unp_gc simply - * returns because the previous instance had set unp_gcing, and we - * return all the way back to soclose, which marks the socket with - * SS_NOFDREF, and then calls sofree. Sofree calls sorflush to free - * up the rights that are queued in messages on the socket A, i.e., - * the reference on B. The sorflush calls via the dom_dispose switch - * unp_dispose, which unp_scans with unp_discard. This second - * instance of unp_discard just calls closef on B. - * - * Well, a similar chain occurs on B, resulting in a sorflush on B, - * which results in another closef on A. Unfortunately, A is already - * being closed, and the descriptor has already been marked with - * SS_NOFDREF, and soclose panics at this point. - * - * Here, we first take an extra reference to each inaccessible - * descriptor. Then, we call sorflush ourself, since we know it is a - * Unix domain socket anyhow. After we destroy all the rights - * carried in messages, we do a last closef to get rid of our extra - * reference. This is the last close, and the unp_detach etc will - * shut down the socket. - * - * 91/09/19, bsy@cs.cmu.edu + * Now flush all sockets, free'ing rights. This will free the + * struct files associated with these sockets but leave each socket + * with one remaining ref. */ -again: - nfiles_snap = openfiles + nfiles_slack; /* some slack */ - extra_ref = malloc(nfiles_snap * sizeof(struct file *), M_TEMP, - M_WAITOK); - sx_slock(&filelist_lock); - if (nfiles_snap < openfiles) { - sx_sunlock(&filelist_lock); - free(extra_ref, M_TEMP); - nfiles_slack += 20; - goto again; - } - for (nunref = 0, fp = LIST_FIRST(&filehead), fpp = extra_ref; - fp != NULL; fp = nextfp) { - nextfp = LIST_NEXT(fp, f_list); - FILE_LOCK(fp); - /* - * If it's not open, skip it - */ - if (fp->f_count == 0) { - FILE_UNLOCK(fp); - continue; - } - /* - * If all refs are from msgs, and it's not marked accessible - * then it must be referenced from some unreachable cycle of - * (shut-down) FDs, so include it in our list of FDs to - * remove. - */ - if (fp->f_count == fp->f_msgcount && !(fp->f_gcflag & FMARK)) { - *fpp++ = fp; - nunref++; - fp->f_count++; - } - FILE_UNLOCK(fp); - } - sx_sunlock(&filelist_lock); + for (i = 0; i < unp_unreachable; i++) + sorflush(unref[i]->f_data); /* - * For each FD on our hit list, do the following two things: + * And finally release the sockets so they can be reclaimed. */ - for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) { - struct file *tfp = *fpp; - FILE_LOCK(tfp); - if (tfp->f_type == DTYPE_SOCKET && - tfp->f_data != NULL) { - FILE_UNLOCK(tfp); - sorflush(tfp->f_data); - } else { - FILE_UNLOCK(tfp); - } - } - for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) { - closef(*fpp, (struct thread *) NULL); - unp_recycled++; - } - free(extra_ref, M_TEMP); + for (i = 0; i < unp_unreachable; i++) + fdrop(unref[i], NULL); + unp_recycled += unp_unreachable; + free(unref, M_TEMP); } void @@ -2143,31 +2106,6 @@ } } -static void -unp_mark(struct file *fp) -{ - - /* XXXRW: Should probably assert file list lock here. */ - - if (fp->f_gcflag & FMARK) - return; - unp_defer++; - fp->f_gcflag |= (FMARK|FDEFER); -} - -static void -unp_discard(struct file *fp) -{ - - UNP_GLOBAL_WLOCK(); - FILE_LOCK(fp); - fp->f_msgcount--; - unp_rights--; - FILE_UNLOCK(fp); - UNP_GLOBAL_WUNLOCK(); - (void) closef(fp, (struct thread *)NULL); -} - #ifdef DDB static void db_print_indent(int indent) --- //depot/vendor/freebsd/src/sys/kern/vfs_aio.c 2007/08/20 11:57:07 +++ //depot/user/kris/contention/sys/kern/vfs_aio.c 2007/08/31 20:34:30 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -520,12 +521,12 @@ TAILQ_INIT(&ki->kaio_sockqueue); TAILQ_INIT(&ki->kaio_syncqueue); TASK_INIT(&ki->kaio_task, 0, aio_kick_helper, p); - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_aioinfo == NULL) { p->p_aioinfo = ki; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); mtx_destroy(&ki->kaio_mtx); uma_zfree(kaio_zone, ki); } @@ -539,13 +540,13 @@ { int ret = 0; - PROC_LOCK(p); + PROC_WLOCK(p); if (!KSI_ONQ(ksi)) { ksi->ksi_code = SI_ASYNCIO; ksi->ksi_flags |= KSI_EXT | KSI_INS; ret = psignal_event(p, sigev, ksi); } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (ret); } @@ -586,18 +587,18 @@ TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list); /* lio is going away, we need to destroy any knotes */ knlist_delete(&lj->klist, curthread, 1); - PROC_LOCK(p); + PROC_WLOCK(p); sigqueue_take(&lj->lioj_ksi); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uma_zfree(aiolio_zone, lj); } } /* aiocbe is going away, we need to destroy any knotes */ knlist_delete(&aiocbe->klist, curthread, 1); - PROC_LOCK(p); + PROC_WLOCK(p); sigqueue_take(&aiocbe->ksi); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); MPASS(aiocbe->bp == NULL); aiocbe->jobstate = JOBST_NULL; @@ -708,9 +709,9 @@ if (lj->lioj_count == 0) { TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list); knlist_delete(&lj->klist, curthread, 1); - PROC_LOCK(p); + PROC_WLOCK(p); sigqueue_take(&lj->lioj_ksi); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); uma_zfree(aiolio_zone, lj); } else { panic("LIO job not cleaned up: C:%d, FC:%d\n", @@ -865,9 +866,9 @@ sigpipe = 0; } if (sigpipe) { - PROC_LOCK(aiocbe->userproc); + PROC_WLOCK(aiocbe->userproc); psignal(aiocbe->userproc, SIGPIPE); - PROC_UNLOCK(aiocbe->userproc); + PROC_WUNLOCK(aiocbe->userproc); } } } @@ -2090,9 +2091,9 @@ if (lj->lioj_count == 0) { TAILQ_REMOVE(&ki->kaio_liojoblist, lj, lioj_list); knlist_delete(&lj->klist, curthread, 1); - PROC_LOCK(p); + PROC_WLOCK(p); sigqueue_take(&lj->lioj_ksi); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); AIO_UNLOCK(ki); uma_zfree(aiolio_zone, lj); } else --- //depot/vendor/freebsd/src/sys/kern/vfs_bio.c 2007/06/09 23:49:40 +++ //depot/user/kris/contention/sys/kern/vfs_bio.c 2007/06/22 23:30:21 @@ -2217,7 +2217,8 @@ VOP_UNLOCK(vp, 0, td); flushwithdeps += hasdeps; flushed++; - waitrunningbufspace(); + if ((curthread->td_pflags & TDP_NORUNNINGBUF) == 0) + waitrunningbufspace(); numdirtywakeup((lodirtybuffers + hidirtybuffers) / 2); mtx_lock(&bqlock); continue; --- //depot/vendor/freebsd/src/sys/kern/vfs_cache.c 2007/06/18 09:32:27 +++ //depot/user/kris/contention/sys/kern/vfs_cache.c 2007/08/31 20:06:22 @@ -314,6 +314,7 @@ struct componentname *cnp; { struct namecache *ncp; + struct thread *td; u_int32_t hash; int error, ltype; @@ -321,6 +322,7 @@ cnp->cn_flags &= ~MAKEENTRY; return (0); } + td = cnp->cn_thread; retry: CACHE_LOCK(); numcalls++; @@ -419,18 +421,29 @@ if (dvp == *vpp) { /* lookup on "." */ VREF(*vpp); CACHE_UNLOCK(); + /* + * When we lookup "." we still can be asked to lock it + * differently... + */ + ltype = cnp->cn_lkflags & (LK_SHARED | LK_EXCLUSIVE); + if (ltype == VOP_ISLOCKED(*vpp, td)) + return (-1); + else if (ltype == LK_EXCLUSIVE) + vn_lock(*vpp, LK_UPGRADE | LK_RETRY, td); return (-1); } ltype = 0; /* silence gcc warning */ if (cnp->cn_flags & ISDOTDOT) { - ltype = VOP_ISLOCKED(dvp, cnp->cn_thread); - VOP_UNLOCK(dvp, 0, cnp->cn_thread); + ltype = VOP_ISLOCKED(dvp, td); + VOP_UNLOCK(dvp, 0, td); } VI_LOCK(*vpp); CACHE_UNLOCK(); - error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread); + error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, td); if (cnp->cn_flags & ISDOTDOT) - vn_lock(dvp, ltype | LK_RETRY, cnp->cn_thread); + vn_lock(dvp, ltype | LK_RETRY, td); + if ((cnp->cn_flags & ISLASTCN) && (cnp->cn_lkflags & LK_EXCLUSIVE)) + ASSERT_VOP_ELOCKED(*vpp, "cache_lookup"); if (error) { *vpp = NULL; goto retry; --- //depot/vendor/freebsd/src/sys/kern/vfs_lookup.c 2007/05/27 20:54:00 +++ //depot/user/kris/contention/sys/kern/vfs_lookup.c 2007/08/31 20:06:22 @@ -88,12 +88,8 @@ } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL) -#ifdef LOOKUP_SHARED static int lookup_shared = 1; -#else -static int lookup_shared = 0; -#endif -SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RW, &lookup_shared, 0, +SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RW, &lookup_shared, 1, "Enables/Disables shared locks for path name translation"); /* @@ -772,6 +768,14 @@ if ((cnp->cn_flags & LOCKLEAF) == 0) VOP_UNLOCK(dp, 0, td); success: + /* + * Because of lookup_shared we may have the vnode shared locked, but + * the caller may want it to be exclusively locked. + */ + if ((cnp->cn_flags & (ISLASTCN | LOCKSHARED | LOCKLEAF)) == + (ISLASTCN | LOCKLEAF) && VOP_ISLOCKED(dp, td) != LK_EXCLUSIVE) { + vn_lock(dp, LK_UPGRADE | LK_RETRY, td); + } if (vfslocked && dvfslocked) VFS_UNLOCK_GIANT(dvfslocked); /* Only need one */ if (vfslocked || dvfslocked) --- //depot/vendor/freebsd/src/sys/kern/vfs_syscalls.c 2007/09/10 00:02:48 +++ //depot/user/kris/contention/sys/kern/vfs_syscalls.c 2007/09/14 21:34:44 @@ -1022,6 +1022,8 @@ return (error); /* An extra reference on `nfp' has been held for us by falloc(). */ fp = nfp; + /* Set the flags early so the finit in devfs can pick them up. */ + fp->f_flag = flags & FMASK; cmode = ((mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT; NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1 | MPSAFE, pathseg, path, td); td->td_dupfd = -1; /* XXX check for fdopen */ @@ -1067,16 +1069,16 @@ NDFREE(&nd, NDF_ONLY_PNBUF); vp = nd.ni_vp; - FILE_LOCK(fp); - fp->f_vnode = vp; - if (fp->f_data == NULL) - fp->f_data = vp; - fp->f_flag = flags & FMASK; - fp->f_seqcount = 1; - fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE); - if (fp->f_ops == &badfileops) - fp->f_ops = &vnops; - FILE_UNLOCK(fp); + fp->f_vnode = vp; /* XXX Does devfs need this? */ + /* + * If the file wasn't claimed by devfs bind it to the normal + * vnode operations here. + */ + if (fp->f_ops == &badfileops) { + KASSERT(vp->v_type != VFIFO, ("Unexpected fifo.")); + fp->f_seqcount = 1; + finit(fp, flags & FMASK, DTYPE_VNODE, vp, &vnops); + } VOP_UNLOCK(vp, 0, td); if (flags & (O_EXLOCK | O_SHLOCK)) { @@ -1093,7 +1095,7 @@ if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) goto bad; - fp->f_flag |= FHASLOCK; + atomic_set_int(&fp->f_flag, FHASLOCK); } if (flags & O_TRUNC) { if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) @@ -4179,14 +4181,8 @@ } /* An extra reference on `nfp' has been held for us by falloc(). */ fp = nfp; - - FILE_LOCK(nfp); nfp->f_vnode = vp; - nfp->f_data = vp; - nfp->f_flag = fmode & FMASK; - nfp->f_type = DTYPE_VNODE; - nfp->f_ops = &vnops; - FILE_UNLOCK(nfp); + finit(nfp, fmode & FMASK, DTYPE_VNODE, vp, &vnops); if (fmode & (O_EXLOCK | O_SHLOCK)) { lf.l_whence = SEEK_SET; lf.l_start = 0; @@ -4215,7 +4211,7 @@ goto out; } vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); - fp->f_flag |= FHASLOCK; + atomic_set_int(&fp->f_flag, FHASLOCK); } VOP_UNLOCK(vp, 0, td); --- //depot/vendor/freebsd/src/sys/kern/vfs_vnops.c 2007/07/26 17:02:32 +++ //depot/user/kris/contention/sys/kern/vfs_vnops.c 2007/08/16 16:17:38 @@ -80,7 +80,7 @@ .fo_kqfilter = vn_kqfilter, .fo_stat = vn_statfile, .fo_close = vn_closefile, - .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE + .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | DFLAG_MPSAFE }; int @@ -488,10 +488,12 @@ { struct vnode *vp; int error, ioflag; + struct mtx *mtxp; int vfslocked; KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", uio->uio_td, td)); + mtxp = NULL; vp = fp->f_vnode; ioflag = 0; if (fp->f_flag & FNONBLOCK) @@ -505,13 +507,15 @@ * It is now protected by the FOFFSET_LOCKED flag. */ if ((flags & FOF_OFFSET) == 0) { - FILE_LOCK(fp); + mtxp = mtx_pool_find(mtxpool_sleep, fp); + mtx_lock(mtxp); while(fp->f_vnread_flags & FOFFSET_LOCKED) { fp->f_vnread_flags |= FOFFSET_LOCK_WAITING; - msleep(&fp->f_vnread_flags,fp->f_mtxp,PUSER -1,"vnread offlock",0); + msleep(&fp->f_vnread_flags, mtxp, PUSER -1, + "vnread offlock", 0); } fp->f_vnread_flags |= FOFFSET_LOCKED; - FILE_UNLOCK(fp); + mtx_unlock(mtxp); vn_lock(vp, LK_SHARED | LK_RETRY, td); uio->uio_offset = fp->f_offset; } else @@ -526,11 +530,11 @@ error = VOP_READ(vp, uio, ioflag, fp->f_cred); if ((flags & FOF_OFFSET) == 0) { fp->f_offset = uio->uio_offset; - FILE_LOCK(fp); + mtx_lock(mtxp); if (fp->f_vnread_flags & FOFFSET_LOCK_WAITING) wakeup(&fp->f_vnread_flags); fp->f_vnread_flags = 0; - FILE_UNLOCK(fp); + mtx_unlock(mtxp); } fp->f_nextoff = uio->uio_offset; VOP_UNLOCK(vp, 0, td); --- //depot/vendor/freebsd/src/sys/modules/hwpmc/Makefile 2006/07/27 19:16:26 +++ //depot/user/kris/contention/sys/modules/hwpmc/Makefile 2007/09/08 18:21:40 @@ -11,7 +11,7 @@ WARNS?= 2 .if ${MACHINE_ARCH} == "amd64" -SRCS+= hwpmc_amd.c hwpmc_piv.c hwpmc_x86.c +SRCS+= hwpmc_amd.c hwpmc_piv.c hwpmc_ppro.c hwpmc_x86.c SRCS+= device_if.h bus_if.h .endif --- //depot/vendor/freebsd/src/sys/netgraph/netflow/ng_netflow.c 2007/03/28 14:02:33 +++ //depot/user/kris/contention/sys/netgraph/netflow/ng_netflow.c 2007/04/01 20:54:11 @@ -184,7 +184,7 @@ priv->info.nfinfo_act_t = ACTIVE_TIMEOUT; /* Initialize callout handle */ - callout_init(&priv->exp_callout, 1); + callout_init(&priv->exp_callout, CALLOUT_MPSAFE); /* Allocate memory and set up flow cache */ if ((error = ng_netflow_cache_init(priv))) --- //depot/vendor/freebsd/src/sys/netgraph/ng_socket.c 2007/05/11 10:23:09 +++ //depot/user/kris/contention/sys/netgraph/ng_socket.c 2007/08/16 16:17:38 @@ -688,7 +688,7 @@ vn = fp->f_data; if (vn && (vn->v_type == VCHR)) { /* for a VCHR, actually reference the FILE */ - fp->f_count++; + fhold(fp); /* XXX then what :) */ /* how to pass on to other modules? */ } else { --- //depot/vendor/freebsd/src/sys/netinet/ip_dummynet.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/netinet/ip_dummynet.c 2007/08/10 15:36:57 @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -842,7 +843,7 @@ ip = mtod(m, struct ip *); ip->ip_len = htons(ip->ip_len); ip->ip_off = htons(ip->ip_off); - netisr_dispatch(NETISR_IP, m); + netisr2_dispatch(NETISR_IP, m); break; #ifdef INET6 case DN_TO_IP6_IN: --- //depot/vendor/freebsd/src/sys/netinet/sctp_os_bsd.h 2007/09/08 11:37:14 +++ //depot/user/kris/contention/sys/netinet/sctp_os_bsd.h 2007/09/14 21:34:44 @@ -260,7 +260,7 @@ #include typedef struct callout sctp_os_timer_t; -#define SCTP_OS_TIMER_INIT(tmr) callout_init(tmr, 1) +#define SCTP_OS_TIMER_INIT(tmr) callout_init(tmr, CALLOUT_MPSAFE) #define SCTP_OS_TIMER_START callout_reset #define SCTP_OS_TIMER_STOP callout_stop #define SCTP_OS_TIMER_STOP_DRAIN callout_drain --- //depot/vendor/freebsd/src/sys/netncp/ncp_ncp.c 2005/01/07 01:52:23 +++ //depot/user/kris/contention/sys/netncp/ncp_ncp.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -85,7 +86,7 @@ if (td == NULL) return 0; p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); tmpset = p->p_siglist; SIGSETOR(tmpset, td->td_siglist); SIGSETNAND(tmpset, td->td_sigmask); @@ -93,10 +94,10 @@ SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore); mtx_unlock(&p->p_sigacts->ps_mtx); if (SIGNOTEMPTY(td->td_siglist) && NCP_SIGMASK(tmpset)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return EINTR; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; } --- //depot/vendor/freebsd/src/sys/netncp/ncp_rq.c 2005/07/29 13:25:19 +++ //depot/user/kris/contention/sys/netncp/ncp_rq.c 2007/08/16 16:03:09 @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -274,7 +276,9 @@ /* * Flush out replies on previous reqs */ - while (ncp_poll(so, POLLIN) != 0) { + tv.tv_sec = 0; + tv.tv_usec = 0; + while (selsocket(so, POLLIN, &tv, td) == 0) { if (ncp_sock_recv(so, &m, &len) != 0) break; m_freem(m); @@ -319,7 +323,7 @@ } tv.tv_sec = conn->li.timeout; tv.tv_usec = 0; - error = ncp_sock_rselect(so, td, &tv, POLLIN); + error = selsocket(so, POLLIN, &tv, td); if (error == EWOULDBLOCK ) /* timeout expired */ continue; error = ncp_chkintr(conn, td); @@ -335,7 +339,9 @@ dosend = 1; /* resend rq if error */ for (;;) { error = 0; - if (ncp_poll(so, POLLIN) == 0) + tv.tv_sec = 0; + tv.tv_usec = 0; + if (selsocket(so, POLLIN, &tv, td) != 0) break; /* if (so->so_rcv.sb_cc == 0) { break; --- //depot/vendor/freebsd/src/sys/netncp/ncp_sock.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/netncp/ncp_sock.c 2007/08/16 16:03:09 @@ -65,7 +65,6 @@ #define ipx_setnullhost(x) ((x).x_host.s_host[0] = 0); \ ((x).x_host.s_host[1] = 0); ((x).x_host.s_host[2] = 0); -/*int ncp_poll(struct socket *so, int events);*/ /*static int ncp_getsockname(struct socket *so, caddr_t asa, int *alen);*/ static int ncp_soconnect(struct socket *so, struct sockaddr *target, struct thread *td); @@ -181,110 +180,6 @@ return error; } -int -ncp_poll(struct socket *so, int events) -{ - struct thread *td = curthread; - int revents; - - /* Fake up enough state to look like we are in poll(2). */ - mtx_lock(&sellock); - thread_lock(td); - td->td_flags |= TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - TAILQ_INIT(&td->td_selq); - - revents = sopoll(so, events, NULL, td); - - /* Tear down the fake poll(2) state. */ - mtx_lock(&sellock); - clear_selinfo_list(td); - thread_lock(td); - td->td_flags &= ~TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - - return (revents); -} - -int -ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv, - int events) -{ - struct timeval atv, rtv, ttv; - int ncoll, timo, error, revents; - - if (tv) { - atv = *tv; - if (itimerfix(&atv)) { - error = EINVAL; - goto done_noproclock; - } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); - } - timo = 0; - mtx_lock(&sellock); - -retry: - ncoll = nselcoll; - thread_lock(td); - td->td_flags |= TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - - TAILQ_INIT(&td->td_selq); - revents = sopoll(so, events, NULL, td); - mtx_lock(&sellock); - if (revents) { - error = 0; - goto done; - } - if (tv) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) { - error = EWOULDBLOCK; - goto done; - } - ttv = atv; - timevalsub(&ttv, &rtv); - timo = tvtohz(&ttv); - } - /* - * An event of our interest may occur during locking a thread. - * In order to avoid missing the event that occurred during locking - * the process, test TDF_SELECT and rescan file descriptors if - * necessary. - */ - thread_lock(td); - if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { - thread_unlock(td); - goto retry; - } - thread_unlock(td); - - if (timo > 0) - error = cv_timedwait(&selwait, &sellock, timo); - else { - cv_wait(&selwait, &sellock); - error = 0; - } - -done: - clear_selinfo_list(td); - - thread_lock(td); - td->td_flags &= ~TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - -done_noproclock: - if (error == ERESTART) - error = 0; - return (error); -} - /* * Connect to specified server via IPX */ --- //depot/vendor/freebsd/src/sys/netncp/ncp_sock.h 2005/01/07 01:52:23 +++ //depot/user/kris/contention/sys/netncp/ncp_sock.h 2007/08/16 16:03:09 @@ -45,9 +45,6 @@ int ncp_sock_recv(struct socket *so, struct mbuf **mp, int *rlen); int ncp_sock_send(struct socket *so, struct mbuf *data, struct ncp_rq *rqp); int ncp_sock_disconnect(struct ncp_conn *conn); -int ncp_poll(struct socket *so, int events); -int ncp_sock_rselect(struct socket *so, struct thread *td, struct timeval *tv, - int events); int ncp_sock_checksum(struct ncp_conn *conn, int enable); void ncp_check_rq(struct ncp_conn *conn); --- //depot/vendor/freebsd/src/sys/netsmb/smb_subr.c 2006/11/05 06:32:03 +++ //depot/user/kris/contention/sys/netsmb/smb_subr.c 2007/08/31 20:34:30 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -80,7 +81,7 @@ return 0; p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); tmpset = p->p_siglist; SIGSETOR(tmpset, td->td_siglist); SIGSETNAND(tmpset, td->td_sigmask); @@ -88,10 +89,10 @@ SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore); mtx_unlock(&p->p_sigacts->ps_mtx); if (SIGNOTEMPTY(td->td_siglist) && SMB_SIGMASK(tmpset)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return EINTR; } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return 0; } --- //depot/vendor/freebsd/src/sys/netsmb/smb_trantcp.c 2007/06/15 23:50:49 +++ //depot/user/kris/contention/sys/netsmb/smb_trantcp.c 2007/08/16 16:03:09 @@ -95,84 +95,6 @@ } static int -nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events, - struct thread *td) -{ - struct timeval atv, rtv, ttv; - int ncoll, timo, error, revents; - - if (tv) { - atv = *tv; - if (itimerfix(&atv)) { - error = EINVAL; - goto done_noproclock; - } - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); - } - timo = 0; - mtx_lock(&sellock); -retry: - - ncoll = nselcoll; - thread_lock(td); - td->td_flags |= TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - - /* XXX: Should be done when the thread is initialized. */ - TAILQ_INIT(&td->td_selq); - revents = sopoll(nbp->nbp_tso, events, NULL, td); - mtx_lock(&sellock); - if (revents) { - error = 0; - goto done; - } - if (tv) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) { - error = EWOULDBLOCK; - goto done; - } - ttv = atv; - timevalsub(&ttv, &rtv); - timo = tvtohz(&ttv); - } - /* - * An event of our interest may occur during locking a process. - * In order to avoid missing the event that occurred during locking - * the process, test P_SELECT and rescan file descriptors if - * necessary. - */ - thread_lock(td); - if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) { - thread_unlock(td); - goto retry; - } - thread_unlock(td); - - if (timo > 0) - error = cv_timedwait(&selwait, &sellock, timo); - else { - cv_wait(&selwait, &sellock); - error = 0; - } - -done: - clear_selinfo_list(td); - - thread_lock(td); - td->td_flags &= ~TDF_SELECT; - thread_unlock(td); - mtx_unlock(&sellock); - -done_noproclock: - if (error == ERESTART) - return 0; - return error; -} - -static int nb_intr(struct nbpcb *nbp, struct proc *p) { return 0; @@ -302,7 +224,7 @@ if (error) return error; TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo); - error = nbssn_rselect(nbp, &tv, POLLIN, td); + error = selsocket(nbp->nbp_tso, POLLIN, &tv, td); if (error == EWOULDBLOCK) { /* Timeout */ NBDEBUG("initial request timeout\n"); return ETIMEDOUT; --- //depot/vendor/freebsd/src/sys/nfs4client/nfs4_dev.c 2006/05/13 00:20:41 +++ //depot/user/kris/contention/sys/nfs4client/nfs4_dev.c 2007/08/31 20:34:30 @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -238,9 +239,9 @@ if (dead != NULL) { NFS4DEV_DEBUG("nfs4dev_uninit(): you forgot to kill attached daemon (pid: %u)\n", dead->p_pid); - PROC_LOCK(dead); + PROC_WLOCK(dead); psignal(dead, SIGTERM); - PROC_UNLOCK(dead); + PROC_WUNLOCK(dead); } /* XXX moot? */ --- //depot/vendor/freebsd/src/sys/nfsclient/nfs_bio.c 2007/07/03 18:32:21 +++ //depot/user/kris/contention/sys/nfsclient/nfs_bio.c 2007/08/31 20:34:30 @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -951,14 +952,18 @@ * file servers have no limits, i don't think it matters */ if (p != NULL) { - PROC_LOCK(p); + PROC_RLOCK(p); if (uio->uio_offset + uio->uio_resid > lim_cur(p, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(p)) { + PROC_RUNLOCK(p); + PROC_WLOCK(p); + } psignal(p, SIGXFSZ); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EFBIG); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); } biosize = vp->v_mount->mnt_stat.f_iosize; @@ -1586,9 +1591,9 @@ mtx_lock(&np->n_mtx); if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &np->n_vattr.va_mtime)) { mtx_unlock(&np->n_mtx); - PROC_LOCK(p); + PROC_WLOCK(p); killproc(p, "text file modification"); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else mtx_unlock(&np->n_mtx); } --- //depot/vendor/freebsd/src/sys/nfsclient/nfs_lock.c 2007/04/21 18:12:03 +++ //depot/user/kris/contention/sys/nfsclient/nfs_lock.c 2007/08/31 20:34:30 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -363,7 +364,7 @@ (timevalcmp(&targetp->p_nlminfo->pid_start, &ansp->la_msg_ident.pid_start, !=) || targetp->p_nlminfo->msg_seq != ansp->la_msg_ident.msg_seq))) { - PROC_UNLOCK(targetp); + PROC_WUNLOCK(targetp); return (EPIPE); } @@ -373,7 +374,7 @@ wakeup(targetp->p_nlminfo); - PROC_UNLOCK(targetp); + PROC_WUNLOCK(targetp); return (0); } --- //depot/vendor/freebsd/src/sys/nfsclient/nfs_socket.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/nfsclient/nfs_socket.c 2007/08/31 20:34:30 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -1611,7 +1612,7 @@ td = curthread; /* XXX */ p = td->td_proc; /* Remove the NFS set of signals from newset */ - PROC_LOCK(p); + PROC_RLOCK(p); mtx_lock(&p->p_sigacts->ps_mtx); for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) { /* @@ -1625,7 +1626,7 @@ SIGDELSET(newset, nfs_sig_set[i]); } mtx_unlock(&p->p_sigacts->ps_mtx); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); kern_sigprocmask(td, SIG_SETMASK, &newset, oldset, 0); } @@ -1687,7 +1688,7 @@ if (td == NULL) return (0); p = td->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); tmpset = p->p_siglist; SIGSETOR(tmpset, td->td_siglist); SIGSETNAND(tmpset, td->td_sigmask); @@ -1696,10 +1697,10 @@ mtx_unlock(&p->p_sigacts->ps_mtx); if ((SIGNOTEMPTY(p->p_siglist) || SIGNOTEMPTY(td->td_siglist)) && nfs_sig_pending(tmpset)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (EINTR); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); return (0); } --- //depot/vendor/freebsd/src/sys/nfsclient/nfs_subs.c 2007/07/03 18:32:21 +++ //depot/user/kris/contention/sys/nfsclient/nfs_subs.c 2007/07/26 15:30:52 @@ -738,9 +738,6 @@ np = VTONFS(vp); vap = &np->n_vattr; nmp = VFSTONFS(vp->v_mount); -#ifdef NFS_ACDEBUG - mtx_lock(&Giant); /* nfs_printf() */ -#endif mtx_lock(&np->n_mtx); /* XXX n_mtime doesn't seem to be updated on a miss-and-reload */ timeo = (time_second - np->n_mtime.tv_sec) / 10; @@ -802,9 +799,6 @@ vaper->va_mtime = np->n_mtim; } mtx_unlock(&np->n_mtx); -#ifdef NFS_ACDEBUG - mtx_unlock(&Giant); /* nfs_printf() */ -#endif return (0); } --- //depot/vendor/freebsd/src/sys/opencrypto/crypto.c 2007/03/21 03:48:12 +++ //depot/user/kris/contention/sys/opencrypto/crypto.c 2007/08/31 20:34:30 @@ -68,6 +68,7 @@ #include #include #include +#include #include #include @@ -254,10 +255,10 @@ *pp = NULL; if (p) { wakeup_one(q); - PROC_LOCK(p); /* NB: insure we don't miss wakeup */ + PROC_WLOCK(p); /* NB: insure we don't miss wakeup */ CRYPTO_DRIVER_UNLOCK(); /* let crypto_finis progress */ - msleep(p, &p->p_mtx, PWAIT, "crypto_destroy", 0); - PROC_UNLOCK(p); + rw_sleep(p, &p->p_rwlock, PWAIT, "crypto_destroy", 0); + PROC_WUNLOCK(p); CRYPTO_DRIVER_LOCK(); } } --- //depot/vendor/freebsd/src/sys/opencrypto/cryptodev.c 2007/05/09 19:37:47 +++ //depot/user/kris/contention/sys/opencrypto/cryptodev.c 2007/08/16 16:17:38 @@ -837,12 +837,7 @@ return (error); } /* falloc automatically provides an extra reference to 'f'. */ - FILE_LOCK(f); - f->f_flag = FREAD | FWRITE; - f->f_type = DTYPE_CRYPTO; - f->f_data = fcr; - f->f_ops = &cryptofops; - FILE_UNLOCK(f); + finit(f, FREAD | FWRITE, DTYPE_CRYPTO, fcr, &cryptofops); *(u_int32_t *)data = fd; fdrop(f, td); break; --- //depot/vendor/freebsd/src/sys/pc98/pc98/machdep.c 2007/06/06 13:05:23 +++ //depot/user/kris/contention/sys/pc98/pc98/machdep.c 2007/08/31 20:34:30 @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include @@ -286,7 +287,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -324,7 +325,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Save most if not all of trap frame. */ sf.sf_siginfo.si_sc.sc_eax = regs->tf_eax; @@ -382,7 +383,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -395,7 +396,7 @@ regs->tf_fs = _udatasel; load_gs(_udatasel); regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } #endif /* COMPAT_43 */ @@ -414,7 +415,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -465,7 +466,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * If we're a vm86 process, we want to save the segment registers. @@ -503,7 +504,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -515,7 +516,7 @@ regs->tf_es = _udatasel; regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } #endif /* COMPAT_FREEBSD4 */ @@ -534,7 +535,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -601,7 +602,7 @@ sf.sf_ahu.sf_handler = catcher; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* * If we're a vm86 process, we want to save the segment registers. @@ -639,7 +640,7 @@ #ifdef DEBUG printf("process %ld has trashed its stack\n", (long)p->p_pid); #endif - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -651,7 +652,7 @@ regs->tf_es = _udatasel; regs->tf_fs = _udatasel; regs->tf_ss = _udatasel; - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -777,7 +778,7 @@ regs->tf_eip = scp->sc_pc; regs->tf_eflags = eflags; - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (scp->sc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -787,7 +788,7 @@ SIGSETOLD(td->td_sigmask, scp->sc_mask); SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } #endif /* COMPAT_43 */ @@ -894,7 +895,7 @@ bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -905,7 +906,7 @@ td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } #endif /* COMPAT_FREEBSD4 */ @@ -1015,7 +1016,7 @@ bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs)); } - PROC_LOCK(p); + PROC_WLOCK(p); #if defined(COMPAT_43) if (ucp->uc_mcontext.mc_onstack & 1) td->td_sigstk.ss_flags |= SS_ONSTACK; @@ -1026,7 +1027,7 @@ td->td_sigmask = ucp->uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (EJUSTRETURN); } @@ -1982,6 +1983,7 @@ */ mutex_init(); mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS | MTX_NOPROFILE); + rwlock_init(); /* make ldt memory segments */ ldt_segs[LUCODE_SEL].ssd_limit = atop(0 - 1); @@ -2394,9 +2396,7 @@ tp = td->td_frame; - PROC_LOCK(curthread->td_proc); mcp->mc_onstack = sigonstack(tp->tf_esp); - PROC_UNLOCK(curthread->td_proc); mcp->mc_gs = td->td_pcb->pcb_gs; mcp->mc_fs = tp->tf_fs; mcp->mc_es = tp->tf_es; --- //depot/vendor/freebsd/src/sys/powerpc/powerpc/machdep.c 2007/05/31 22:54:01 +++ //depot/user/kris/contention/sys/powerpc/powerpc/machdep.c 2007/08/31 20:34:30 @@ -84,6 +84,7 @@ #include #include #include +#include #include #include #include @@ -302,6 +303,7 @@ __asm __volatile("mtsprg 0, %0" :: "r"(pc)); mutex_init(); + rwlock_init(); /* * Initialize the console before printing anything. @@ -449,7 +451,7 @@ td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; code = ksi->ksi_code; psp = p->p_sigacts; @@ -530,7 +532,7 @@ tf->dar : tf->srr0; } mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); @@ -542,14 +544,14 @@ * Process has trashed its stack. Kill it. */ CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->srr0, tf->fixreg[1]); - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -572,11 +574,11 @@ return (error); p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); td->td_sigmask = uc.uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); @@ -659,11 +661,8 @@ int error; error = grab_mcontext(td, mcp, flags); - if (error == 0) { - PROC_LOCK(curthread->td_proc); + if (error == 0) mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); - PROC_UNLOCK(curthread->td_proc); - } return (error); } --- //depot/vendor/freebsd/src/sys/powerpc/powerpc/mem.c 2006/07/26 17:15:56 +++ //depot/user/kris/contention/sys/powerpc/powerpc/mem.c 2007/07/26 22:46:10 @@ -82,8 +82,6 @@ cnt = 0; error = 0; - GIANT_REQUIRED; - while (uio->uio_resid > 0 && !error) { iov = uio->uio_iov; if (iov->iov_len == 0) { --- //depot/vendor/freebsd/src/sys/powerpc/powerpc/trap.c 2007/08/07 18:45:34 +++ //depot/user/kris/contention/sys/powerpc/powerpc/trap.c 2007/08/31 20:34:30 @@ -541,18 +541,18 @@ * Keep swapout from messing with us during this * critical time. */ - PROC_LOCK(p); + PROC_WLOCK(p); ++p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Fault in the user page: */ rv = vm_fault(map, va, ftype, (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : VM_FAULT_NORMAL); - PROC_LOCK(p); + PROC_WLOCK(p); --p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * Don't have to worry about process locking or stacks in the --- //depot/vendor/freebsd/src/sys/rpc/rpcclnt.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/rpc/rpcclnt.c 2007/08/31 20:34:30 @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -1540,17 +1541,17 @@ RPC_RETURN(EINTR); #else p = pr->td_proc; - PROC_LOCK(p); + PROC_RLOCK(p); tmpset = p->p_siglist; SIGSETNAND(tmpset, pr->td_sigmask); mtx_lock(&p->p_sigacts->ps_mtx); SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore); mtx_unlock(&p->p_sigacts->ps_mtx); if (SIGNOTEMPTY(p->p_siglist) && RPCCLNTINT_SIGMASK(tmpset)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); RPC_RETURN(EINTR); } - PROC_UNLOCK(p); + PROC_RUNLOCK(p); #endif RPC_RETURN(0); } --- //depot/vendor/freebsd/src/sys/security/audit/audit_arg.c 2007/06/27 17:03:26 +++ //depot/user/kris/contention/sys/security/audit/audit_arg.c 2007/08/31 20:34:30 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -358,7 +359,7 @@ KASSERT(p != NULL, ("audit_arg_process: p == NULL")); - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); ar = currecord(); if (ar == NULL) --- //depot/vendor/freebsd/src/sys/security/audit/audit_syscalls.c 2007/06/27 17:03:26 +++ //depot/user/kris/contention/sys/security/audit/audit_syscalls.c 2007/08/31 20:34:30 @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -314,14 +316,14 @@ case A_GETPINFO: if (udata.au_aupinfo.ap_pid < 1) return (EINVAL); - if ((tp = pfind(udata.au_aupinfo.ap_pid)) == NULL) + if ((tp = pfindr(udata.au_aupinfo.ap_pid)) == NULL) return (EINVAL); if (p_cansee(td, tp) != 0) { - PROC_UNLOCK(tp); + PROC_RUNLOCK(tp); return (EINVAL); } if (tp->p_ucred->cr_audit.ai_termid.at_type == AU_IPv6) { - PROC_UNLOCK(tp); + PROC_RUNLOCK(tp); return (EINVAL); } udata.au_aupinfo.ap_auid = @@ -336,7 +338,7 @@ (dev_t)tp->p_ucred->cr_audit.ai_termid.at_port; udata.au_aupinfo.ap_asid = tp->p_ucred->cr_audit.ai_asid; - PROC_UNLOCK(tp); + PROC_RUNLOCK(tp); break; case A_SETPMASK: @@ -348,7 +350,7 @@ return (EINVAL); } if (p_cansee(td, tp) != 0) { - PROC_UNLOCK(tp); + PROC_WUNLOCK(tp); crfree(newcred); return (EINVAL); } @@ -359,7 +361,7 @@ newcred->cr_audit.ai_mask.am_failure = udata.au_aupinfo.ap_mask.am_failure; td->td_proc->p_ucred = newcred; - PROC_UNLOCK(tp); + PROC_WUNLOCK(tp); crfree(oldcred); break; @@ -378,7 +380,7 @@ case A_GETPINFO_ADDR: if (udata.au_aupinfo_addr.ap_pid < 1) return (EINVAL); - if ((tp = pfind(udata.au_aupinfo_addr.ap_pid)) == NULL) + if ((tp = pfindr(udata.au_aupinfo_addr.ap_pid)) == NULL) return (EINVAL); udata.au_aupinfo_addr.ap_auid = tp->p_ucred->cr_audit.ai_auid; @@ -390,7 +392,7 @@ tp->p_ucred->cr_audit.ai_termid; udata.au_aupinfo_addr.ap_asid = tp->p_ucred->cr_audit.ai_asid; - PROC_UNLOCK(tp); + PROC_RUNLOCK(tp); break; case A_GETKAUDIT: @@ -466,7 +468,7 @@ return (error); audit_arg_auid(id); newcred = crget(); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); oldcred = td->td_proc->p_ucred; crcopy(newcred, oldcred); #ifdef MAC @@ -479,11 +481,11 @@ goto fail; newcred->cr_audit.ai_auid = id; td->td_proc->p_ucred = newcred; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); crfree(oldcred); return (0); fail: - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); crfree(newcred); return (error); } @@ -529,7 +531,7 @@ return (error); audit_arg_auditinfo(&ai); newcred = crget(); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); oldcred = td->td_proc->p_ucred; crcopy(newcred, oldcred); #ifdef MAC @@ -548,11 +550,11 @@ newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port; newcred->cr_audit.ai_termid.at_type = AU_IPv4; td->td_proc->p_ucred = newcred; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); crfree(oldcred); return (0); fail: - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); crfree(newcred); return (error); } @@ -592,7 +594,7 @@ aia.ai_termid.at_type != AU_IPv4) return (EINVAL); newcred = crget(); - PROC_LOCK(td->td_proc); + PROC_WLOCK(td->td_proc); oldcred = td->td_proc->p_ucred; crcopy(newcred, oldcred); #ifdef MAC @@ -605,11 +607,11 @@ goto fail; newcred->cr_audit = aia; td->td_proc->p_ucred = newcred; - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); crfree(oldcred); return (0); fail: - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); crfree(newcred); return (error); } --- //depot/vendor/freebsd/src/sys/security/mac/mac_process.c 2007/04/22 19:57:25 +++ //depot/user/kris/contention/sys/security/mac/mac_process.c 2007/08/31 20:34:30 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -460,7 +461,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_debug, cred, p); @@ -472,7 +473,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_sched, cred, p); @@ -484,7 +485,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_signal, cred, p, signum); @@ -496,7 +497,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setuid, cred, uid); return (error); @@ -507,7 +508,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_seteuid, cred, euid); return (error); @@ -518,7 +519,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setgid, cred, gid); @@ -530,7 +531,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setegid, cred, egid); @@ -543,7 +544,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setgroups, cred, ngroups, gidset); return (error); @@ -555,7 +556,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setreuid, cred, ruid, euid); @@ -568,7 +569,7 @@ { int error; - PROC_LOCK_ASSERT(proc, MA_OWNED); + PROC_LOCK_ASSERT(proc, RA_LOCKED); MAC_CHECK(check_proc_setregid, cred, rgid, egid); @@ -581,7 +582,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setresuid, cred, ruid, euid, suid); return (error); @@ -593,7 +594,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_setresgid, cred, rgid, egid, sgid); @@ -605,7 +606,7 @@ { int error; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); MAC_CHECK(check_proc_wait, cred, p); --- //depot/vendor/freebsd/src/sys/security/mac/mac_syscalls.c 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/security/mac/mac_syscalls.c 2007/08/31 20:34:30 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -84,7 +85,7 @@ if (error) return (error); - tproc = pfind(uap->pid); + tproc = pfindr(uap->pid); if (tproc == NULL) return (ESRCH); @@ -92,7 +93,7 @@ error = p_cansee(td, tproc); if (error == 0) tcred = crhold(tproc->p_ucred); - PROC_UNLOCK(tproc); + PROC_RUNLOCK(tproc); if (error) return (error); @@ -183,12 +184,12 @@ newcred = crget(); p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); oldcred = p->p_ucred; error = mac_check_cred_relabel(oldcred, intlabel); if (error) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); crfree(newcred); goto out; } @@ -203,7 +204,7 @@ * releasing the proc lock and sharing the cred. */ crhold(newcred); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); mac_cred_mmapped_drop_perms(td, newcred); --- //depot/vendor/freebsd/src/sys/security/mac_lomac/mac_lomac.c 2007/09/10 00:02:48 +++ //depot/user/kris/contention/sys/security/mac_lomac/mac_lomac.c 2007/09/14 21:34:44 @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -2789,7 +2790,7 @@ * user of subj->mtx wouldn't be holding Giant. */ mtx_lock(&Giant); - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&subj->mtx); /* * Check if we lost the race while allocating the cred. @@ -2807,7 +2808,7 @@ dodrop = 1; out: mtx_unlock(&subj->mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); if (dodrop) mac_cred_mmapped_drop_perms(curthread, newcred); mtx_unlock(&Giant); --- //depot/vendor/freebsd/src/sys/sparc64/sparc64/machdep.c 2007/06/16 23:28:17 +++ //depot/user/kris/contention/sys/sparc64/sparc64/machdep.c 2007/08/31 20:34:30 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -435,6 +436,7 @@ msgbufinit(msgbufp, MSGBUF_SIZE); mutex_init(); + rwlock_init(); intr_init2(); /* @@ -476,7 +478,7 @@ oonstack = 0; td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); @@ -514,7 +516,7 @@ } else sfp = (struct sigframe *)sp - 1; mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); fp = (struct frame *)sfp - 1; @@ -547,7 +549,7 @@ * ...Kill the process. */ CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); /* NOTREACHED */ } @@ -559,7 +561,7 @@ CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, tf->tf_sp); - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -582,7 +584,7 @@ p = td->td_proc; if (rwindow_save(td)) { - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -597,11 +599,11 @@ if (error != 0) return (error); - PROC_LOCK(p); + PROC_WLOCK(p); td->td_sigmask = uc.uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate); --- //depot/vendor/freebsd/src/sys/sparc64/sparc64/mem.c 2007/05/20 13:08:23 +++ //depot/user/kris/contention/sys/sparc64/sparc64/mem.c 2007/07/26 22:46:10 @@ -101,8 +101,6 @@ error = 0; ova = 0; - GIANT_REQUIRED; - while (uio->uio_resid > 0 && error == 0) { iov = uio->uio_iov; if (iov->iov_len == 0) { --- //depot/vendor/freebsd/src/sys/sparc64/sparc64/trap.c 2007/06/04 21:44:15 +++ //depot/user/kris/contention/sys/sparc64/sparc64/trap.c 2007/08/31 20:34:30 @@ -439,9 +439,9 @@ * Keep swapout from messing with us during this * critical time. */ - PROC_LOCK(p); + PROC_WLOCK(p); ++p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Fault in the user page. */ rv = vm_fault(&vm->vm_map, va, prot, flags); @@ -449,9 +449,9 @@ /* * Now the process can be swapped again. */ - PROC_LOCK(p); + PROC_WLOCK(p); --p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * This is a fault on kernel virtual memory. Attempts to --- //depot/vendor/freebsd/src/sys/sun4v/sun4v/machdep.c 2007/06/16 22:33:50 +++ //depot/user/kris/contention/sys/sun4v/sun4v/machdep.c 2007/08/31 20:34:30 @@ -66,6 +66,7 @@ #include #include #include +#include #include #include #include @@ -498,6 +499,9 @@ BVPRINTF("initialize mutexes\n"); mutex_init(); + + BVPRINTF("initialize rw locks\n"); + rwlock_init(); BVPRINTF("initialize machine descriptor table\n"); mdesc_init(); @@ -540,7 +544,7 @@ oonstack = 0; td = curthread; p = td->td_proc; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); sig = ksi->ksi_signo; code = ksi->ksi_code; psp = p->p_sigacts; @@ -579,7 +583,7 @@ } else sfp = (struct sigframe *)sp - 1; mtx_unlock(&psp->ps_mtx); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); fp = (struct frame *)sfp - 1; @@ -616,7 +620,7 @@ * ...Kill the process. */ CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); /* NOTREACHED */ } @@ -628,7 +632,7 @@ CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc, tf->tf_sp); - PROC_LOCK(p); + PROC_WLOCK(p); mtx_lock(&psp->ps_mtx); } @@ -651,7 +655,7 @@ p = td->td_proc; if (rwindow_save(td)) { - PROC_LOCK(p); + PROC_WLOCK(p); sigexit(td, SIGILL); } @@ -666,11 +670,11 @@ if (error != 0) return (error); - PROC_LOCK(p); + PROC_WLOCK(p); td->td_sigmask = uc.uc_sigmask; SIG_CANTMASK(td->td_sigmask); signotify(td); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); CTR4(KTR_SIG, "sigreturn: return td=%p pc=%#lx sp=%#lx tstate=%#lx", td, mc->mc_tpc, mc->mc_sp, mc->mc_tstate); --- //depot/vendor/freebsd/src/sys/sun4v/sun4v/trap.c 2007/06/16 22:33:50 +++ //depot/user/kris/contention/sys/sun4v/sun4v/trap.c 2007/08/31 20:34:30 @@ -522,9 +522,9 @@ * Keep swapout from messing with us during this * critical time. */ - PROC_LOCK(p); + PROC_WLOCK(p); ++p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); /* Fault in the user page. */ rv = vm_fault(&vm->vm_map, va, prot, flags); @@ -532,9 +532,9 @@ /* * Now the process can be swapped again. */ - PROC_LOCK(p); + PROC_WLOCK(p); --p->p_lock; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } else { /* * This is a fault on kernel virtual memory. Attempts to --- //depot/vendor/freebsd/src/sys/sys/_sx.h 2007/03/31 23:26:09 +++ //depot/user/kris/contention/sys/sys/_sx.h 2007/05/24 21:02:07 @@ -1,43 +1,15 @@ -/*- - * Copyright (c) 2007 Attilio Rao - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * $FreeBSD: src/sys/sys/_sx.h,v 1.1 2007/03/31 23:23:42 jhb Exp $ - */ - #ifndef _SYS__SX_H_ #define _SYS__SX_H_ /* - * Shared/exclusive lock main structure definition. + * Shared/Exclusive locks main structure definition. */ struct sx { struct lock_object lock_object; volatile uintptr_t sx_lock; volatile unsigned sx_recurse; + const char *sx_desc; }; -#endif /* !_SYS__SX_H_ */ +#endif + --- //depot/vendor/freebsd/src/sys/sys/callout.h 2007/05/11 20:53:55 +++ //depot/user/kris/contention/sys/sys/callout.h 2007/08/31 20:34:30 @@ -40,7 +40,7 @@ #include -struct mtx; +struct lock_object; SLIST_HEAD(callout_list, callout); TAILQ_HEAD(callout_tailq, callout); @@ -53,7 +53,7 @@ int c_time; /* ticks to the event */ void *c_arg; /* function argument */ void (*c_func)(void *); /* function to call */ - struct mtx *c_mtx; /* mutex to lock */ + struct lock_object *c_lock; /* lock */ int c_flags; /* state of this entry */ }; @@ -61,8 +61,8 @@ #define CALLOUT_ACTIVE 0x0002 /* callout is currently active */ #define CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */ #define CALLOUT_MPSAFE 0x0008 /* callout handler is mp safe */ -#define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with mtx unlocked */ -#define CALLOUT_NETGIANT 0x0020 /* XXX: obtain Giant before mutex */ +#define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with lock unlocked */ +#define CALLOUT_NETGIANT 0x0020 /* XXX: obtain Giant before lock */ struct callout_handle { struct callout *callout; @@ -80,7 +80,11 @@ #define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE) #define callout_drain(c) _callout_stop_safe(c, 1) void callout_init(struct callout *, int); -void callout_init_mtx(struct callout *, struct mtx *, int); +void _callout_init_lock(struct callout *, struct lock_object *, int); +#define callout_init_lock(c, lock, flags) \ + _callout_init_lock((c), &(lock)->lock_object, (flags)) +#define callout_init_mtx(c, lock, flags) \ + callout_init_lock((c), (lock), (flags)) #define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING) int callout_reset(struct callout *, int, void (*)(void *), void *); #define callout_stop(c) _callout_stop_safe(c, 0) --- //depot/vendor/freebsd/src/sys/sys/disk.h 2007/05/05 17:07:34 +++ //depot/user/kris/contention/sys/sys/disk.h 2007/05/12 21:25:58 @@ -57,7 +57,7 @@ * Enable/Disable (the argument is boolean) the device for kernel * core dumps. */ - + #define DIOCGFRONTSTUFF _IOR('d', 134, off_t) /*- * Many disk formats have some amount of space reserved at the @@ -71,7 +71,11 @@ * Flush write cache of the device. */ -#define DIOCGDELETE _IOW('d', 136, off_t[2]) /* Delete data */ +struct g_offlen { + off_t offset; + off_t length; +}; +#define DIOCGDELETE _IOW('d', 136, struct g_offlen) /* Delete data */ /*- * Mark data on the device as unused. */ --- //depot/vendor/freebsd/src/sys/sys/file.h 2007/01/05 20:03:21 +++ //depot/user/kris/contention/sys/sys/file.h 2007/08/16 16:17:38 @@ -92,6 +92,7 @@ #define DFLAG_PASSABLE 0x01 /* may be passed via unix sockets. */ #define DFLAG_SEEKABLE 0x02 /* seekable / nonsequential */ +#define DFLAG_MPSAFE 0x04 /* These fileops are MPSAFE */ /* * Kernel descriptor table. @@ -99,49 +100,37 @@ * * Below is the list of locks that protects members in struct file. * - * (fl) filelist_lock - * (f) f_mtx in struct file + * (f) protected with mtx_lock(mtx_pool_find(fp)) * none not locked */ struct file { - LIST_ENTRY(file) f_list;/* (fl) list of active files */ - short f_type; /* descriptor type */ - void *f_data; /* file descriptor specific data */ - u_int f_flag; /* see fcntl.h */ - struct mtx *f_mtxp; /* mutex to protect data */ - struct fileops *f_ops; /* File operations */ - struct ucred *f_cred; /* credentials associated with descriptor */ - int f_count; /* (f) reference count */ - struct vnode *f_vnode; /* NULL or applicable vnode */ + void *f_data; /* file descriptor specific data */ + struct fileops *f_ops; /* File operations */ + struct ucred *f_cred; /* associated credentials. */ + struct vnode *f_vnode; /* NULL or applicable vnode */ + short f_type; /* descriptor type */ + short f_vnread_flags; /* (f) Sleep lock for f_offset */ + volatile u_int f_flag; /* see fcntl.h */ + volatile int f_count; /* reference count */ + /* + * DTYPE_VNODE specific fields. + */ + int f_seqcount; /* Count of sequential accesses. */ + off_t f_nextoff; /* next expected read/write offset. */ + /* + * DFLAG_SEEKABLE specific fields + */ + off_t f_offset; + /* + * Mandatory Access control information. + */ + void *f_label; /* Place-holder for MAC label. */ +}; - /* DFLAG_SEEKABLE specific fields */ - off_t f_offset; - short f_vnread_flags; /* - * (f) home grown sleep lock for f_offset - * Used only for shared vnode locking in - * vnread() - */ -#define FOFFSET_LOCKED 0x1 -#define FOFFSET_LOCK_WAITING 0x2 - /* DTYPE_SOCKET specific fields */ - short f_gcflag; /* used by thread doing fd garbage collection */ -#define FMARK 0x1 /* mark during gc() */ -#define FDEFER 0x2 /* defer for next gc pass */ -#define FWAIT 0x4 /* gc is scanning message buffers */ - int f_msgcount; /* (f) references from message queue */ +#define FOFFSET_LOCKED 0x1 +#define FOFFSET_LOCK_WAITING 0x2 - /* DTYPE_VNODE specific fields */ - int f_seqcount; /* - * count of sequential accesses -- cleared - * by most seek operations. - */ - off_t f_nextoff; /* - * offset of next expected read or write - */ - void *f_label; /* Place-holder for struct label pointer. */ -}; - #endif /* _KERNEL */ /* @@ -168,20 +157,17 @@ MALLOC_DECLARE(M_FILE); #endif -LIST_HEAD(filelist, file); -extern struct filelist filehead; /* (fl) head of list of open files */ extern struct fileops vnops; extern struct fileops badfileops; extern struct fileops socketops; extern int maxfiles; /* kernel limit on number of open files */ extern int maxfilesperproc; /* per process limit on number of open files */ -extern int openfiles; /* (fl) actual number of open files */ -extern struct sx filelist_lock; /* sx to protect filelist and openfiles */ +extern volatile int openfiles; /* actual number of open files */ int fget(struct thread *td, int fd, struct file **fpp); int fget_read(struct thread *td, int fd, struct file **fpp); int fget_write(struct thread *td, int fd, struct file **fpp); -int fdrop(struct file *fp, struct thread *td); +int _fdrop(struct file *fp, struct thread *td); /* * The socket operations are used a couple of places. @@ -196,12 +182,7 @@ fo_stat_t soo_stat; fo_close_t soo_close; -/* Lock a file. */ -#define FILE_LOCK(f) mtx_lock((f)->f_mtxp) -#define FILE_UNLOCK(f) mtx_unlock((f)->f_mtxp) -#define FILE_LOCKED(f) mtx_owned((f)->f_mtxp) -#define FILE_LOCK_ASSERT(f, type) mtx_assert((f)->f_mtxp, (type)) - +void finit(struct file *, u_int, short, void *, struct fileops *); int fgetvp(struct thread *td, int fd, struct vnode **vpp); int fgetvp_read(struct thread *td, int fd, struct vnode **vpp); int fgetvp_write(struct thread *td, int fd, struct vnode **vpp); @@ -209,18 +190,9 @@ int fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp); void fputsock(struct socket *sp); -#define fhold_locked(fp) \ - do { \ - FILE_LOCK_ASSERT(fp, MA_OWNED); \ - (fp)->f_count++; \ - } while (0) - -#define fhold(fp) \ - do { \ - FILE_LOCK(fp); \ - (fp)->f_count++; \ - FILE_UNLOCK(fp); \ - } while (0) +#define fhold(fp) atomic_add_int(&(fp)->f_count, 1) +#define fdrop(fp, td) \ + (atomic_fetchadd_int(&(fp)->f_count, -1) <= 1 ? _fdrop((fp), (td)) : 0) static __inline fo_rdwr_t fo_read; static __inline fo_rdwr_t fo_write; --- //depot/vendor/freebsd/src/sys/sys/lock.h 2007/04/03 18:03:41 +++ //depot/user/kris/contention/sys/sys/lock.h 2007/08/31 20:34:30 @@ -60,6 +60,7 @@ void (*lc_ddb_show)(struct lock_object *lock); void (*lc_lock)(struct lock_object *lock, int how); int (*lc_unlock)(struct lock_object *lock); + int (*lc_locked)(struct lock_object *lock); }; #define LC_SLEEPLOCK 0x00000001 /* Sleep lock. */ @@ -328,8 +329,12 @@ WITNESS_CHECKORDER(&(l)->lock_object, LOP_EXCLUSIVE, LOCK_FILE, \ LOCK_LINE) -#define witness_check_shared(l) \ - WITNESS_CHECKORDER(&(l)->lock_object, 0, LOCK_FILE, LOCK_LINE) +#define witness_check_shared_sx(sx) \ + WITNESS_CHECKORDER(&(sx)->lock_object, LOP_NEWORDER, LOCK_FILE, LOCK_LINE) +#define witness_check_exclusive_sx(sx) \ + WITNESS_CHECKORDER(&(sx)->lock_object, LOP_NEWORDER | \ + LOP_EXCLUSIVE, LOCK_FILE, LOCK_LINE) + #endif /* _KERNEL */ #endif /* _SYS_LOCK_H_ */ --- //depot/vendor/freebsd/src/sys/sys/mutex.h 2007/08/06 14:28:11 +++ //depot/user/kris/contention/sys/sys/mutex.h 2007/08/10 15:36:57 @@ -181,8 +181,25 @@ */ #ifndef _get_spin_lock #ifdef SMP +#ifdef SPINLOCK_PROFILING +extern int spin_prof_enable; +extern u_int spin_count; +extern u_int spin_scale; #define _get_spin_lock(mp, tid, opts, file, line) do { \ uintptr_t _tid = (uintptr_t)(tid); \ + \ + spinlock_enter(); \ + if (!_obtain_lock((mp), _tid)) { \ + if ((mp)->mtx_lock == _tid) \ + (mp)->mtx_recurse++; \ + else \ + _mtx_lock_spin((mp), _tid, (opts), (file), (line)); \ + } else if (spin_prof_enable && !(++spin_count % spin_scale)) \ + CTR3(KTR_CONTENTION, "%p %s:%d", mp, file, line); \ +} while (0) +#else /* !SPINLOCK_PROFILING */ +#define _get_spin_lock(mp, tid, opts, file, line) do { \ + uintptr_t _tid = (uintptr_t)(tid); \ spinlock_enter(); \ if (!_obtain_lock((mp), _tid)) { \ if ((mp)->mtx_lock == _tid) \ @@ -194,6 +211,7 @@ lock_profile_obtain_lock_success(&(mp)->lock_object, 0, \ 0, (file), (line)); \ } while (0) +#endif /* SPINLOCK_PROFILING */ #else /* SMP */ #define _get_spin_lock(mp, tid, opts, file, line) do { \ uintptr_t _tid = (uintptr_t)(tid); \ --- //depot/vendor/freebsd/src/sys/sys/proc.h 2007/07/27 09:22:31 +++ //depot/user/kris/contention/sys/sys/proc.h 2007/08/31 20:34:30 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include /* XXX. */ #include @@ -127,7 +128,7 @@ * b - created at fork, never changes * (exception aiods switch vmspaces, but they are also * marked 'P_SYSTEM' so hopefully it will be left alone) - * c - locked by proc mtx + * c - locked by proc lock * d - locked by allproc_lock lock * e - locked by proctree_lock lock * f - session mtx @@ -141,7 +142,6 @@ * m - Giant * n - not locked, lazy * o - ktrace lock - * p - select lock (sellock) * q - td_contested lock * r - p_peers lock * t - thread lock @@ -209,7 +209,7 @@ TAILQ_ENTRY(thread) td_slpq; /* (t) Sleep queue. */ TAILQ_ENTRY(thread) td_lockq; /* (t) Lock queue. */ - TAILQ_HEAD(, selinfo) td_selq; /* (p) List of selinfos. */ + struct seltd *td_sel; /* Select queue/channel. */ struct sleepqueue *td_sleepqueue; /* (k) Associated sleep queue. */ struct turnstile *td_turnstile; /* (k) Associated turnstile. */ struct umtx_q *td_umtxq; /* (c?) Link for when we're blocked. */ @@ -319,7 +319,7 @@ #define TDF_SINTR 0x00000008 /* Sleep is interruptible. */ #define TDF_TIMEOUT 0x00000010 /* Timing out during sleep. */ #define TDF_IDLETD 0x00000020 /* This is a per-CPU idle thread. */ -#define TDF_SELECT 0x00000040 /* Selecting; wakeup/waiting danger. */ +#define TDF_UNUSEDx40 0x00000040 /* --available-- */ #define TDF_SLEEPABORT 0x00000080 /* sleepq_abort was called. */ #define TDF_UNUSEDx100 0x00000100 /* --available-- */ #define TDF_UBORROWING 0x00000200 /* Thread is borrowing user pri. */ @@ -508,7 +508,7 @@ struct proc *p_pptr; /* (c + e) Pointer to parent process. */ LIST_ENTRY(proc) p_sibling; /* (e) List of sibling processes. */ LIST_HEAD(, proc) p_children; /* (e) Pointer to list of children. */ - struct mtx p_mtx; /* (n) Lock for this struct. */ + struct rwlock p_rwlock; /* (n) Lock for this struct. */ struct ksiginfo *p_ksi; /* Locked by parent proc lock */ sigqueue_t p_sigqueue; /* (c) Sigs not delivered to a td. */ #define p_siglist p_sigqueue.sq_signals @@ -691,25 +691,28 @@ #define STOPEVENT(p, e, v) do { \ if ((p)->p_stops & (e)) { \ - PROC_LOCK(p); \ + PROC_WLOCK(p); \ stopevent((p), (e), (v)); \ - PROC_UNLOCK(p); \ + PROC_WUNLOCK(p); \ } \ } while (0) #define _STOPEVENT(p, e, v) do { \ - PROC_LOCK_ASSERT(p, MA_OWNED); \ - WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, &p->p_mtx.lock_object, \ + PROC_LOCK_ASSERT(p, RA_LOCKED); \ + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, &p->p_rwlock.lock_object, \ "checking stopevent %d", (e)); \ if ((p)->p_stops & (e)) \ stopevent((p), (e), (v)); \ } while (0) /* Lock and unlock a process. */ -#define PROC_LOCK(p) mtx_lock(&(p)->p_mtx) -#define PROC_TRYLOCK(p) mtx_trylock(&(p)->p_mtx) -#define PROC_UNLOCK(p) mtx_unlock(&(p)->p_mtx) -#define PROC_LOCKED(p) mtx_owned(&(p)->p_mtx) -#define PROC_LOCK_ASSERT(p, type) mtx_assert(&(p)->p_mtx, (type)) +#define PROC_RLOCK(p) rw_rlock(&(p)->p_rwlock) +#define PROC_RUNLOCK(p) rw_runlock(&(p)->p_rwlock) +#define PROC_WLOCK(p) rw_wlock(&(p)->p_rwlock) +#define PROC_WUNLOCK(p) rw_wunlock(&(p)->p_rwlock) +#define PROC_LOCK_ASSERT(p, type) rw_assert(&(p)->p_rwlock, (type)) +#define PROC_TRY_UPGRADE(p) rw_try_upgrade(&(p)->p_rwlock) +#define PROC_DOWNGRADE(p) rw_downgrade(&(p)->p_rwlock) +#define PROC_TRYLOCK(p) rw_try_wlock(&(p)->p_rwlock) /* Lock and unlock a process group. */ #define PGRP_LOCK(pg) mtx_lock(&(pg)->pg_mtx) @@ -734,12 +737,12 @@ /* Hold process U-area in memory, normally for ptrace/procfs work. */ #define PHOLD(p) do { \ - PROC_LOCK(p); \ + PROC_WLOCK(p); \ _PHOLD(p); \ - PROC_UNLOCK(p); \ + PROC_WUNLOCK(p); \ } while (0) #define _PHOLD(p) do { \ - PROC_LOCK_ASSERT((p), MA_OWNED); \ + PROC_LOCK_ASSERT((p), RA_LOCKED); \ KASSERT(!((p)->p_flag & P_WEXIT) || (p) == curproc, \ ("PHOLD of exiting process")); \ (p)->p_lock++; \ @@ -751,12 +754,12 @@ } while (0) #define PRELE(p) do { \ - PROC_LOCK((p)); \ + PROC_WLOCK((p)); \ _PRELE((p)); \ - PROC_UNLOCK((p)); \ + PROC_WUNLOCK((p)); \ } while (0) #define _PRELE(p) do { \ - PROC_LOCK_ASSERT((p), MA_OWNED); \ + PROC_LOCK_ASSERT((p), RA_LOCKED); \ (--(p)->p_lock); \ if (((p)->p_flag & P_WEXIT) && (p)->p_lock == 0) \ wakeup(&(p)->p_lock); \ @@ -810,7 +813,8 @@ extern struct uma_zone *proc_zone; -struct proc *pfind(pid_t); /* Find process by id. */ +struct proc *pfind(pid_t); /* Find process by id (write-lock). */ +struct proc *pfindr(pid_t); /* Find process by id (read-lock). */ struct pgrp *pgfind(pid_t); /* Find process group by id. */ struct proc *zpfind(pid_t); /* Find zombie process by id. */ --- //depot/vendor/freebsd/src/sys/sys/ptrace.h 2006/02/06 09:47:34 +++ //depot/user/kris/contention/sys/sys/ptrace.h 2007/08/31 20:34:30 @@ -102,9 +102,9 @@ #define PTRACESTOP_SC(p, td, flag) \ if ((p)->p_flag & P_TRACED && (p)->p_stops & (flag)) { \ - PROC_LOCK(p); \ + PROC_WLOCK(p); \ ptracestop((td), SIGTRAP); \ - PROC_UNLOCK(p); \ + PROC_WUNLOCK(p); \ } /* * The flags below are used for ptrace(2) tracing and have no relation --- //depot/vendor/freebsd/src/sys/sys/rwlock.h 2007/07/20 08:48:10 +++ //depot/user/kris/contention/sys/sys/rwlock.h 2007/08/31 20:34:30 @@ -127,11 +127,14 @@ void rw_init_flags(struct rwlock *rw, const char *name, int opts); void rw_destroy(struct rwlock *rw); void rw_sysinit(void *arg); +void rwlock_init(void); int rw_wowned(struct rwlock *rw); void _rw_wlock(struct rwlock *rw, const char *file, int line); void _rw_wunlock(struct rwlock *rw, const char *file, int line); +int _rw_try_wlock(struct rwlock *rw, const char *file, int line); void _rw_rlock(struct rwlock *rw, const char *file, int line); void _rw_runlock(struct rwlock *rw, const char *file, int line); +int _rw_try_rlock(struct rwlock *rw, const char *file, int line); void _rw_wlock_hard(struct rwlock *rw, uintptr_t tid, const char *file, int line); void _rw_wunlock_hard(struct rwlock *rw, uintptr_t tid, const char *file, @@ -144,8 +147,6 @@ /* * Public interface for lock operations. - * - * XXX: Missing try locks. */ #ifndef LOCK_DEBUG @@ -166,6 +167,8 @@ #define rw_downgrade(rw) _rw_downgrade((rw), LOCK_FILE, LOCK_LINE) #define rw_sleep(chan, rw, pri, wmesg, timo) \ _sleep((chan), &(rw)->lock_object, (pri), (wmesg), (timo)) +#define rw_try_wlock(rw) _rw_try_wlock((rw), LOCK_FILE, LOCK_LINE) +#define rw_try_rlock(rw) _rw_try_rlock((rw), LOCK_FILE, LOCK_LINE) #define rw_initialized(rw) lock_initalized(&(rw)->lock_object) --- //depot/vendor/freebsd/src/sys/sys/selinfo.h 2004/08/15 06:25:49 +++ //depot/user/kris/contention/sys/sys/selinfo.h 2007/08/16 16:03:09 @@ -35,26 +35,26 @@ #include /* for struct klist */ +struct selfd; +TAILQ_HEAD(selfdlist, selfd); + /* * Used to maintain information about processes that wish to be * notified when I/O becomes possible. */ struct selinfo { - TAILQ_ENTRY(selinfo) si_thrlist; /* list hung off of thread */ - struct thread *si_thread; /* thread waiting */ - struct knlist si_note; /* kernel note list */ - short si_flags; /* see below */ + struct selfdlist si_tdlist; /* List of sleeping threads. */ + struct knlist si_note; /* kernel note list */ + struct mtx *si_mtx; /* Lock for tdlist. */ }; -#define SI_COLL 0x0001 /* collision occurred */ -#define SEL_WAITING(si) \ - ((si)->si_thread != NULL || ((si)->si_flags & SI_COLL) != 0) +#define SEL_WAITING(si) (!TAILQ_EMPTY(&(si)->si_tdlist)) #ifdef _KERNEL -void clear_selinfo_list(struct thread *td); void selrecord(struct thread *selector, struct selinfo *sip); void selwakeup(struct selinfo *sip); void selwakeuppri(struct selinfo *sip, int pri); +void seltdfini(struct thread *td); #endif #endif /* !_SYS_SELINFO_H_ */ --- //depot/vendor/freebsd/src/sys/sys/sem.h 2006/11/07 18:57:34 +++ //depot/user/kris/contention/sys/sys/sem.h 2007/03/02 13:35:42 @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/sys/sem.h,v 1.31 2006/11/07 18:56:48 jhb Exp $ */ +/* $FreeBSD: /repoman/r/ncvs/src/sys/sys/sem.h,v 1.31 2006/11/07 18:56:48 jhb Exp $ */ /* $NetBSD: sem.h,v 1.5 1994/06/29 06:45:15 cgd Exp $ */ /* @@ -103,6 +103,7 @@ struct semid_kernel { struct semid_ds u; struct label *label; /* MAC framework label */ + int sem_binary; /* flag for the type of semaphore */ }; /* internal "mode" bits */ --- //depot/vendor/freebsd/src/sys/sys/socketvar.h 2007/05/03 14:46:36 +++ //depot/user/kris/contention/sys/sys/socketvar.h 2007/08/16 16:03:09 @@ -546,6 +546,8 @@ int soshutdown(struct socket *so, int how); void sotoxsocket(struct socket *so, struct xsocket *xso); void sowakeup(struct socket *so, struct sockbuf *sb); +int selsocket(struct socket *so, int events, struct timeval *tv, + struct thread *td); #ifdef SOCKBUF_DEBUG void sblastrecordchk(struct sockbuf *, const char *, int); --- //depot/vendor/freebsd/src/sys/sys/sysctl.h 2007/06/04 18:18:07 +++ //depot/user/kris/contention/sys/sys/sysctl.h 2007/06/05 06:30:35 @@ -84,6 +84,7 @@ #define CTLFLAG_SKIP 0x01000000 /* Skip this sysctl when listing */ #define CTLMASK_SECURE 0x00F00000 /* Secure level */ #define CTLFLAG_TUN 0x00080000 /* Tunable variable */ +#define CTLFLAG_MPSAFE 0x00040000 /* Handler is MP safe */ #define CTLFLAG_RDTUN (CTLFLAG_RD|CTLFLAG_TUN) /* @@ -112,6 +113,15 @@ #define CTL_AUTO_START 0x100 #ifdef _KERNEL + +/* sx lock for manipulating the sysctl tree */ +extern struct sx sysctl_tree_sx; + +#define SYSCTL_TREE_XLOCK() sx_xlock(&sysctl_tree_sx) +#define SYSCTL_TREE_XUNLOCK() sx_xunlock(&sysctl_tree_sx) +#define SYSCTL_TREE_SLOCK() sx_slock(&sysctl_tree_sx) +#define SYSCTL_TREE_SUNLOCK() sx_sunlock(&sysctl_tree_sx) + #define SYSCTL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, int arg2, \ struct sysctl_req *req @@ -162,6 +172,7 @@ const char *oid_fmt; int oid_refcnt; const char *oid_descr; + u_long oid_counter; }; #define SYSCTL_IN(r, p, l) (r->newfunc)(r, p, l) --- //depot/vendor/freebsd/src/sys/sys/systm.h 2007/07/04 06:57:24 +++ //depot/user/kris/contention/sys/sys/systm.h 2007/08/16 16:03:09 @@ -56,10 +56,6 @@ extern int nswap; /* size of swap space */ -extern u_int nselcoll; /* select collisions since boot */ -extern struct mtx sellock; /* select lock variable */ -extern struct cv selwait; /* select conditional variable */ - extern long physmem; /* physical memory */ extern long realmem; /* 'real' memory */ --- //depot/vendor/freebsd/src/sys/sys/unpcb.h 2007/02/26 20:49:00 +++ //depot/user/kris/contention/sys/sys/unpcb.h 2007/08/16 16:17:38 @@ -67,6 +67,7 @@ struct unpcb { LIST_ENTRY(unpcb) unp_link; /* glue on list of all PCBs */ struct socket *unp_socket; /* pointer back to socket */ + struct file *unp_file; /* back-pointer to file for gc. */ struct vnode *unp_vnode; /* if associated with file */ ino_t unp_ino; /* fake inode number */ struct unpcb *unp_conn; /* control block of connected socket */ @@ -76,9 +77,11 @@ int unp_cc; /* copy of rcv.sb_cc */ int unp_mbcnt; /* copy of rcv.sb_mbcnt */ unp_gen_t unp_gencnt; /* generation count of this instance */ - int unp_flags; /* flags */ + short unp_flags; /* flags */ + short unp_gcflag; /* Garbage collector flags. */ struct xucred unp_peercred; /* peer credentials, if applicable */ u_int unp_refcount; + u_int unp_msgcount; /* references from message queue */ struct mtx unp_mtx; /* mutex */ }; @@ -100,6 +103,14 @@ #define UNP_WANTCRED 0x004 /* credentials wanted */ #define UNP_CONNWAIT 0x008 /* connect blocks until accepted */ +#define UNPGC_REF 0x1 /* unpcb has external ref. */ +#define UNPGC_DEAD 0x2 /* unpcb might be dead. */ +#define UNPGC_SCANNED 0x4 /* Has been scanned. */ + +#define UNPGC_REF 0x1 /* unpcb has external ref. */ +#define UNPGC_DEAD 0x2 /* unpcb might be dead. */ +#define UNPGC_SCANNED 0x4 /* Has been scanned. */ + /* * These flags are used to handle non-atomicity in connect() and bind() * operations on a socket: in particular, to avoid races between multiple --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_alloc.c 2007/09/10 14:12:54 +++ //depot/user/kris/contention/sys/ufs/ffs/ffs_alloc.c 2007/09/14 21:34:44 @@ -79,6 +79,8 @@ #include #include +#include + #include #include #include @@ -1832,7 +1834,7 @@ struct buf *bp; ufs1_daddr_t fragno, cgbno; ufs2_daddr_t cgblkno; - int i, cg, blk, frags, bbase; + int i, cg, blk, frags, bbase, error; u_int8_t *blksfree; struct cdev *dev; @@ -1943,6 +1945,9 @@ ACTIVECLEAR(fs, cg); UFS_UNLOCK(ump); bdwrite(bp); + error = g_delete_data(ump->um_cp, bno * fs->fs_fsize, size); + if (error != 0 && error != EOPNOTSUPP) + ffs_fserr(fs, inum, "cannot delete data"); } #ifdef DIAGNOSTIC --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_rawread.c 2007/02/04 23:46:56 +++ //depot/user/kris/contention/sys/ufs/ffs/ffs_rawread.c 2007/08/31 20:34:30 @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_snapshot.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/ufs/ffs/ffs_snapshot.c 2007/08/31 20:34:30 @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -392,12 +393,12 @@ struct proc *p; p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); saved_nice = p->p_nice; sched_nice(p, 0); PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } /* * Suspend operation on filesystem. @@ -815,11 +816,11 @@ struct proc *p; p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); sched_nice(td->td_proc, saved_nice); PROC_SUNLOCK(p); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); } UFS_LOCK(ump); if (fs->fs_active != 0) { --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_softdep.c 2007/06/22 13:23:10 +++ //depot/user/kris/contention/sys/ufs/ffs/ffs_softdep.c 2007/08/31 20:34:30 @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_vfsops.c 2007/04/04 07:32:11 +++ //depot/user/kris/contention/sys/ufs/ffs/ffs_vfsops.c 2007/04/06 22:35:04 @@ -881,6 +881,9 @@ #endif /* !UFS_EXTATTR_AUTOSTART */ #endif /* !UFS_EXTATTR */ MNT_ILOCK(mp); +#ifndef NO_UFS_LOOKUP_SHARED + mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED; +#endif mp->mnt_kern_flag |= MNTK_MPSAFE; MNT_IUNLOCK(mp); return (0); --- //depot/vendor/freebsd/src/sys/ufs/ffs/ffs_vnops.c 2007/07/13 18:53:41 +++ //depot/user/kris/contention/sys/ufs/ffs/ffs_vnops.c 2007/08/31 20:34:30 @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -680,14 +681,18 @@ */ td = uio->uio_td; if (vp->v_type == VREG && td != NULL) { - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (uio->uio_offset + uio->uio_resid > lim_cur(td->td_proc, RLIMIT_FSIZE)) { + if (!PROC_TRY_UPGRADE(td->td_proc)) { + PROC_RUNLOCK(td->td_proc); + PROC_WLOCK(td->td_proc); + } psignal(td->td_proc, SIGXFSZ); - PROC_UNLOCK(td->td_proc); + PROC_WUNLOCK(td->td_proc); return (EFBIG); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } resid = uio->uio_resid; --- //depot/vendor/freebsd/src/sys/ufs/ufs/ufs_lookup.c 2007/03/14 08:53:09 +++ //depot/user/kris/contention/sys/ufs/ufs/ufs_lookup.c 2007/04/03 18:43:03 @@ -166,6 +166,14 @@ vdp = ap->a_dvp; dp = VTOI(vdp); + +#ifndef NO_UFS_LOOKUP_SHARED + if ((vdp->v_mount->mnt_kern_flag & MNTK_LOOKUP_SHARED) && + (VOP_ISLOCKED(vdp, td) != LK_EXCLUSIVE)) { + /* Upgrade to exclusive lock, this might block */ + VOP_LOCK(vdp, LK_UPGRADE, td); + } +#endif /* * We now have a segment name to search for, and a directory to search. * --- //depot/vendor/freebsd/src/sys/vm/vm_glue.c 2007/06/05 00:03:37 +++ //depot/user/kris/contention/sys/vm/vm_glue.c 2007/08/31 20:34:30 @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -201,14 +202,14 @@ npages = atop(end - start); if (npages > vm_page_max_wired) return (ENOMEM); - PROC_LOCK(curproc); + PROC_RLOCK(curproc); if (ptoa(npages + pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map))) > lim_cur(curproc, RLIMIT_MEMLOCK)) { - PROC_UNLOCK(curproc); + PROC_RUNLOCK(curproc); return (ENOMEM); } - PROC_UNLOCK(curproc); + PROC_RUNLOCK(curproc); #if 0 /* * XXX - not yet @@ -600,19 +601,19 @@ { #ifdef NO_SWAPPING - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); if ((p->p_sflag & PS_INMEM) == 0) panic("faultin: proc swapped out with NO_SWAPPING!"); #else /* !NO_SWAPPING */ struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); /* * If another process is swapping in this process, * just wait until it finishes. */ if (p->p_sflag & PS_SWAPPINGIN) - msleep(&p->p_sflag, &p->p_mtx, PVM, "faultin", 0); + rw_sleep(&p->p_sflag, &p->p_rwlock, PVM, "faultin", 0); else if ((p->p_sflag & PS_INMEM) == 0) { /* * Don't let another thread swap process p out while we are @@ -622,12 +623,12 @@ PROC_SLOCK(p); p->p_sflag |= PS_SWAPPINGIN; PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); FOREACH_THREAD_IN_PROC(p, td) vm_thread_swapin(td); - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); p->p_sflag &= ~PS_SWAPPINGIN; p->p_sflag |= PS_INMEM; @@ -731,7 +732,7 @@ thread_unlock(&thread0); goto loop; } - PROC_LOCK(p); + PROC_WLOCK(p); /* * Another process may be bringing or may have already @@ -739,7 +740,7 @@ * Or, this process may even be being swapped out again. */ if (p->p_sflag & (PS_INMEM | PS_SWAPPINGOUT | PS_SWAPPINGIN)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(&thread0); proc0_rescan = 0; thread_unlock(&thread0); @@ -755,7 +756,7 @@ * [What checks the space? ] */ faultin(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); PROC_SLOCK(p); p->p_swtime = 0; PROC_SUNLOCK(p); @@ -863,7 +864,7 @@ if (!vm_map_trylock(&vm->vm_map)) goto nextproc1; - PROC_LOCK(p); + PROC_WLOCK(p); if (p->p_lock != 0 || (p->p_flag & (P_STOPPED_SINGLE|P_TRACED|P_SYSTEM|P_WEXIT) ) != 0) { @@ -938,7 +939,7 @@ swapout(p); didswap++; PROC_SUNLOCK(p); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); vm_map_unlock(&vm->vm_map); vmspace_free(vm); sx_sunlock(&allproc_lock); @@ -948,7 +949,7 @@ PROC_SUNLOCK(p); } nextproc2: - PROC_UNLOCK(p); + PROC_WUNLOCK(p); vm_map_unlock(&vm->vm_map); nextproc1: vmspace_free(vm); @@ -969,7 +970,7 @@ { struct thread *td; - PROC_LOCK_ASSERT(p, MA_OWNED); + PROC_LOCK_ASSERT(p, RA_LOCKED); mtx_assert(&p->p_slock, MA_OWNED | MA_NOTRECURSED); #if defined(SWAP_DEBUG) printf("swapping out %d\n", p->p_pid); @@ -1003,7 +1004,7 @@ p->p_sflag &= ~PS_INMEM; p->p_sflag |= PS_SWAPPINGOUT; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); FOREACH_THREAD_IN_PROC(p, td) { thread_lock(td); TD_SET_SWAPPED(td); @@ -1014,7 +1015,7 @@ FOREACH_THREAD_IN_PROC(p, td) vm_thread_swapout(td); - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); p->p_sflag &= ~PS_SWAPPINGOUT; p->p_swtime = 0; --- //depot/vendor/freebsd/src/sys/vm/vm_map.c 2007/08/20 12:07:05 +++ //depot/user/kris/contention/sys/vm/vm_map.c 2007/08/31 20:34:30 @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -2690,6 +2691,7 @@ vm_map_entry_t new_entry, prev_entry; vm_offset_t bot, top; vm_size_t init_ssize; + struct proc *p; int orient, rv; rlim_t vmemlim; @@ -2708,9 +2710,10 @@ init_ssize = (max_ssize < sgrowsiz) ? max_ssize : sgrowsiz; - PROC_LOCK(curthread->td_proc); - vmemlim = lim_cur(curthread->td_proc, RLIMIT_VMEM); - PROC_UNLOCK(curthread->td_proc); + p = curthread->td_proc; + PROC_RLOCK(p); + vmemlim = lim_cur(p, RLIMIT_VMEM); + PROC_RUNLOCK(p); vm_map_lock(map); @@ -2798,10 +2801,10 @@ int is_procstack, rv; Retry: - PROC_LOCK(p); + PROC_RLOCK(p); stacklim = lim_cur(p, RLIMIT_STACK); vmemlim = lim_cur(p, RLIMIT_VMEM); - PROC_UNLOCK(p); + PROC_RUNLOCK(p); vm_map_lock_read(map); --- //depot/vendor/freebsd/src/sys/vm/vm_meter.c 2007/07/27 20:02:32 +++ //depot/user/kris/contention/sys/vm/vm_meter.c 2007/07/28 20:19:27 @@ -89,7 +89,7 @@ #endif return SYSCTL_OUT(req, &averunnable, sizeof(averunnable)); } -SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT|CTLFLAG_RD, +SYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT|CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_loadavg, "S,loadavg", "Machine loadaverage history"); static int --- //depot/vendor/freebsd/src/sys/vm/vm_mmap.c 2007/08/20 12:07:05 +++ //depot/user/kris/contention/sys/vm/vm_mmap.c 2007/08/31 20:34:30 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include @@ -281,14 +282,14 @@ * There should really be a pmap call to determine a reasonable * location. */ - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (addr == 0 || (addr >= round_page((vm_offset_t)vms->vm_taddr) && addr < round_page((vm_offset_t)vms->vm_daddr + lim_max(td->td_proc, RLIMIT_DATA)))) addr = round_page((vm_offset_t)vms->vm_daddr + lim_max(td->td_proc, RLIMIT_DATA)); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); } if (flags & MAP_ANON) { /* @@ -702,9 +703,9 @@ error = priv_check(td, PRIV_VM_MADV_PROTECT); if (error == 0) { p = td->td_proc; - PROC_LOCK(p); + PROC_WLOCK(p); p->p_flag |= P_PROTECTED; - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } return (error); } @@ -980,14 +981,14 @@ if (npages > vm_page_max_wired) return (ENOMEM); proc = td->td_proc; - PROC_LOCK(proc); + PROC_RLOCK(proc); if (ptoa(npages + pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))) > lim_cur(proc, RLIMIT_MEMLOCK)) { - PROC_UNLOCK(proc); + PROC_RUNLOCK(proc); return (ENOMEM); } - PROC_UNLOCK(proc); + PROC_RUNLOCK(proc); if (npages + cnt.v_wire_count > vm_page_max_wired) return (EAGAIN); error = vm_map_wire(&proc->p_vmspace->vm_map, start, end, @@ -1023,13 +1024,13 @@ * If wiring all pages in the process would cause it to exceed * a hard resource limit, return ENOMEM. */ - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (map->size - ptoa(pmap_wired_count(vm_map_pmap(map)) > lim_cur(td->td_proc, RLIMIT_MEMLOCK))) { - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); return (ENOMEM); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); #else error = priv_check(td, PRIV_VM_MLOCK); if (error) @@ -1315,13 +1316,13 @@ size = round_page(size); - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); if (td->td_proc->p_vmspace->vm_map.size + size > lim_cur(td->td_proc, RLIMIT_VMEM)) { - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); return(ENOMEM); } - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); /* * We currently can only deal with page aligned file offsets. --- //depot/vendor/freebsd/src/sys/vm/vm_pageout.c 2007/07/02 06:57:53 +++ //depot/user/kris/contention/sys/vm/vm_pageout.c 2007/08/31 20:34:30 @@ -87,6 +87,7 @@ #include #include #include +#include #include #include #include @@ -447,7 +448,8 @@ for (i = 0; i < count; i++) { vm_page_t mt = mc[i]; - KASSERT((mt->flags & PG_WRITEABLE) == 0, + KASSERT(pageout_status[i] == VM_PAGER_PEND || + (mt->flags & PG_WRITEABLE) == 0, ("vm_pageout_flush: page %p is not write protected", mt)); switch (pageout_status[i]) { case VM_PAGER_OK: @@ -1228,7 +1230,7 @@ if ((p->p_flag & P_SYSTEM) || (p->p_pid == 1) || (p->p_flag & P_PROTECTED) || ((p->p_pid < 48) && (swap_pager_avail != 0))) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } /* @@ -1250,14 +1252,14 @@ } PROC_SUNLOCK(p); if (breakout) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } /* * get the process size */ if (!vm_map_trylock_read(&p->p_vmspace->vm_map)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } size = vmspace_swap_count(p->p_vmspace); @@ -1269,11 +1271,11 @@ */ if (size > bigsize) { if (bigproc != NULL) - PROC_UNLOCK(bigproc); + PROC_WUNLOCK(bigproc); bigproc = p; bigsize = size; } else - PROC_UNLOCK(p); + PROC_WUNLOCK(p); } sx_sunlock(&allproc_lock); if (bigproc != NULL) { @@ -1281,7 +1283,7 @@ PROC_SLOCK(bigproc); sched_nice(bigproc, PRIO_MIN); PROC_SUNLOCK(bigproc); - PROC_UNLOCK(bigproc); + PROC_WUNLOCK(bigproc); wakeup(&cnt.v_free_count); } } @@ -1554,7 +1556,6 @@ static void vm_daemon() { - struct rlimit rsslim; struct proc *p; struct thread *td; int breakout, swapout_flags; @@ -1580,9 +1581,9 @@ * if this is a system process or if we have already * looked at this process, skip it. */ - PROC_LOCK(p); + PROC_RLOCK(p); if (p->p_flag & (P_SYSTEM | P_WEXIT)) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } /* @@ -1604,24 +1605,25 @@ } PROC_SUNLOCK(p); if (breakout) { - PROC_UNLOCK(p); + PROC_RUNLOCK(p); continue; } /* - * get a limit - */ - lim_rlimit(p, RLIMIT_RSS, &rsslim); - limit = OFF_TO_IDX( - qmin(rsslim.rlim_cur, rsslim.rlim_max)); - - /* * let processes that are swapped out really be * swapped out set the limit to nothing (will force a * swap-out.) */ if ((p->p_sflag & PS_INMEM) == 0) limit = 0; /* XXX */ - PROC_UNLOCK(p); + else { + struct rlimit rsslim; + + /* get a limit */ + lim_rlimit(p, RLIMIT_RSS, &rsslim); + limit = OFF_TO_IDX(qmin(rsslim.rlim_cur, + rsslim.rlim_max)); + } + PROC_RUNLOCK(p); size = vmspace_resident_count(p->p_vmspace); if (limit >= 0 && size >= limit) { --- //depot/vendor/freebsd/src/sys/vm/vm_unix.c 2005/01/07 02:32:16 +++ //depot/user/kris/contention/sys/vm/vm_unix.c 2007/08/31 20:34:30 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -78,10 +79,10 @@ int error = 0; boolean_t do_map_wirefuture; - PROC_LOCK(td->td_proc); + PROC_RLOCK(td->td_proc); datalim = lim_cur(td->td_proc, RLIMIT_DATA); vmemlim = lim_cur(td->td_proc, RLIMIT_VMEM); - PROC_UNLOCK(td->td_proc); + PROC_RUNLOCK(td->td_proc); do_map_wirefuture = FALSE; new = round_page((vm_offset_t)uap->nsize); --- //depot/vendor/freebsd/src/sys/vm/vm_zeroidle.c 2007/07/14 19:07:58 +++ //depot/user/kris/contention/sys/vm/vm_zeroidle.c 2007/08/31 20:34:30 @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -154,9 +155,9 @@ /* * We're an idle task, don't count us in the load. */ - PROC_LOCK(pagezero_proc); + PROC_WLOCK(pagezero_proc); pagezero_proc->p_flag |= P_NOLOAD; - PROC_UNLOCK(pagezero_proc); + PROC_WUNLOCK(pagezero_proc); td = FIRST_THREAD_IN_PROC(pagezero_proc); thread_lock(td); sched_class(td, PRI_IDLE);