Skip site navigation (1)Skip section navigation (2)
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>