Date: Mon, 20 Nov 2000 00:06:54 -0800 From: Jake Burkholder <jburkhol@home.com> To: smp@FreeBSD.ORG Subject: Re: patch: allproc_lock Message-ID: <20001120080655.5BEA4BA7A@io.yi.org> In-Reply-To: Message from Jake Burkholder <jburkhol@home.com> of "Sun, 19 Nov 2000 23:55:16 PST." <20001120075516.93B73BA7A@io.yi.org>
index | next in thread | previous in thread | raw e-mail
[-- Attachment #1 --]
>
> Attached is a patch that adds allproc_lock. This is a lockmgr
> lock which protectes the following:
>
> allproc
> zombproc
> pidhashtbl
> proc.p_list
> proc.p_hash
> nextpid
>
> Please review it.
Sorry, too quick with the send...<blush>
Here's the patch:
[-- Attachment #2 --]
Index: alpha/alpha/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/alpha/pmap.c,v
retrieving revision 1.44
diff -u -r1.44 pmap.c
--- alpha/alpha/pmap.c 2000/10/17 10:05:46 1.44
+++ alpha/alpha/pmap.c 2000/11/19 10:12:35
@@ -723,12 +723,14 @@
printf("pmap_get_asn: generation rollover\n");
#endif
PCPU_GET(current_asngen) = 1;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_vmspace) {
tpmap = vmspace_pmap(p->p_vmspace);
tpmap->pm_asn[PCPU_GET(cpuno)].gen = 0;
}
}
+ allproc_unlock();
}
/*
@@ -1553,12 +1555,14 @@
newlev1 = pmap_phys_to_pte(pa)
| PG_V | PG_ASM | PG_KRE | PG_KWE;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_vmspace) {
pmap = vmspace_pmap(p->p_vmspace);
*pmap_lev1pte(pmap, kernel_vm_end) = newlev1;
}
}
+ allproc_unlock();
*pte = newlev1;
pmap_invalidate_all(kernel_pmap);
}
@@ -3057,6 +3061,7 @@
struct proc *p;
int npte = 0;
int index;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid != pid)
continue;
@@ -3079,6 +3084,7 @@
index = 0;
printf("\n");
}
+ allproc_unlock();
return npte;
}
pte = pmap_pte_quick( pmap, va);
@@ -3103,6 +3109,7 @@
}
}
}
+ allproc_unlock();
return npte;
}
#endif
Index: i386/i386/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v
retrieving revision 1.264
diff -u -r1.264 pmap.c
--- i386/i386/pmap.c 2000/11/07 18:31:16 1.264
+++ i386/i386/pmap.c 2000/11/19 10:12:35
@@ -3324,6 +3324,7 @@
struct proc *p;
int npte = 0;
int index;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid != pid)
continue;
@@ -3346,6 +3347,7 @@
index = 0;
printf("\n");
}
+ allproc_unlock();
return npte;
}
pte = pmap_pte_quick( pmap, va);
@@ -3370,6 +3372,7 @@
}
}
}
+ allproc_unlock();
return npte;
}
#endif
Index: ia64/ia64/pmap.c
===================================================================
RCS file: /home/ncvs/src/sys/ia64/ia64/pmap.c,v
retrieving revision 1.8
diff -u -r1.8 pmap.c
--- ia64/ia64/pmap.c 2000/10/17 10:05:49 1.8
+++ ia64/ia64/pmap.c 2000/11/19 10:12:36
@@ -2244,6 +2244,7 @@
struct proc *p;
int npte = 0;
int index;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid != pid)
continue;
@@ -2266,6 +2267,7 @@
index = 0;
printf("\n");
}
+ allproc_unlock();
return npte;
}
pte = pmap_pte_quick( pmap, va);
@@ -2290,6 +2292,7 @@
}
}
}
+ allproc_unlock();
return npte;
}
#endif
Index: kern/imgact_elf.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/imgact_elf.c,v
retrieving revision 1.84
diff -u -r1.84 imgact_elf.c
--- kern/imgact_elf.c 2000/11/09 08:25:47 1.84
+++ kern/imgact_elf.c 2000/11/19 10:12:36
@@ -153,10 +153,12 @@
{
struct proc *p;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_sysent == entry->sysvec)
return TRUE;
}
+ allproc_unlock();
return FALSE;
}
Index: kern/init_main.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/init_main.c,v
retrieving revision 1.146
diff -u -r1.146 init_main.c
--- kern/init_main.c 2000/11/05 10:41:34 1.146
+++ kern/init_main.c 2000/11/19 10:12:37
@@ -405,10 +405,12 @@
* Now we can look at the time, having had a chance to verify the
* time from the file system. Pretend that proc0 started now.
*/
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
microtime(&p->p_stats->p_start);
p->p_runtime = 0;
}
+ allproc_unlock();
microuptime(&switchtime);
PCPU_SET(switchticks, ticks);
Index: kern/kern_exit.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_exit.c,v
retrieving revision 1.103
diff -u -r1.103 kern_exit.c
--- kern/kern_exit.c 2000/10/20 07:58:02 1.103
+++ kern/kern_exit.c 2000/11/20 06:17:32
@@ -264,11 +264,13 @@
* Remove proc from allproc queue and pidhash chain.
* Place onto zombproc. Unlink from parent's child list.
*/
+ allproc_lock(LK_EXCLUSIVE);
LIST_REMOVE(p, p_list);
LIST_INSERT_HEAD(&zombproc, p, p_list);
p->p_stat = SZOMB;
LIST_REMOVE(p, p_hash);
+ allproc_unlock();
q = LIST_FIRST(&p->p_children);
if (q) /* only need this if any child is S_ZOMB */
Index: kern/kern_fork.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_fork.c,v
retrieving revision 1.83
diff -u -r1.83 kern_fork.c
--- kern/kern_fork.c 2000/10/20 07:58:03 1.83
+++ kern/kern_fork.c 2000/11/20 06:13:57
@@ -287,6 +287,7 @@
* If RFHIGHPID is set (used during system boot), do not allocate
* low-numbered pids.
*/
+ allproc_lock(LK_EXCLUSIVE);
trypid = nextpid + 1;
if (flags & RFHIGHPID) {
if (trypid < 10) {
@@ -343,12 +344,6 @@
}
}
- p2 = newproc;
- p2->p_stat = SIDL; /* protect against others */
- p2->p_pid = trypid;
- LIST_INSERT_HEAD(&allproc, p2, p_list);
- LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
-
/*
* RFHIGHPID does not mess with the nextpid counter during boot.
*/
@@ -356,6 +351,13 @@
pidchecked = 0;
else
nextpid = trypid;
+
+ p2 = newproc;
+ p2->p_stat = SIDL; /* protect against others */
+ p2->p_pid = trypid;
+ LIST_INSERT_HEAD(&allproc, p2, p_list);
+ LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
+ allproc_unlock();
/*
* Make a proc table entry for the new process.
Index: kern/kern_ktrace.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.43
diff -u -r1.43 kern_ktrace.c
--- kern/kern_ktrace.c 2000/10/27 11:45:33 1.43
+++ kern/kern_ktrace.c 2000/11/19 10:12:37
@@ -278,6 +278,7 @@
* Clear all uses of the tracefile
*/
if (ops == KTROP_CLEARFILE) {
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_tracep == vp) {
if (ktrcanset(curp, p)) {
@@ -289,6 +290,7 @@
error = EPERM;
}
}
+ allproc_unlock();
goto done;
}
/*
@@ -494,6 +496,7 @@
*/
log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
error);
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_tracep == vp) {
p->p_tracep = NULL;
@@ -501,6 +504,7 @@
vrele(vp);
}
}
+ allproc_unlock();
}
/*
Index: kern/kern_proc.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.75
diff -u -r1.75 kern_proc.c
--- kern/kern_proc.c 2000/09/07 01:32:51 1.75
+++ kern/kern_proc.c 2000/11/20 06:05:52
@@ -72,6 +72,7 @@
u_long pgrphash;
struct proclist allproc;
struct proclist zombproc;
+struct lock __allproc_lock;
vm_zone_t proc_zone;
vm_zone_t ithread_zone;
@@ -82,6 +83,7 @@
procinit()
{
+ lockinit(&__allproc_lock, PZERO, "allproc", 0, 0);
LIST_INIT(&allproc);
LIST_INIT(&zombproc);
pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
@@ -113,10 +115,12 @@
{
register struct proc *p;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, PIDHASH(pid), p_hash)
if (p->p_pid == pid)
- return (p);
- return (NULL);
+ break;
+ allproc_unlock();
+ return (p);
}
/*
@@ -470,6 +474,7 @@
if (error)
return (error);
}
+ allproc_lock(LK_SHARED);
for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
if (!doingzomb)
p = LIST_FIRST(&allproc);
@@ -525,10 +530,13 @@
continue;
error = sysctl_out_proc(p, req, doingzomb);
- if (error)
+ if (error) {
+ allproc_unlock();
return (error);
+ }
}
}
+ allproc_unlock();
return (0);
}
Index: kern/kern_resource.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_resource.c,v
retrieving revision 1.64
diff -u -r1.64 kern_resource.c
--- kern/kern_resource.c 2000/09/18 17:03:03 1.64
+++ kern/kern_resource.c 2000/11/19 10:12:37
@@ -119,11 +119,13 @@
case PRIO_USER:
if (uap->who == 0)
uap->who = curp->p_ucred->cr_uid;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list)
if (!p_can(curp, p, P_CAN_SEE, NULL) &&
p->p_ucred->cr_uid == uap->who &&
p->p_nice < low)
low = p->p_nice;
+ allproc_unlock();
break;
default:
@@ -185,12 +187,14 @@
case PRIO_USER:
if (uap->who == 0)
uap->who = curp->p_ucred->cr_uid;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list)
if (p->p_ucred->cr_uid == uap->who &&
!p_can(curp, p, P_CAN_SEE, NULL)) {
error = donice(curp, p, uap->prio);
found++;
}
+ allproc_unlock();
break;
default:
Index: kern/kern_sig.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v
retrieving revision 1.92
diff -u -r1.92 kern_sig.c
--- kern/kern_sig.c 2000/11/17 18:09:15 1.92
+++ kern/kern_sig.c 2000/11/19 10:12:37
@@ -850,10 +850,11 @@
struct pgrp *pgrp;
int nfound = 0;
- if (all)
+ if (all) {
/*
* broadcast
*/
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !CANSIGNAL(cp, p, sig))
@@ -862,7 +863,8 @@
if (sig)
psignal(p, sig);
}
- else {
+ allproc_unlock();
+ } else {
if (pgid == 0)
/*
* zero pgid means send to my process group.
Index: kern/kern_synch.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_synch.c,v
retrieving revision 1.109
diff -u -r1.109 kern_synch.c
--- kern/kern_synch.c 2000/11/17 18:09:15 1.109
+++ kern/kern_synch.c 2000/11/19 10:12:37
@@ -281,6 +281,7 @@
register int realstathz, s;
realstathz = stathz ? stathz : hz;
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
/*
* Increment time in/out of memory and sleep time
@@ -340,6 +341,7 @@
mtx_exit(&sched_lock, MTX_SPIN);
splx(s);
}
+ allproc_unlock();
vmmeter();
wakeup((caddr_t)&lbolt);
timeout(schedcpu, (void *)0, hz);
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.172
diff -u -r1.172 vfs_syscalls.c
--- kern/vfs_syscalls.c 2000/11/18 21:01:02 1.172
+++ kern/vfs_syscalls.c 2000/11/19 10:12:38
@@ -366,6 +366,7 @@
return;
if (VFS_ROOT(olddp->v_mountedhere, &newdp))
panic("mount: lost mount");
+ allproc_lock(LK_SHARED);
LIST_FOREACH(p, &allproc, p_list) {
fdp = p->p_fd;
if (fdp->fd_cdir == olddp) {
@@ -379,6 +380,7 @@
fdp->fd_rdir = newdp;
}
}
+ allproc_unlock();
if (rootvnode == olddp) {
vrele(rootvnode);
VREF(newdp);
Index: sys/proc.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/proc.h,v
retrieving revision 1.123
diff -u -r1.123 proc.h
--- sys/proc.h 2000/11/17 18:09:18 1.123
+++ sys/proc.h 2000/11/19 10:12:38
@@ -45,6 +45,7 @@
#include <machine/proc.h> /* Machine-dependent proc substruct. */
#include <sys/callout.h> /* For struct callout_handle. */
#include <sys/filedesc.h>
+#include <sys/lock.h> /* For lockmgr. */
#include <sys/queue.h>
#include <sys/rtprio.h> /* For struct rtprio. */
#include <sys/signal.h>
@@ -483,6 +484,20 @@
struct vm_zone;
extern struct vm_zone *proc_zone;
+
+extern struct lock __allproc_lock;
+
+static __inline void
+allproc_lock(int how)
+{
+ lockmgr(&__allproc_lock, how, NULL, CURPROC);
+}
+
+static __inline void
+allproc_unlock(void)
+{
+ lockmgr(&__allproc_lock, LK_RELEASE, NULL, CURPROC);
+}
int enterpgrp __P((struct proc *p, pid_t pgid, int mksess));
void fixjobc __P((struct proc *p, struct pgrp *pgrp, int entering));
Index: vm/vm_glue.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_glue.c,v
retrieving revision 1.100
diff -u -r1.100 vm_glue.c
--- vm/vm_glue.c 2000/10/25 00:04:16 1.100
+++ vm/vm_glue.c 2000/11/19 10:14:55
@@ -360,6 +360,7 @@
pp = NULL;
ppri = INT_MIN;
+ allproc_lock(LK_SHARED);
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_stat == SRUN &&
(p->p_flag & (P_INMEM | P_SWAPPING)) == 0) {
@@ -381,6 +382,7 @@
}
}
+ allproc_unlock();
/*
* Nothing to do, back to sleep.
*/
@@ -439,6 +441,7 @@
outp = outp2 = NULL;
outpri = outpri2 = INT_MIN;
+ allproc_lock(LK_SHARED);
retry:
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
struct vmspace *vm;
@@ -504,6 +507,7 @@
}
}
}
+ allproc_unlock();
/*
* If we swapped something out, and another process needed memory,
* then wakeup the sched process.
Index: vm/vm_meter.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_meter.c,v
retrieving revision 1.41
diff -u -r1.41 vm_meter.c
--- vm/vm_meter.c 2000/09/15 22:00:22 1.41
+++ vm/vm_meter.c 2000/11/19 10:12:38
@@ -78,6 +78,7 @@
register int i, nrun;
register struct proc *p;
+ allproc_lock(LK_SHARED);
for (nrun = 0, p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
switch (p->p_stat) {
case SSLEEP:
@@ -92,6 +93,7 @@
nrun++;
}
}
+ allproc_unlock();
for (i = 0; i < 3; i++)
avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
@@ -149,6 +151,7 @@
/*
* Calculate process statistics.
*/
+ allproc_lock(LK_SHARED);
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if (p->p_flag & P_SYSTEM)
continue;
@@ -199,6 +202,7 @@
if (paging)
totalp->t_pw++;
}
+ allproc_unlock();
/*
* Calculate object memory usage statistics.
*/
Index: vm/vm_object.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_object.c,v
retrieving revision 1.177
diff -u -r1.177 vm_object.c
--- vm/vm_object.c 2000/05/29 22:40:54 1.177
+++ vm/vm_object.c 2000/11/19 10:12:38
@@ -1620,12 +1620,16 @@
vm_object_t object;
{
struct proc *p;
+ allproc_lock(LK_SHARED);
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
if( !p->p_vmspace /* || (p->p_flag & (P_SYSTEM|P_WEXIT)) */)
continue;
- if( _vm_object_in_map(&p->p_vmspace->vm_map, object, 0))
+ if( _vm_object_in_map(&p->p_vmspace->vm_map, object, 0)) {
+ allproc_unlock();
return 1;
+ }
}
+ allproc_unlock();
if( _vm_object_in_map( kernel_map, object, 0))
return 1;
if( _vm_object_in_map( kmem_map, object, 0))
Index: vm/vm_pageout.c
===================================================================
RCS file: /home/ncvs/src/sys/vm/vm_pageout.c,v
retrieving revision 1.162
diff -u -r1.162 vm_pageout.c
--- vm/vm_pageout.c 2000/11/18 23:06:26 1.162
+++ vm/vm_pageout.c 2000/11/19 10:16:05
@@ -1129,6 +1129,7 @@
if ((vm_swap_size < 64 || swap_pager_full) && vm_page_count_min()) {
bigproc = NULL;
bigsize = 0;
+ allproc_lock(LK_SHARED);
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
/*
* if this is a system process, skip it
@@ -1158,6 +1159,7 @@
bigsize = size;
}
}
+ allproc_unlock();
if (bigproc != NULL) {
killproc(bigproc, "out of swap space");
bigproc->p_estcpu = 0;
@@ -1442,6 +1444,7 @@
* process is swapped out -- deactivate pages
*/
+ allproc_lock(LK_SHARED);
for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
vm_pindex_t limit, size;
@@ -1480,6 +1483,7 @@
&p->p_vmspace->vm_map, limit);
}
}
+ allproc_unlock();
}
}
#endif
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20001120080655.5BEA4BA7A>
