From owner-p4-projects@FreeBSD.ORG Mon Jun 19 04:36:20 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D896116A47C; Mon, 19 Jun 2006 04:36:19 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8313316A47A for ; Mon, 19 Jun 2006 04:36:19 +0000 (UTC) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3432F43D49 for ; Mon, 19 Jun 2006 04:36:19 +0000 (GMT) (envelope-from kmacy@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k5J4aJ7X001839 for ; Mon, 19 Jun 2006 04:36:19 GMT (envelope-from kmacy@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k5J4aISI001836 for perforce@freebsd.org; Mon, 19 Jun 2006 04:36:18 GMT (envelope-from kmacy@freebsd.org) Date: Mon, 19 Jun 2006 04:36:18 GMT Message-Id: <200606190436.k5J4aISI001836@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to kmacy@freebsd.org using -f From: Kip Macy To: Perforce Change Reviews Cc: Subject: PERFORCE change 99581 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Jun 2006 04:36:20 -0000 http://perforce.freebsd.org/chv.cgi?CH=99581 Change 99581 by kmacy@kmacy_storage:sun4v_work_sleepq on 2006/06/19 04:35:17 make process list per-cpu remove allproc_lock Affected files ... .. //depot/projects/kmacy_sun4v/src/sys/ddb/db_command.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/ddb/db_main.c#3 edit .. //depot/projects/kmacy_sun4v/src/sys/ddb/db_print.c#3 edit .. //depot/projects/kmacy_sun4v/src/sys/ddb/db_ps.c#6 edit .. //depot/projects/kmacy_sun4v/src/sys/ddb/db_thread.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/fs/pseudofs/pseudofs_vnops.c#3 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/imgact_elf.c#3 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/init_main.c#6 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_descrip.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_exit.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_fork.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_ktrace.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_mutex.c#10 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_proc.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_resource.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_sig.c#8 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_switch.c#7 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_synch.c#7 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/kern_sysctl.c#3 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/sched_4bsd.c#7 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/subr_kdb.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/subr_pcpu.c#3 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/subr_sleepqueue.c#6 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/subr_turnstile.c#6 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/subr_witness.c#6 edit .. //depot/projects/kmacy_sun4v/src/sys/kern/sys_process.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/db_interface.c#2 edit .. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/hv_pci.c#43 edit .. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/trap.c#15 edit .. //depot/projects/kmacy_sun4v/src/sys/sun4v/sun4v/vnex.c#5 edit .. //depot/projects/kmacy_sun4v/src/sys/sys/pcpu.h#3 edit .. //depot/projects/kmacy_sun4v/src/sys/sys/proc.h#6 edit .. //depot/projects/kmacy_sun4v/src/sys/vm/vm_glue.c#6 edit .. //depot/projects/kmacy_sun4v/src/sys/vm/vm_meter.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/vm/vm_object.c#4 edit .. //depot/projects/kmacy_sun4v/src/sys/vm/vm_pageout.c#3 edit Differences ... ==== //depot/projects/kmacy_sun4v/src/sys/ddb/db_command.c#5 (text+ko) ==== @@ -540,6 +540,7 @@ { db_expr_t old_radix, pid, sig; struct proc *p; + struct pcpu *pc; #define DB_ERROR(f) do { db_printf f; db_flush_lex(); goto out; } while (0) @@ -559,14 +560,19 @@ if (sig < 0 || sig > _SIG_MAXSIG) DB_ERROR(("Signal number out of range\n")); + /* gcc doesn't know that we have at least 1 pcpu */ + p = NULL; /* - * Find the process in question. allproc_lock is not needed + * Find the process in question. allpcpu_lock is not needed * since we're in DDB. */ - /* sx_slock(&allproc_lock); */ - LIST_FOREACH(p, &allproc, p_list) - if (p->p_pid == pid) - break; + /* sx_slock(&allpcpu_lock); */ + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + if (p->p_pid == pid) + break; + } + } /* sx_sunlock(&allproc_lock); */ if (p == NULL) DB_ERROR(("Can't find process with pid %ld\n", (long) pid)); @@ -674,18 +680,21 @@ char *dummy4) { struct proc *p; + struct pcpu *pc; struct thread *td; int quit; quit = 0; db_setup_paging(db_simple_pager, &quit, db_lines_per_page); - LIST_FOREACH(p, &allproc, p_list) { - FOREACH_THREAD_IN_PROC(p, td) { - db_printf("\nTracing command %s pid %d tid %ld td %p\n", - p->p_comm, p->p_pid, (long)td->td_tid, td); - db_trace_thread(td, -1); - if (quit) + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + FOREACH_THREAD_IN_PROC(p, td) { + db_printf("\nTracing command %s pid %d tid %ld td %p\n", + p->p_comm, p->p_pid, (long)td->td_tid, td); + db_trace_thread(td, -1); + if (quit) return; + } } } } ==== //depot/projects/kmacy_sun4v/src/sys/ddb/db_main.c#3 (text+ko) ==== @@ -33,7 +33,6 @@ #include #include #include -#include #include #include ==== //depot/projects/kmacy_sun4v/src/sys/ddb/db_print.c#3 (text+ko) ==== @@ -38,7 +38,6 @@ #include #include -#include #include ==== //depot/projects/kmacy_sun4v/src/sys/ddb/db_ps.c#6 (text+ko) ==== @@ -71,17 +71,15 @@ volatile struct proc *p, *pp; volatile struct thread *td; struct ucred *cred; + struct pcpu *pc; struct pgrp *pgrp; char state[9]; + int proc0_seen; int np, quit, rflag, sflag, dflag, lflag, wflag; np = nprocs; quit = 0; - - if (!LIST_EMPTY(&allproc)) - p = LIST_FIRST(&allproc); - else - p = &proc0; + proc0_seen = 0; db_setup_paging(db_simple_pager, &quit, db_lines_per_page); #ifdef __LP64__ @@ -90,115 +88,125 @@ db_printf(" pid uid ppid pgrp state wmesg wchan cmd\n"); #endif while (--np >= 0 && !quit) { - if (p == NULL) { - db_printf("oops, ran out of processes early!\n"); - break; - } - pp = p->p_pptr; - if (pp == NULL) - pp = p; - - cred = p->p_ucred; - pgrp = p->p_pgrp; - db_printf("%5d %4d %5d %5d ", p->p_pid, - cred != NULL ? cred->cr_ruid : 0, pp->p_pid, - pgrp != NULL ? pgrp->pg_id : 0); - - /* Determine our primary process state. */ - switch (p->p_state) { - case PRS_NORMAL: - if (P_SHOULDSTOP(p)) - state[0] = 'T'; - else { - /* - * One of D, L, R, S, W. For a - * multithreaded process we will use - * the state of the thread with the - * highest precedence. The - * precendence order from high to low - * is R, L, D, S, W. If no thread is - * in a sane state we use '?' for our - * primary state. - */ - rflag = sflag = dflag = lflag = wflag = 0; - FOREACH_THREAD_IN_PROC(p, td) { - if (td->td_state == TDS_RUNNING || - td->td_state == TDS_RUNQ || - td->td_state == TDS_CAN_RUN) - rflag++; - if (TD_ON_LOCK(td)) - lflag++; - if (TD_IS_SLEEPING(td)) { - if (!td->td_flags & TDF_SINTR) - dflag++; + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + if (!LIST_EMPTY(&pc->pc_allproc)) { + p = LIST_FIRST(&pc->pc_allproc); + } else if (!proc0_seen) { + proc0_seen = 1; + p = &proc0; + } else { + continue; + } + if (p == NULL) { + db_printf("oops, ran out of processes early!\n"); + break; + } + pp = p->p_pptr; + if (pp == NULL) + pp = p; + + cred = p->p_ucred; + pgrp = p->p_pgrp; + db_printf("%5d %4d %5d %5d ", p->p_pid, + cred != NULL ? cred->cr_ruid : 0, pp->p_pid, + pgrp != NULL ? pgrp->pg_id : 0); + + /* Determine our primary process state. */ + switch (p->p_state) { + case PRS_NORMAL: + if (P_SHOULDSTOP(p)) + state[0] = 'T'; + else { + /* + * One of D, L, R, S, W. For a + * multithreaded process we will use + * the state of the thread with the + * highest precedence. The + * precendence order from high to low + * is R, L, D, S, W. If no thread is + * in a sane state we use '?' for our + * primary state. + */ + rflag = sflag = dflag = lflag = wflag = 0; + FOREACH_THREAD_IN_PROC(p, td) { + if (td->td_state == TDS_RUNNING || + td->td_state == TDS_RUNQ || + td->td_state == TDS_CAN_RUN) + rflag++; + if (TD_ON_LOCK(td)) + lflag++; + if (TD_IS_SLEEPING(td)) { + if (!td->td_flags & TDF_SINTR) + dflag++; else sflag++; + } + if (TD_AWAITING_INTR(td)) + wflag++; } - if (TD_AWAITING_INTR(td)) - wflag++; + if (rflag) + state[0] = 'R'; + else if (lflag) + state[0] = 'L'; + else if (dflag) + state[0] = 'D'; + else if (sflag) + state[0] = 'S'; + else if (wflag) + state[0] = 'W'; + else + state[0] = '?'; } - if (rflag) - state[0] = 'R'; - else if (lflag) - state[0] = 'L'; - else if (dflag) - state[0] = 'D'; - else if (sflag) - state[0] = 'S'; - else if (wflag) - state[0] = 'W'; - else - state[0] = '?'; + break; + case PRS_NEW: + state[0] = 'N'; + break; + case PRS_ZOMBIE: + state[0] = 'Z'; + break; + default: + state[0] = 'U'; + break; } - break; - case PRS_NEW: - state[0] = 'N'; - break; - case PRS_ZOMBIE: - state[0] = 'Z'; - break; - default: - state[0] = 'U'; - break; - } - state[1] = '\0'; - - /* Additional process state flags. */ - if (!p->p_sflag & PS_INMEM) - strlcat(state, "W", sizeof(state)); - if (p->p_flag & P_TRACED) - strlcat(state, "X", sizeof(state)); - if (p->p_flag & P_WEXIT && p->p_state != PRS_ZOMBIE) - strlcat(state, "E", sizeof(state)); - if (p->p_flag & P_PPWAIT) - strlcat(state, "V", sizeof(state)); - if (p->p_flag & P_SYSTEM || p->p_lock > 0) - strlcat(state, "L", sizeof(state)); - if (p->p_session != NULL && SESS_LEADER(p)) - strlcat(state, "s", sizeof(state)); - /* Cheated here and didn't compare pgid's. */ - if (p->p_flag & P_CONTROLT) - strlcat(state, "+", sizeof(state)); - if (cred != NULL && jailed(cred)) - strlcat(state, "J", sizeof(state)); - db_printf(" %-6.6s ", state); - if (p->p_flag & P_HADTHREADS) + state[1] = '\0'; + + /* Additional process state flags. */ + if (!p->p_sflag & PS_INMEM) + strlcat(state, "W", sizeof(state)); + if (p->p_flag & P_TRACED) + strlcat(state, "X", sizeof(state)); + if (p->p_flag & P_WEXIT && p->p_state != PRS_ZOMBIE) + strlcat(state, "E", sizeof(state)); + if (p->p_flag & P_PPWAIT) + strlcat(state, "V", sizeof(state)); + if (p->p_flag & P_SYSTEM || p->p_lock > 0) + strlcat(state, "L", sizeof(state)); + if (p->p_session != NULL && SESS_LEADER(p)) + strlcat(state, "s", sizeof(state)); + /* Cheated here and didn't compare pgid's. */ + if (p->p_flag & P_CONTROLT) + strlcat(state, "+", sizeof(state)); + if (cred != NULL && jailed(cred)) + strlcat(state, "J", sizeof(state)); + db_printf(" %-6.6s ", state); + if (p->p_flag & P_HADTHREADS) #ifdef __LP64__ - db_printf(" (threaded) %s\n", - p->p_comm); + db_printf(" (threaded) %s\n", + p->p_comm); #else db_printf(" (threaded) %s\n", p->p_comm); #endif - FOREACH_THREAD_IN_PROC(p, td) { - dumpthread(p, td, p->p_flag & P_HADTHREADS); - if (quit) - break; + FOREACH_THREAD_IN_PROC(p, td) { + dumpthread(p, td, p->p_flag & P_HADTHREADS); + if (quit) + break; + } + + p = LIST_NEXT(p, p_list); + if (p == NULL && np > 0) + p = LIST_FIRST(&pc->pc_zombproc); } - - p = LIST_NEXT(p, p_list); - if (p == NULL && np > 0) - p = LIST_FIRST(&zombproc); - } + } } static void ==== //depot/projects/kmacy_sun4v/src/sys/ddb/db_thread.c#4 (text+ko) ==== @@ -149,6 +149,7 @@ { struct thread *td; db_expr_t decaddr; + struct pcpu *pc; struct proc *p; /* @@ -163,13 +164,15 @@ if (td != NULL) return (td); if (check_pid) { - LIST_FOREACH(p, &allproc, p_list) { - if (p->p_pid == decaddr) - return (FIRST_THREAD_IN_PROC(p)); - } - LIST_FOREACH(p, &zombproc, p_list) { - if (p->p_pid == decaddr) - return (FIRST_THREAD_IN_PROC(p)); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + if (p->p_pid == decaddr) + return (FIRST_THREAD_IN_PROC(p)); + } + LIST_FOREACH(p, &pc->pc_zombproc, p_list) { + if (p->p_pid == decaddr) + return (FIRST_THREAD_IN_PROC(p)); + } } } return ((struct thread *)addr); @@ -186,16 +189,19 @@ { db_expr_t decaddr; struct proc *p; + struct pcpu *pc; decaddr = hex2dec(addr); if (decaddr != -1) { - LIST_FOREACH(p, &allproc, p_list) { - if (p->p_pid == decaddr) - return (p); - } - LIST_FOREACH(p, &zombproc, p_list) { - if (p->p_pid == decaddr) - return (p); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + if (p->p_pid == decaddr) + return (p); + } + LIST_FOREACH(p, &pc->pc_zombproc, p_list) { + if (p->p_pid == decaddr) + return (p); + } } } return ((struct proc *)addr); ==== //depot/projects/kmacy_sun4v/src/sys/fs/pseudofs/pseudofs_vnops.c#3 (text+ko) ==== @@ -553,9 +553,9 @@ */ static int pfs_iterate(struct thread *td, pid_t pid, struct pfs_node *pd, - struct pfs_node **pn, struct proc **p) + struct pfs_node **pn, struct proc **p, struct pcpu **pc) { - sx_assert(&allproc_lock, SX_SLOCKED); + sx_assert(&allpcpu_lock, SX_SLOCKED); again: if (*pn == NULL) { /* first node */ @@ -566,13 +566,22 @@ } if (*pn != NULL && (*pn)->pn_type == pfstype_procdir) { /* next process */ - if (*p == NULL) - *p = LIST_FIRST(&allproc); - else + if (*p == NULL) { + *p = LIST_FIRST(&(*pc)->pc_allproc); + PCPU_PROC_LOCK(*pc); + } else if ((LIST_NEXT(*p, p_list) == NULL) && (SLIST_NEXT(*pc, pc_allcpu) != NULL)) { + PCPU_PROC_UNLOCK(*pc); + *pc = SLIST_NEXT(*pc, pc_allcpu); + PCPU_PROC_LOCK(*pc); + *p = LIST_FIRST(&(*pc)->pc_allproc); + } else { *p = LIST_NEXT(*p, p_list); + } /* out of processes: next node */ - if (*p == NULL) + if (*p == NULL) { + PCPU_PROC_UNLOCK(*pc); *pn = (*pn)->pn_next; + } } if ((*pn) == NULL) @@ -599,6 +608,7 @@ struct dirent *entry; struct uio *uio; struct proc *p; + struct pcpu *pc; off_t offset; int error, i, resid; char *buf, *ent; @@ -623,17 +633,18 @@ PFS_RETURN (0); /* skip unwanted entries */ - sx_slock(&allproc_lock); + sx_slock(&allpcpu_lock); + pc = SLIST_FIRST(&cpuhead); for (pn = NULL, p = NULL; offset > 0; offset -= PFS_DELEN) - if (pfs_iterate(curthread, pid, pd, &pn, &p) == -1) { + if (pfs_iterate(curthread, pid, pd, &pn, &p, &pc) == -1) { /* nothing left... */ - sx_sunlock(&allproc_lock); + sx_sunlock(&allpcpu_lock); PFS_RETURN (0); } /* fill in entries */ ent = buf = malloc(resid, M_IOV, M_WAITOK | M_ZERO); - while (pfs_iterate(curthread, pid, pd, &pn, &p) != -1 && + while (pfs_iterate(curthread, pid, pd, &pn, &p, &pc) != -1 && resid >= PFS_DELEN) { entry = (struct dirent *)ent; entry->d_reclen = PFS_DELEN; @@ -678,7 +689,7 @@ resid -= PFS_DELEN; ent += PFS_DELEN; } - sx_sunlock(&allproc_lock); + sx_sunlock(&allpcpu_lock); error = uiomove(buf, ent - buf, uio); free(buf, M_IOV); PFS_RETURN (error); ==== //depot/projects/kmacy_sun4v/src/sys/kern/imgact_elf.c#3 (text+ko) ==== @@ -142,16 +142,21 @@ __elfN(brand_inuse)(Elf_Brandinfo *entry) { struct proc *p; + struct pcpu *pc; int rval = FALSE; - sx_slock(&allproc_lock); - LIST_FOREACH(p, &allproc, p_list) { - if (p->p_sysent == entry->sysvec) { - rval = TRUE; - break; + sx_slock(&allpcpu_lock); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + PCPU_PROC_LOCK(pc); + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + + if (p->p_sysent == entry->sysvec) { + rval = TRUE; + break; + } } } - sx_sunlock(&allproc_lock); + sx_sunlock(&allpcpu_lock); return (rval); } ==== //depot/projects/kmacy_sun4v/src/sys/kern/init_main.c#6 (text+ko) ==== @@ -431,7 +431,8 @@ /* * Create process 0 (the swapper). */ - LIST_INSERT_HEAD(&allproc, p, p_list); + p->p_pcpu = pcpup; + LIST_INSERT_HEAD(&p->p_pcpu->pc_allproc, p, p_list); LIST_INSERT_HEAD(PIDHASH(0), p, p_hash); mtx_init(&pgrp0.pg_mtx, "process group", NULL, MTX_DEF | MTX_DUPOK); p->p_pgrp = &pgrp0; @@ -529,17 +530,23 @@ { struct timespec ts; struct proc *p; + struct pcpu *pc; /* * Now we can look at the time, having had a chance to verify the * time from the filesystem. Pretend that proc0 started now. */ - sx_slock(&allproc_lock); - LIST_FOREACH(p, &allproc, p_list) { - microuptime(&p->p_stats->p_start); - p->p_rux.rux_runtime = 0; + + sx_slock(&allpcpu_lock); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + PCPU_PROC_LOCK(pc); + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + microuptime(&p->p_stats->p_start); + p->p_rux.rux_runtime = 0; + } + PCPU_PROC_UNLOCK(pc); } - sx_sunlock(&allproc_lock); + sx_sunlock(&allpcpu_lock); PCPU_SET(switchtime, cpu_ticks()); PCPU_SET(switchticks, ticks); ==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_descrip.c#4 (text+ko) ==== @@ -2349,33 +2349,39 @@ { struct filedesc *fdp; struct proc *p; + struct pcpu *pc; int nrele; if (vrefcnt(olddp) == 1) return; - sx_slock(&allproc_lock); - LIST_FOREACH(p, &allproc, p_list) { - fdp = fdhold(p); - if (fdp == NULL) - continue; - nrele = 0; - FILEDESC_LOCK_FAST(fdp); - if (fdp->fd_cdir == olddp) { - vref(newdp); - fdp->fd_cdir = newdp; - nrele++; + + sx_slock(&allpcpu_lock); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + PCPU_PROC_LOCK(pc); + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + fdp = fdhold(p); + if (fdp == NULL) + continue; + nrele = 0; + FILEDESC_LOCK_FAST(fdp); + if (fdp->fd_cdir == olddp) { + vref(newdp); + fdp->fd_cdir = newdp; + nrele++; + } + if (fdp->fd_rdir == olddp) { + vref(newdp); + fdp->fd_rdir = newdp; + nrele++; + } + FILEDESC_UNLOCK_FAST(fdp); + fddrop(fdp); + while (nrele--) + vrele(olddp); } - if (fdp->fd_rdir == olddp) { - vref(newdp); - fdp->fd_rdir = newdp; - nrele++; - } - FILEDESC_UNLOCK_FAST(fdp); - fddrop(fdp); - while (nrele--) - vrele(olddp); + PCPU_PROC_UNLOCK(pc); } - sx_sunlock(&allproc_lock); + sx_sunlock(&allpcpu_lock); if (rootvnode == olddp) { vrele(rootvnode); vref(newdp); @@ -2420,6 +2426,7 @@ struct filedesc *fdp; struct file *fp; struct proc *p; + struct pcpu *pc; int error, n; /* @@ -2450,44 +2457,48 @@ error = 0; bzero(&xf, sizeof(xf)); xf.xf_size = sizeof(xf); - sx_slock(&allproc_lock); - LIST_FOREACH(p, &allproc, p_list) { - if (p->p_state == PRS_NEW) - continue; - PROC_LOCK(p); - if (p_cansee(req->td, p) != 0) { + sx_slock(&allpcpu_lock); + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + PCPU_PROC_LOCK(pc); + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + if (p->p_state == PRS_NEW) + continue; + PROC_LOCK(p); + if (p_cansee(req->td, p) != 0) { + PROC_UNLOCK(p); + continue; + } + xf.xf_pid = p->p_pid; + xf.xf_uid = p->p_ucred->cr_uid; PROC_UNLOCK(p); - continue; - } - xf.xf_pid = p->p_pid; - xf.xf_uid = p->p_ucred->cr_uid; - PROC_UNLOCK(p); - fdp = fdhold(p); - if (fdp == NULL) - continue; - FILEDESC_LOCK_FAST(fdp); - for (n = 0; fdp->fd_refcnt > 0 && n < fdp->fd_nfiles; ++n) { - if ((fp = fdp->fd_ofiles[n]) == NULL) + fdp = fdhold(p); + if (fdp == NULL) continue; - xf.xf_fd = n; - xf.xf_file = fp; - xf.xf_data = fp->f_data; - xf.xf_vnode = fp->f_vnode; - xf.xf_type = fp->f_type; - xf.xf_count = fp->f_count; - xf.xf_msgcount = fp->f_msgcount; - xf.xf_offset = fp->f_offset; - xf.xf_flag = fp->f_flag; - error = SYSCTL_OUT(req, &xf, sizeof(xf)); + FILEDESC_LOCK_FAST(fdp); + for (n = 0; fdp->fd_refcnt > 0 && n < fdp->fd_nfiles; ++n) { + if ((fp = fdp->fd_ofiles[n]) == NULL) + continue; + xf.xf_fd = n; + xf.xf_file = fp; + xf.xf_data = fp->f_data; + xf.xf_vnode = fp->f_vnode; + xf.xf_type = fp->f_type; + xf.xf_count = fp->f_count; + xf.xf_msgcount = fp->f_msgcount; + xf.xf_offset = fp->f_offset; + xf.xf_flag = fp->f_flag; + error = SYSCTL_OUT(req, &xf, sizeof(xf)); + if (error) + break; + } + FILEDESC_UNLOCK_FAST(fdp); + fddrop(fdp); if (error) break; } - FILEDESC_UNLOCK_FAST(fdp); - fddrop(fdp); - if (error) - break; + PCPU_PROC_UNLOCK(pc); } - sx_sunlock(&allproc_lock); + sx_sunlock(&allpcpu_lock); return (error); } @@ -2531,17 +2542,19 @@ { struct filedesc *fdp; struct proc *p; + struct pcpu *pc; int n; - - LIST_FOREACH(p, &allproc, p_list) { - if (p->p_state == PRS_NEW) - continue; - fdp = p->p_fd; - if (fdp == NULL) - continue; - for (n = 0; n < fdp->fd_nfiles; n++) { - if (fp == fdp->fd_ofiles[n]) + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + LIST_FOREACH(p, &pc->pc_allproc, p_list) { + if (p->p_state == PRS_NEW) + continue; + fdp = p->p_fd; + if (fdp == NULL) + continue; + for (n = 0; n < fdp->fd_nfiles; n++) { + if (fp == fdp->fd_ofiles[n]) return (p); + } } } return (NULL); ==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_exit.c#5 (text+ko) ==== @@ -121,12 +121,7 @@ struct plimit *plim; int locked; - /* - * Drop Giant if caller has it. Eventually we should warn about - * being called with Giant held. - */ - while (mtx_owned(&Giant)) - mtx_unlock(&Giant); + mtx_assert(&Giant, MA_NOTOWNED); p = td->td_proc; if (p == initproc) { @@ -408,11 +403,21 @@ * Remove proc from allproc queue and pidhash chain. * Place onto zombproc. Unlink from parent's child list. */ - sx_xlock(&allproc_lock); + if (p->p_pcpu == NULL) + panic("process: %d has null pcpu pointer", p->p_pid); + if (!mtx_initialized(&(p->p_pcpu->pc_allproc_lock))) + panic("null allproc lock on %d", p->p_pcpu->pc_cpuid); + + PCPU_PROC_LOCK(p->p_pcpu); LIST_REMOVE(p, p_list); - LIST_INSERT_HEAD(&zombproc, p, p_list); + LIST_INSERT_HEAD(&p->p_pcpu->pc_zombproc, p, p_list); + PCPU_PROC_UNLOCK(p->p_pcpu); + + mtx_lock(&pidhash_lock); LIST_REMOVE(p, p_hash); - sx_xunlock(&allproc_lock); + LIST_INSERT_HEAD(ZPIDHASH(p->p_pid), p, p_hash); + mtx_unlock(&pidhash_lock); + /* * Reparent all of our children to init. @@ -764,9 +769,15 @@ * Remove other references to this process to ensure * we have an exclusive reference. */ - sx_xlock(&allproc_lock); + + PCPU_PROC_LOCK(p->p_pcpu); LIST_REMOVE(p, p_list); /* off zombproc */ - sx_xunlock(&allproc_lock); + PCPU_PROC_UNLOCK(p->p_pcpu); + + mtx_lock(&pidhash_lock); + LIST_REMOVE(p, p_hash); /* off zombproc */ + mtx_unlock(&pidhash_lock); + LIST_REMOVE(p, p_sibling); leavepgrp(p); sx_xunlock(&proctree_lock); @@ -821,9 +832,7 @@ KASSERT(FIRST_THREAD_IN_PROC(p), ("kern_wait: no residual thread!")); uma_zfree(proc_zone, p); - sx_xlock(&allproc_lock); - nprocs--; - sx_xunlock(&allproc_lock); + atomic_subtract_int(&nprocs, 1); return (0); } mtx_lock_spin(&sched_lock); ==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_fork.c#5 (text+ko) ==== @@ -170,7 +170,7 @@ error = sysctl_wire_old_buffer(req, sizeof(int)); if (error != 0) return(error); - sx_xlock(&allproc_lock); + mtx_lock(&pidhash_lock); pid = randompid; error = sysctl_handle_int(oidp, &pid, 0, req); if (error == 0 && req->newptr != NULL) { @@ -182,7 +182,7 @@ pid = 100; randompid = pid; } - sx_xunlock(&allproc_lock); + mtx_unlock(&pidhash_lock); return (error); } @@ -199,6 +199,7 @@ struct proc *p1, *p2, *pptr; uid_t uid; struct proc *newproc; + struct pcpu *pc; int ok, trypid; static int curfail, pidchecked = 0; static struct timeval lastfail; @@ -306,7 +307,6 @@ * exceed the limit. The variable nprocs is the current number of * processes, maxproc is the limit. */ - sx_xlock(&allproc_lock); uid = td->td_ucred->cr_ruid; if ((nprocs >= maxproc - 10 && suser_cred(td->td_ucred, SUSER_RUID) != 0) || @@ -314,7 +314,6 @@ error = EAGAIN; goto fail; } - /* * Increment the count of procs running with this uid. Don't allow * a nonprivileged user to exceed their current limit. @@ -332,7 +331,7 @@ * Increment the nprocs resource before blocking can occur. There * are hard-limits as to the number of processes that can run. */ - nprocs++; + atomic_add_int(&nprocs, 1); /* * Find an unused process ID. We remember a range of unused IDs @@ -341,6 +340,7 @@ * If RFHIGHPID is set (used during system boot), do not allocate * low-numbered pids. */ + mtx_lock(&pidalloc_lock); trypid = lastpid + 1; if (flags & RFHIGHPID) { if (trypid < 10) @@ -370,40 +370,49 @@ * is in use. Remember the lowest pid that's greater * than trypid, so we can avoid checking for a while. */ - p2 = LIST_FIRST(&allproc); -again: - for (; p2 != NULL; p2 = LIST_NEXT(p2, p_list)) { - PROC_LOCK(p2); - while (p2->p_pid == trypid || - (p2->p_pgrp != NULL && - (p2->p_pgrp->pg_id == trypid || - (p2->p_session != NULL && - p2->p_session->s_sid == trypid)))) { - trypid++; - if (trypid >= pidchecked) { - PROC_UNLOCK(p2); - goto retry; + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + PCPU_PROC_LOCK(pc); + + p2 = LIST_FIRST(&pc->pc_allproc); + again: + for (; p2 != NULL; p2 = LIST_NEXT(p2, p_list)) { + PROC_LOCK(p2); + while (p2->p_pid == trypid || + (p2->p_pgrp != NULL && + (p2->p_pgrp->pg_id == trypid || + (p2->p_session != NULL && + p2->p_session->s_sid == trypid)))) { + trypid++; + if (trypid >= pidchecked) { + PROC_UNLOCK(p2); + PCPU_PROC_UNLOCK(pc); + goto retry; + } + } + if (p2->p_pid > trypid && pidchecked > p2->p_pid) + pidchecked = p2->p_pid; + if (p2->p_pgrp != NULL) { + if (p2->p_pgrp->pg_id > trypid && + pidchecked > p2->p_pgrp->pg_id) + pidchecked = p2->p_pgrp->pg_id; + if (p2->p_session != NULL && + p2->p_session->s_sid > trypid && + pidchecked > p2->p_session->s_sid) + pidchecked = p2->p_session->s_sid; } + PROC_UNLOCK(p2); } - if (p2->p_pid > trypid && pidchecked > p2->p_pid) - pidchecked = p2->p_pid; - if (p2->p_pgrp != NULL) { - if (p2->p_pgrp->pg_id > trypid && - pidchecked > p2->p_pgrp->pg_id) - pidchecked = p2->p_pgrp->pg_id; - if (p2->p_session != NULL && - p2->p_session->s_sid > trypid && - pidchecked > p2->p_session->s_sid) - pidchecked = p2->p_session->s_sid; + + + if (!doingzomb) { + doingzomb = 1; + p2 = LIST_FIRST(&pc->pc_zombproc); + goto again; } - PROC_UNLOCK(p2); + PCPU_PROC_UNLOCK(pc); } - if (!doingzomb) { - doingzomb = 1; - p2 = LIST_FIRST(&zombproc); - goto again; - } } + mtx_unlock(&pidalloc_lock); sx_sunlock(&proctree_lock); /* @@ -418,9 +427,15 @@ p2->p_state = PRS_NEW; /* protect against others */ p2->p_pid = trypid; AUDIT_ARG(pid, p2->p_pid); - LIST_INSERT_HEAD(&allproc, p2, p_list); + p2->p_pcpu = pcpup; + + PCPU_PROC_LOCK(p2->p_pcpu); + LIST_INSERT_HEAD(&p2->p_pcpu->pc_allproc, p2, p_list); + PCPU_PROC_UNLOCK(p2->p_pcpu); >>> TRUNCATED FOR MAIL (1000 lines) <<<