PERFORCE change 99581 for review
Kip Macy
kmacy at FreeBSD.org
Mon Jun 19 04:36:20 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=99581
Change 99581 by kmacy at 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 <sys/linker.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
-#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/reboot.h>
==== //depot/projects/kmacy_sun4v/src/sys/ddb/db_print.c#3 (text+ko) ====
@@ -38,7 +38,6 @@
#include <sys/param.h>
#include <sys/kdb.h>
-#include <sys/proc.h>
#include <machine/pcb.h>
==== //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) <<<
More information about the p4-projects
mailing list