--- sys/amd64/amd64/machdep.c.orig +++ sys/amd64/amd64/machdep.c @@ -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; --- sys/amd64/amd64/trap.c.orig +++ sys/amd64/amd64/trap.c @@ -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 --- sys/amd64/ia32/ia32_signal.c.orig +++ sys/amd64/ia32/ia32_signal.c @@ -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); } --- sys/amd64/ia32/ia32_syscall.c.orig +++ sys/amd64/ia32/ia32_syscall.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include #include --- sys/amd64/linux32/linux32_machdep.c.orig +++ sys/amd64/linux32/linux32_machdep.c @@ -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)); } --- sys/amd64/linux32/linux32_sysvec.c.orig +++ sys/amd64/linux32/linux32_sysvec.c @@ -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 --- sys/arm/arm/machdep.c.orig +++ sys/arm/arm/machdep.c @@ -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); } --- sys/arm/arm/trap.c.orig +++ sys/arm/arm/trap.c @@ -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)) --- sys/arm/arm/undefined.c.orig +++ sys/arm/arm/undefined.c @@ -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; } --- sys/cam/cam_periph.c.orig +++ sys/cam/cam_periph.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include --- sys/compat/freebsd32/freebsd32_misc.c.orig +++ sys/compat/freebsd32/freebsd32_misc.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include /* Must come after sys/selinfo.h */ #include /* Must come after sys/selinfo.h */ @@ -2023,10 +2024,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 +2081,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 +2097,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 +2112,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); } --- sys/compat/linprocfs/linprocfs.c.orig +++ sys/compat/linprocfs/linprocfs.c @@ -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); --- sys/compat/linux/linux_emul.c.orig +++ sys/compat/linux/linux_emul.c @@ -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) { --- sys/compat/linux/linux_file.c.orig +++ sys/compat/linux/linux_file.c @@ -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) { --- sys/compat/linux/linux_misc.c.orig +++ sys/compat/linux/linux_misc.c @@ -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; --- sys/compat/linux/linux_signal.c.orig +++ sys/compat/linux/linux_signal.c @@ -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); --- sys/compat/linux/linux_uid16.c.orig +++ sys/compat/linux/linux_uid16.c @@ -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); } --- sys/compat/svr4/imgact_svr4.c.orig +++ sys/compat/svr4/imgact_svr4.c @@ -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); --- sys/compat/svr4/svr4_fcntl.c.orig +++ sys/compat/svr4/svr4_fcntl.c @@ -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; } --- sys/compat/svr4/svr4_filio.c.orig +++ sys/compat/svr4/svr4_filio.c @@ -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 } --- sys/compat/svr4/svr4_misc.c.orig +++ sys/compat/svr4/svr4_misc.c @@ -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; --- sys/compat/svr4/svr4_resource.c.orig +++ sys/compat/svr4/svr4_resource.c @@ -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 --- sys/compat/svr4/svr4_signal.c.orig +++ sys/compat/svr4/svr4_signal.c @@ -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); } --- sys/ddb/db_command.c.orig +++ sys/ddb/db_command.c @@ -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: --- sys/dev/bktr/bktr_core.c.orig +++ sys/dev/bktr/bktr_core.c @@ -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); } /* --- sys/dev/hwpmc/hwpmc_logging.c.orig +++ sys/dev/hwpmc/hwpmc_logging.c @@ -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, --- sys/dev/hwpmc/hwpmc_mod.c.orig +++ sys/dev/hwpmc/hwpmc_mod.c @@ -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); } --- sys/dev/iscsi/initiator/isc_soc.c.orig +++ sys/dev/iscsi/initiator/isc_soc.c @@ -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); } --- sys/dev/mfi/mfi.c.orig +++ sys/dev/mfi/mfi.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include @@ -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); } } --- sys/dev/sound/midi/midi.c.orig +++ sys/dev/sound/midi/midi.c @@ -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); --- sys/dev/syscons/scmouse.c.orig +++ sys/dev/syscons/scmouse.c @@ -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; } } --- sys/dev/syscons/syscons.c.orig +++ sys/dev/syscons/syscons.c @@ -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; } --- sys/dev/usb/uhid.c.orig +++ sys/dev/usb/uhid.c @@ -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); } } --- sys/dev/usb/usb.c.orig +++ sys/dev/usb/usb.c @@ -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); } --- sys/dev/utopia/utopia.c.orig +++ sys/dev/utopia/utopia.c @@ -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); --- sys/fs/coda/coda_psdev.c.orig +++ sys/fs/coda/coda_psdev.c @@ -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 --- sys/fs/coda/coda_vnops.c.orig +++ sys/fs/coda/coda_vnops.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include --- sys/fs/fdescfs/fdesc_vfsops.c.orig +++ sys/fs/fdescfs/fdesc_vfsops.c @@ -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); --- sys/fs/msdosfs/msdosfs_vnops.c.orig +++ sys/fs/msdosfs/msdosfs_vnops.c @@ -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); } /* --- sys/fs/nwfs/nwfs_io.c.orig +++ sys/fs/nwfs/nwfs_io.c @@ -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); --- sys/fs/procfs/procfs.c.orig +++ sys/fs/procfs/procfs.c @@ -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); } --- sys/fs/procfs/procfs_ctl.c.orig +++ sys/fs/procfs/procfs_ctl.c @@ -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; } } --- sys/fs/procfs/procfs_dbregs.c.orig +++ sys/fs/procfs/procfs_dbregs.c @@ -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); } --- sys/fs/procfs/procfs_fpregs.c.orig +++ sys/fs/procfs/procfs_fpregs.c @@ -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); } --- sys/fs/procfs/procfs_ioctl.c.orig +++ sys/fs/procfs/procfs_ioctl.c @@ -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; --- sys/fs/procfs/procfs_map.c.orig +++ sys/fs/procfs/procfs_map.c @@ -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); --- sys/fs/procfs/procfs_mem.c.orig +++ sys/fs/procfs/procfs_mem.c @@ -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); --- sys/fs/procfs/procfs_regs.c.orig +++ sys/fs/procfs/procfs_regs.c @@ -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); } --- sys/fs/procfs/procfs_rlimit.c.orig +++ sys/fs/procfs/procfs_rlimit.c @@ -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++) { --- sys/fs/procfs/procfs_status.c.orig +++ sys/fs/procfs/procfs_status.c @@ -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 { --- sys/fs/pseudofs/pseudofs.c.orig +++ sys/fs/pseudofs/pseudofs.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include --- sys/fs/pseudofs/pseudofs_fileno.c.orig +++ sys/fs/pseudofs/pseudofs_fileno.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include --- sys/fs/pseudofs/pseudofs_internal.h.orig +++ sys/fs/pseudofs/pseudofs_internal.h @@ -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)); } --- sys/fs/pseudofs/pseudofs_vncache.c.orig +++ sys/fs/pseudofs/pseudofs_vncache.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include --- sys/fs/pseudofs/pseudofs_vnops.c.orig +++ sys/fs/pseudofs/pseudofs_vnops.c @@ -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) { --- sys/fs/smbfs/smbfs_io.c.orig +++ sys/fs/smbfs/smbfs_io.c @@ -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); --- sys/fs/tmpfs/tmpfs_vnops.c.orig +++ sys/fs/tmpfs/tmpfs_vnops.c @@ -700,14 +700,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; --- sys/gnu/fs/ext2fs/ext2_readwrite.c.orig +++ sys/gnu/fs/ext2fs/ext2_readwrite.c @@ -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; --- sys/gnu/fs/ext2fs/ext2_vnops.c.orig +++ sys/gnu/fs/ext2fs/ext2_vnops.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include --- sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c.orig +++ sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c @@ -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 --- sys/i386/i386/machdep.c.orig +++ sys/i386/i386/machdep.c @@ -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; --- sys/i386/i386/trap.c.orig +++ sys/i386/i386/trap.c @@ -512,9 +512,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 +754,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 --- sys/i386/ibcs2/ibcs2_fcntl.c.orig +++ sys/i386/ibcs2/ibcs2_fcntl.c @@ -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; } --- sys/i386/ibcs2/ibcs2_ioctl.c.orig +++ sys/i386/ibcs2/ibcs2_ioctl.c @@ -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; --- sys/i386/ibcs2/ibcs2_misc.c.orig +++ sys/i386/ibcs2/ibcs2_misc.c @@ -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; } --- sys/i386/ibcs2/ibcs2_signal.c.orig +++ sys/i386/ibcs2/ibcs2_signal.c @@ -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); } --- sys/i386/linux/imgact_linux.c.orig +++ sys/i386/linux/imgact_linux.c @@ -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); --- sys/i386/linux/linux_machdep.c.orig +++ sys/i386/linux/linux_machdep.c @@ -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)); } --- sys/i386/linux/linux_ptrace.c.orig +++ sys/i386/linux/linux_ptrace.c @@ -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 --- sys/i386/linux/linux_sysvec.c.orig +++ sys/i386/linux/linux_sysvec.c @@ -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 --- sys/i386/svr4/svr4_machdep.c.orig +++ sys/i386/svr4/svr4_machdep.c @@ -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 } --- sys/ia64/ia64/machdep.c.orig +++ sys/ia64/ia64/machdep.c @@ -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); } --- sys/ia64/ia64/trap.c.orig +++ sys/ia64/ia64/trap.c @@ -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 --- sys/kern/imgact_aout.c.orig +++ sys/kern/imgact_aout.c @@ -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 --- sys/kern/imgact_elf.c.orig +++ sys/kern/imgact_elf.c @@ -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; --- sys/kern/imgact_gzip.c.orig +++ sys/kern/imgact_gzip.c @@ -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; --- sys/kern/init_main.c.orig +++ sys/kern/init_main.c @@ -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); --- sys/kern/kern_acct.c.orig +++ sys/kern/kern_acct.c @@ -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); /* --- sys/kern/kern_clock.c.orig +++ sys/kern/kern_clock.c @@ -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) --- sys/kern/kern_context.c.orig +++ sys/kern/kern_context.c @@ -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); } } } --- sys/kern/kern_descrip.c.orig +++ sys/kern/kern_descrip.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -257,10 +258,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 +383,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; @@ -534,9 +535,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 +546,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 +657,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 +795,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 +833,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 +853,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 +895,7 @@ sx_slock(&proctree_lock); if (pgid > 0) { - proc = pfind(pgid); + proc = pfindr(pgid); if (proc == NULL) { ret = ESRCH; goto fail; @@ -908,7 +909,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 +941,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 +1285,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 +1332,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); @@ -2448,14 +2449,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; --- sys/kern/kern_event.c.orig +++ sys/kern/kern_event.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -347,7 +348,7 @@ if (immediate && filt_proc(kn, NOTE_EXIT)) KNOTE_ACTIVATE(kn, 0); - PROC_UNLOCK(p); + PROC_WUNLOCK(p); return (0); } @@ -1651,29 +1652,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 +1692,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; --- sys/kern/kern_exec.c.orig +++ sys/kern/kern_exec.c @@ -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 --- sys/kern/kern_exit.c.orig +++ sys/kern/kern_exit.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -135,7 +136,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 +193,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 +217,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 +238,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 +249,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 +362,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 +398,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 +433,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 +444,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 +468,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 +523,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 @@ -668,29 +670,29 @@ 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 +706,7 @@ */ if ((p->p_sigparent != SIGCHLD) ^ ((options & WLINUXCLONE) != 0)) { - PROC_UNLOCK(p); + PROC_WUNLOCK(p); continue; } @@ -719,23 +721,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 +758,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 +814,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 +827,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 +847,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 +869,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; --- sys/kern/kern_fork.c.orig +++ sys/kern/kern_fork.c @@ -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); --- sys/kern/kern_idle.c.orig +++ sys/kern/kern_idle.c @@ -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 --- sys/kern/kern_intr.c.orig +++ sys/kern/kern_intr.c @@ -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) --- sys/kern/kern_jail.c.orig +++ sys/kern/kern_jail.c @@ -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: --- sys/kern/kern_kse.c.orig +++ sys/kern/kern_kse.c @@ -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)) --- sys/kern/kern_kthread.c.orig +++ sys/kern/kern_kthread.c @@ -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); } --- sys/kern/kern_ktrace.c.orig +++ sys/kern/kern_ktrace.c @@ -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); --- sys/kern/kern_lock.c.orig +++ sys/kern/kern_lock.c @@ -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) --- sys/kern/kern_mutex.c.orig +++ sys/kern/kern_mutex.c @@ -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. @@ -776,7 +796,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); --- sys/kern/kern_physio.c.orig +++ sys/kern/kern_physio.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include --- sys/kern/kern_proc.c.orig +++ sys/kern/kern_proc.c @@ -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,14 +1276,14 @@ 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)); } --- sys/kern/kern_prot.c.orig +++ sys/kern/kern_prot.c @@ -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; --- sys/kern/kern_resource.c.orig +++ sys/kern/kern_resource.c @@ -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]; --- sys/kern/kern_rwlock.c.orig +++ sys/kern/kern_rwlock.c @@ -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) { @@ -946,6 +957,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) --- sys/kern/kern_shutdown.c.orig +++ sys/kern/kern_shutdown.c @@ -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); --- sys/kern/kern_sig.c.orig +++ sys/kern/kern_sig.c @@ -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); } --- sys/kern/kern_sx.c.orig +++ sys/kern/kern_sx.c @@ -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) { --- sys/kern/kern_thr.c.orig +++ sys/kern/kern_thr.c @@ -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); } --- sys/kern/kern_thread.c.orig +++ sys/kern/kern_thread.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -372,7 +373,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 +464,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 +609,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 +770,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 +813,7 @@ thread_unlock(p->p_singlethread); } } - PROC_UNLOCK(p); + PROC_WUNLOCK(p); thread_lock(td); /* * When a thread suspends, it just @@ -828,7 +829,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 +843,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 +851,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 +859,7 @@ mi_switch(SW_VOL, NULL); thread_unlock(td); PICKUP_GIANT(); - PROC_LOCK(p); + PROC_WLOCK(p); PROC_SLOCK(p); } @@ -895,7 +896,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 +930,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 +957,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) --- sys/kern/kern_time.c.orig +++ sys/kern/kern_time.c @@ -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); } } --- sys/kern/kern_timeout.c.orig +++ sys/kern/kern_timeout.c @@ -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); } --- sys/kern/kern_umtx.c.orig +++ sys/kern/kern_umtx.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -1433,14 +1434,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); } --- sys/kern/p1003_1b.c.orig +++ sys/kern/p1003_1b.c @@ -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); } --- sys/kern/sched_4bsd.c.orig +++ sys/kern/sched_4bsd.c @@ -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) { --- sys/kern/sched_ule.c.orig +++ sys/kern/sched_ule.c @@ -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; --- sys/kern/subr_bus.c.orig +++ sys/kern/subr_bus.c @@ -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); } } --- sys/kern/subr_prf.c.orig +++ sys/kern/subr_prf.c @@ -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; --- sys/kern/subr_prof.c.orig +++ sys/kern/subr_prof.c @@ -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__)) && \ --- sys/kern/subr_sleepqueue.c.orig +++ sys/kern/subr_sleepqueue.c @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -385,7 +386,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); @@ -405,7 +406,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)) { --- sys/kern/subr_trap.c.orig +++ sys/kern/subr_trap.c @@ -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); --- sys/kern/subr_witness.c.orig +++ sys/kern/subr_witness.c @@ -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 }, --- sys/kern/sys_generic.c.orig +++ sys/kern/sys_generic.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -486,9 +487,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; @@ -890,14 +891,14 @@ * 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); + PROC_RUNLOCK(td->td_proc); error = EINVAL; goto done2; } - 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); --- sys/kern/sys_process.c.orig +++ sys/kern/sys_process.c @@ -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); } --- sys/kern/sys_socket.c.orig +++ sys/kern/sys_socket.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -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); } --- sys/kern/sysv_shm.c.orig +++ sys/kern/sysv_shm.c @@ -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); --- sys/kern/tty.c.orig +++ sys/kern/tty.c @@ -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, --- sys/kern/uipc_mqueue.c.orig +++ sys/kern/uipc_mqueue.c @@ -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); } /* @@ -2202,11 +2203,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 +2232,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 --- sys/kern/uipc_sockbuf.c.orig +++ sys/kern/uipc_sockbuf.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -288,9 +289,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, --- sys/kern/uipc_syscalls.c.orig +++ sys/kern/uipc_syscalls.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -794,9 +795,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) @@ -2378,9 +2379,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 +2486,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) --- sys/kern/vfs_aio.c.orig +++ sys/kern/vfs_aio.c @@ -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 --- sys/netncp/ncp_ncp.c.orig +++ sys/netncp/ncp_ncp.c @@ -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; } --- sys/netsmb/smb_subr.c.orig +++ sys/netsmb/smb_subr.c @@ -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; } --- sys/nfs4client/nfs4_dev.c.orig +++ sys/nfs4client/nfs4_dev.c @@ -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? */ --- sys/nfsclient/nfs_bio.c.orig +++ sys/nfsclient/nfs_bio.c @@ -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); } --- sys/nfsclient/nfs_lock.c.orig +++ sys/nfsclient/nfs_lock.c @@ -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); } --- sys/nfsclient/nfs_socket.c.orig +++ sys/nfsclient/nfs_socket.c @@ -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); } --- sys/opencrypto/crypto.c.orig +++ sys/opencrypto/crypto.c @@ -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(); } } --- sys/pc98/pc98/machdep.c.orig +++ sys/pc98/pc98/machdep.c @@ -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; --- sys/powerpc/powerpc/machdep.c.orig +++ sys/powerpc/powerpc/machdep.c @@ -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); } --- sys/powerpc/powerpc/trap.c.orig +++ sys/powerpc/powerpc/trap.c @@ -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 --- sys/rpc/rpcclnt.c.orig +++ sys/rpc/rpcclnt.c @@ -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); } --- sys/security/audit/audit_arg.c.orig +++ sys/security/audit/audit_arg.c @@ -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) --- sys/security/audit/audit_syscalls.c.orig +++ sys/security/audit/audit_syscalls.c @@ -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); } --- sys/security/mac/mac_process.c.orig +++ sys/security/mac/mac_process.c @@ -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); --- sys/security/mac/mac_syscalls.c.orig +++ sys/security/mac/mac_syscalls.c @@ -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); --- sys/security/mac_lomac/mac_lomac.c.orig +++ sys/security/mac_lomac/mac_lomac.c @@ -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); --- sys/sparc64/sparc64/machdep.c.orig +++ sys/sparc64/sparc64/machdep.c @@ -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); --- sys/sparc64/sparc64/trap.c.orig +++ sys/sparc64/sparc64/trap.c @@ -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 --- sys/sun4v/sun4v/machdep.c.orig +++ sys/sun4v/sun4v/machdep.c @@ -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); --- sys/sun4v/sun4v/trap.c.orig +++ sys/sun4v/sun4v/trap.c @@ -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 --- sys/sys/callout.h.orig +++ sys/sys/callout.h @@ -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) --- sys/sys/lock.h.orig +++ sys/sys/lock.h @@ -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. */ --- sys/sys/proc.h.orig +++ sys/sys/proc.h @@ -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 @@ -508,7 +509,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 +692,29 @@ #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) +/* TODO */ +#define PROC_TRYLOCK(p) (rw_wlock(&(p)->p_rwlock), 1) /* Lock and unlock a process group. */ #define PGRP_LOCK(pg) mtx_lock(&(pg)->pg_mtx) @@ -734,12 +739,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 +756,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 +815,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. */ --- sys/sys/ptrace.h.orig +++ sys/sys/ptrace.h @@ -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 --- sys/sys/rwlock.h.orig +++ sys/sys/rwlock.h @@ -127,6 +127,7 @@ 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); --- sys/ufs/ffs/ffs_rawread.c.orig +++ sys/ufs/ffs/ffs_rawread.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include #include #include --- sys/ufs/ffs/ffs_snapshot.c.orig +++ sys/ufs/ffs/ffs_snapshot.c @@ -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) { --- sys/ufs/ffs/ffs_softdep.c.orig +++ sys/ufs/ffs/ffs_softdep.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include #include --- sys/ufs/ffs/ffs_vnops.c.orig +++ sys/ufs/ffs/ffs_vnops.c @@ -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; --- sys/vm/vm_glue.c.orig +++ sys/vm/vm_glue.c @@ -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; --- sys/vm/vm_map.c.orig +++ sys/vm/vm_map.c @@ -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); --- sys/vm/vm_mmap.c.orig +++ sys/vm/vm_mmap.c @@ -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. --- sys/vm/vm_pageout.c.orig +++ sys/vm/vm_pageout.c @@ -87,6 +87,7 @@ #include #include #include +#include #include #include #include @@ -1228,7 +1229,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 +1251,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 +1270,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 +1282,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 +1555,6 @@ static void vm_daemon() { - struct rlimit rsslim; struct proc *p; struct thread *td; int breakout, swapout_flags; @@ -1580,9 +1580,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 +1604,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) { --- sys/vm/vm_unix.c.orig +++ sys/vm/vm_unix.c @@ -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); --- sys/vm/vm_zeroidle.c.orig +++ sys/vm/vm_zeroidle.c @@ -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);