PERFORCE change 188036 for review

Edward Tomasz Napierala trasz at FreeBSD.org
Fri Jan 21 17:11:29 UTC 2011


http://p4web.freebsd.org/@@188036?ac=10

Change 188036 by trasz at trasz_victim on 2011/01/21 17:11:09

	Since rusage_{add,sub,set} functions dereference p_ucred, we need
	to keep proc lock held when calling them.  In the future I'll probably
	move to using thread pointers instead of proc pointers, and I'll be
	able to use td_ucred, which is stable; for now, this will have to do.
	
	It's not _that_ ugly.

Affected files ...

.. //depot/projects/soc2009/trasz_limits/sys/kern/imgact_elf.c#23 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#36 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#57 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_descrip.c#19 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#30 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_fork.c#31 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_rctl.c#13 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_sig.c#20 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/kern_thr.c#13 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/sysv_msg.c#10 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/sysv_sem.c#11 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/sysv_shm.c#12 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/tty_pts.c#24 edit
.. //depot/projects/soc2009/trasz_limits/sys/kern/uipc_sockbuf.c#8 edit
.. //depot/projects/soc2009/trasz_limits/sys/vm/swap_pager.c#18 edit
.. //depot/projects/soc2009/trasz_limits/sys/vm/vm_glue.c#13 edit
.. //depot/projects/soc2009/trasz_limits/sys/vm/vm_map.c#31 edit
.. //depot/projects/soc2009/trasz_limits/sys/vm/vm_mmap.c#23 edit
.. //depot/projects/soc2009/trasz_limits/sys/vm/vm_pageout.c#24 edit
.. //depot/projects/soc2009/trasz_limits/sys/vm/vm_unix.c#14 edit

Differences ...

==== //depot/projects/soc2009/trasz_limits/sys/kern/imgact_elf.c#23 (text+ko) ====

@@ -1105,7 +1105,10 @@
 	hdrsize = 0;
 	__elfN(puthdr)(td, (void *)NULL, &hdrsize, seginfo.count);
 
-	if (rusage_add(td->td_proc, RUSAGE_CORE, hdrsize + seginfo.size)) {
+	PROC_LOCK(td->td_proc);
+	error = rusage_add(td->td_proc, RUSAGE_CORE, hdrsize + seginfo.size);
+	PROC_UNLOCK(td->td_proc);
+	if (error != 0) {
 		error = EFAULT;
 		goto done;
 	}

==== //depot/projects/soc2009/trasz_limits/sys/kern/init_main.c#36 (text+ko) ====

@@ -553,7 +553,9 @@
 	 * Charge root for one process.
 	 */
 	(void)chgproccnt(p->p_ucred->cr_ruidinfo, 1, 0);
+	PROC_LOCK(p);
 	rusage_add_force(p, RUSAGE_NPROC, 1);
+	PROC_UNLOCK(p);
 }
 SYSINIT(p0init, SI_SUB_INTRINSIC, SI_ORDER_FIRST, proc0_init, NULL);
 

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_container.c#57 (text+ko) ====

@@ -306,6 +306,10 @@
 
 	SDT_PROBE(container, kernel, rusage, add, p, resource, amount, 0, 0);
 
+	/*
+	 * We need proc lock to dereference p->p_ucred.
+	 */
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	KASSERT(amount >= 0, ("rusage_add: invalid amount for resource %d: %ju",
 	    resource, amount));
 
@@ -369,6 +373,10 @@
 
 	SDT_PROBE(container, kernel, rusage, add_force, p, resource, amount, 0, 0);
 
+	/*
+	 * We need proc lock to dereference p->p_ucred.
+	 */
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	KASSERT(amount >= 0, ("rusage_add_force: invalid amount for resource %d: %ju",
 	    resource, amount));
 
@@ -391,6 +399,10 @@
 
 	SDT_PROBE(container, kernel, rusage, set, p, resource, amount, 0, 0);
 
+	/*
+	 * We need proc lock to dereference p->p_ucred.
+	 */
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	KASSERT(amount >= 0, ("rusage_set: invalid amount for resource %d: %ju",
 	    resource, amount));
 
@@ -446,6 +458,10 @@
 
 	SDT_PROBE(container, kernel, rusage, set, p, resource, amount, 0, 0);
 
+	/*
+	 * We need proc lock to dereference p->p_ucred.
+	 */
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	KASSERT(amount >= 0, ("rusage_set: invalid amount for resource %d: %ju",
 	    resource, amount));
 
@@ -505,6 +521,10 @@
 
 	SDT_PROBE(container, kernel, rusage, sub, p, resource, amount, 0, 0);
 
+	/*
+	 * We need proc lock to dereference p->p_ucred.
+	 */
+	PROC_LOCK_ASSERT(p, MA_OWNED);
 	KASSERT(amount >= 0, ("rusage_sub: invalid amount for resource %d: %ju",
 	    resource, amount));
 	KASSERT(container_resource_reclaimable(resource),
@@ -600,15 +620,10 @@
 	}
 
 out:
-	mtx_unlock(&container_lock);
-	PROC_UNLOCK(child);
-	PROC_UNLOCK(parent);
-
 #ifdef RCTL
 	if (error == 0) {
 		error = rctl_proc_fork(parent, child);
 		if (error != 0) {
-			mtx_lock(&container_lock);
 			/*
 			 * XXX: The only purpose of these two lines is to prevent from
 			 * tripping checks in container_destroy().
@@ -616,11 +631,14 @@
 			for (i = 0; i <= RUSAGE_MAX; i++)
 				rusage_set_locked(child, i, 0);
 			container_destroy_locked(&child->p_container);
-			mtx_unlock(&container_lock);
 		}
 	}
 #endif
 
+	mtx_unlock(&container_lock);
+	PROC_UNLOCK(child);
+	PROC_UNLOCK(parent);
+
 	return (error);
 }
 
@@ -630,10 +648,12 @@
 	/*
 	 * XXX: Free this some other way.
 	 */
+	PROC_LOCK(p);
 	rusage_set(p, RUSAGE_FSIZE, 0);
 	rusage_set(p, RUSAGE_NPTS, 0);
 	rusage_set(p, RUSAGE_NTHR, 0);
 	rusage_set(p, RUSAGE_RSS, 0);
+	PROC_UNLOCK(p);
 
 #ifdef RCTL
 	rctl_proc_exit(p);
@@ -774,11 +794,13 @@
 			else
 				rusage_throttle(p, 0);
 			PROC_SUNLOCK(p);
-			rusage_set(p, RUSAGE_CPU, cputick2usec(p->p_rux.rux_runtime));
 			microuptime(&wallclock);
 			timevalsub(&wallclock, &p->p_stats->p_start);
+			PROC_LOCK(p);
 			rusage_set(p, RUSAGE_WALLCLOCK, wallclock.tv_sec * 1000000 + wallclock.tv_usec);
 			rusage_set(p, RUSAGE_PCTCPU, pctcpu);
+			rusage_set(p, RUSAGE_CPU, cputick2usec(p->p_rux.rux_runtime));
+			PROC_UNLOCK(p);
 		}
 		sx_sunlock(&allproc_lock);
 		pause("-", hz);

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_descrip.c#19 (text+ko) ====

@@ -279,8 +279,8 @@
 	PROC_LOCK(p);
 	td->td_retval[0] =
 	    min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+	lim = rusage_get_limit(td->td_proc, RUSAGE_NOFILE);
 	PROC_UNLOCK(p);
-	lim = rusage_get_limit(td->td_proc, RUSAGE_NOFILE);
 	if (lim < td->td_retval[0])
 		td->td_retval[0] = lim;
 	return (0);
@@ -804,7 +804,10 @@
 			 * descriptors, just put the limit on the size of the file
 			 * descriptor table.
 			 */
-			if (rusage_set(p, RUSAGE_NOFILE, new + 1)) {
+			PROC_LOCK(p);
+			error = rusage_set(p, RUSAGE_NOFILE, new + 1);
+			PROC_UNLOCK(p);
+			if (error != 0) {
 				FILEDESC_XUNLOCK(fdp);
 				fdrop(fp, td);
 				return (EMFILE);
@@ -1456,7 +1459,7 @@
 {
 	struct proc *p = td->td_proc;
 	struct filedesc *fdp = p->p_fd;
-	int fd = -1, maxfd;
+	int fd = -1, maxfd, error;
 
 	FILEDESC_XLOCK_ASSERT(fdp);
 
@@ -1479,7 +1482,10 @@
 			return (EMFILE);
 		if (fd < fdp->fd_nfiles)
 			break;
-		if (rusage_set(p, RUSAGE_NOFILE, min(fdp->fd_nfiles * 2, maxfd)))
+		PROC_LOCK(p);
+		error = rusage_set(p, RUSAGE_NOFILE, min(fdp->fd_nfiles * 2, maxfd));
+		PROC_UNLOCK(p);
+		if (error != 0)
 			return (EMFILE);
 		fdgrowtable(fdp, min(fdp->fd_nfiles * 2, maxfd));
 	}
@@ -1763,7 +1769,9 @@
 	if (fdp == NULL)
 		return;
 
+	PROC_LOCK(td->td_proc);
 	rusage_set(td->td_proc, RUSAGE_NOFILE, 0);
+	PROC_UNLOCK(td->td_proc);
 
 	/* Check for special need to clear POSIX style locks */
 	fdtol = td->td_proc->p_fdtol;

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_exit.c#30 (text+ko) ====

@@ -741,13 +741,17 @@
 	 * Decrement the count of procs running with this uid.
 	 */
 	(void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0);
-	rusage_set(p, RUSAGE_CPU, cputick2usec(p->p_rux.rux_runtime));
-	rusage_sub(p->p_pptr, RUSAGE_NPROC, 1);
 
 	/*
 	 * Destroy resource container associated with the process.
 	 */
+	PROC_LOCK(p);
+	rusage_set(p, RUSAGE_CPU, cputick2usec(p->p_rux.rux_runtime));
+	PROC_UNLOCK(p);
 	container_proc_exit(p);
+	PROC_LOCK(p->p_pptr);
+	rusage_sub(p->p_pptr, RUSAGE_NPROC, 1);
+	PROC_UNLOCK(p->p_pptr);
 
 	/*
 	 * Free credentials, arguments, and sigacts.
@@ -908,10 +912,11 @@
 	if (child->p_pptr == parent)
 		return;
 
-	rusage_sub(child->p_pptr, RUSAGE_NPROC, 1);
+	PROC_LOCK(parent);
 	rusage_add_force(parent, RUSAGE_NPROC, 1);
-
+	PROC_UNLOCK(parent);
 	PROC_LOCK(child->p_pptr);
+	rusage_sub(child->p_pptr, RUSAGE_NPROC, 1);
 	sigqueue_take(child->p_ksi);
 	PROC_UNLOCK(child->p_pptr);
 	LIST_REMOVE(child, p_sibling);

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_fork.c#31 (text+ko) ====

@@ -712,7 +712,9 @@
 		return (fork_norfproc(td, flags));
 	}
 
+	PROC_LOCK(p1);
 	error = rusage_add(p1, RUSAGE_NPROC, 1);
+	PROC_UNLOCK(p1);
 	if (error != 0)
 		return (error);
 
@@ -801,7 +803,9 @@
 	/*
 	 * After fork, there is exactly one thread running.
 	 */
+	PROC_LOCK(newproc);
 	error = rusage_set(newproc, RUSAGE_NTHR, 1);
+	PROC_UNLOCK(newproc);
 	if (error != 0) {
 		error = EAGAIN;
 		goto fail;
@@ -848,7 +852,9 @@
 		vmspace_free(vm2);
 	uma_zfree(proc_zone, newproc);
 	pause("fork", hz / 2);
+	PROC_LOCK(p1);
 	rusage_sub(p1, RUSAGE_NPROC, 1);
+	PROC_UNLOCK(p1);
 	return (error);
 }
 

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_rctl.c#13 (text+ko) ====

@@ -185,24 +185,6 @@
 	panic("rctl_resource_name: unknown resource %d", resource);
 }
 
-static void
-rctl_deferred_psignal(struct proc *p, int signum)
-{
-	int need_lock;
-
-	/*
-	 * XXX: This is ugly.  Either turn it into a real taskqueue,
-	 *      or think about the locking and don't lock proc here.
-	 */
-	need_lock = !PROC_LOCKED(p);
-
-	if (need_lock)
-		PROC_LOCK(p);
-	psignal(p, signum);
-	if (need_lock)
-		PROC_UNLOCK(p);
-}
-
 /*
  * Return the amount of resource that can be allocated by 'p' before
  * hitting 'rule'.
@@ -325,22 +307,22 @@
 			free(buf, M_RCTL);
 			continue;
 		case RCTL_ACTION_SIGHUP:
-			rctl_deferred_psignal(p, SIGHUP);
+			psignal(p, SIGHUP);
 			continue;
 		case RCTL_ACTION_SIGINT:
-			rctl_deferred_psignal(p, SIGINT);
+			psignal(p, SIGINT);
 			continue;
 		case RCTL_ACTION_SIGKILL:
-			rctl_deferred_psignal(p, SIGKILL);
+			psignal(p, SIGKILL);
 			continue;
 		case RCTL_ACTION_SIGSEGV:
-			rctl_deferred_psignal(p, SIGSEGV);
+			psignal(p, SIGSEGV);
 			continue;
 		case RCTL_ACTION_SIGXCPU:
-			rctl_deferred_psignal(p, SIGXCPU);
+			psignal(p, SIGXCPU);
 			continue;
 		case RCTL_ACTION_SIGXFSZ:
-			rctl_deferred_psignal(p, SIGXFSZ);
+			psignal(p, SIGXFSZ);
 			continue;
 		default:
 			panic("rctl_enforce: unknown action %d",

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_sig.c#20 (text+ko) ====

@@ -3169,15 +3169,15 @@
 	 * if it is larger than the limit.
 	 */
 	limit = (off_t)lim_cur(p, RLIMIT_CORE);
-	PROC_UNLOCK(p);
-	if (limit == 0 && rusage_add(td->td_proc, RUSAGE_CORE, 1) == 0) {
-		rusage_sub(td->td_proc, RUSAGE_CORE, 1);
+	if (limit == 0 && rusage_get_available(p, RUSAGE_CORE) == 0) {
+		PROC_UNLOCK(p);
 #ifdef AUDIT
 		audit_proc_coredump(td, name, EFBIG);
 #endif
 		free(name, M_TEMP);
 		return (EFBIG);
 	}
+	PROC_UNLOCK(p);
 
 restart:
 	NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, name, td);

==== //depot/projects/soc2009/trasz_limits/sys/kern/kern_thr.c#13 (text+ko) ====

@@ -176,7 +176,11 @@
 			return (EINVAL);
 		}
 	}
-	if (rusage_add(p, RUSAGE_NTHR, 1))
+
+	PROC_LOCK(td->td_proc);
+	error = rusage_add(p, RUSAGE_NTHR, 1);
+	PROC_UNLOCK(td->td_proc);
+	if (error != 0)
 		return (EPROCLIM);
 
 	/* Initialize our td */
@@ -265,7 +269,9 @@
 	return (0);
 
 fail:
+	PROC_LOCK(p);
 	rusage_sub(p, RUSAGE_NTHR, 1);
+	PROC_UNLOCK(p);
 	return (error);
 }
 
@@ -297,9 +303,9 @@
 
 	rw_wlock(&tidhash_lock);
 
+	PROC_LOCK(p);
 	rusage_sub(p, RUSAGE_NTHR, 1);
 
-	PROC_LOCK(p);
 	/*
 	 * Shutting down last thread in the proc.  This will actually
 	 * call exit() in the trampoline when it returns.

==== //depot/projects/soc2009/trasz_limits/sys/kern/sysv_msg.c#10 (text+ko) ====

@@ -618,7 +618,10 @@
 			error = ENOSPC;
 			goto done2;
 		}
-		if (rusage_add(td->td_proc, RUSAGE_NMSGQ, 1)) {
+		PROC_LOCK(td->td_proc);
+		error = rusage_add(td->td_proc, RUSAGE_NMSGQ, 1);
+		PROC_UNLOCK(td->td_proc);
+		if (error != 0) {
 			error = ENOSPC;
 			goto done2;
 		}
@@ -719,16 +722,20 @@
 		goto done2;
 #endif
 
+	PROC_LOCK(td->td_proc);
 	if (rusage_add(td->td_proc, RUSAGE_MSGQQUEUED, 1)) {
+		PROC_UNLOCK(td->td_proc);
 		error = EAGAIN;
 		goto done2;
 	}
 	saved_msgsz = msgsz;
 	if (rusage_add(td->td_proc, RUSAGE_MSGQSIZE, msgsz)) {
 		rusage_sub(td->td_proc, RUSAGE_MSGQQUEUED, 1);
+		PROC_UNLOCK(td->td_proc);
 		error = EAGAIN;
 		goto done2;
 	}
+	PROC_UNLOCK(td->td_proc);
 
 	segs_needed = (msgsz + msginfo.msgssz - 1) / msginfo.msgssz;
 	DPRINTF(("msgsz=%zu, msgssz=%d, segs_needed=%d\n", msgsz,
@@ -984,8 +991,10 @@
 	td->td_retval[0] = 0;
 done3:
 	if (error != 0) {
+		PROC_LOCK(td->td_proc);
 		rusage_sub(td->td_proc, RUSAGE_MSGQQUEUED, 1);
 		rusage_sub(td->td_proc, RUSAGE_MSGQSIZE, saved_msgsz);
+		PROC_UNLOCK(td->td_proc);
 	}
 done2:
 	mtx_unlock(&msq_mtx);

==== //depot/projects/soc2009/trasz_limits/sys/kern/sysv_sem.c#11 (text+ko) ====

@@ -929,7 +929,10 @@
 			error = ENOSPC;
 			goto done2;
 		}
-		if (rusage_add(td->td_proc, RUSAGE_NSEM, nsems)) {
+		PROC_LOCK(td->td_proc);
+		error = rusage_add(td->td_proc, RUSAGE_NSEM, nsems);
+		PROC_UNLOCK(td->td_proc);
+		if (error != 0) {
 			error = ENOSPC;
 			goto done2;
 		}
@@ -1018,10 +1021,16 @@
 		DPRINTF(("too many sops (max=%d, nsops=%d)\n", seminfo.semopm,
 		    nsops));
 		return (E2BIG);
-	} else if (nsops > rusage_get_available(td->td_proc, RUSAGE_NSEMOP)) {
-		return (E2BIG);
-	} else
+	} else {
+		PROC_LOCK(td->td_proc);
+		if (nsops > rusage_get_available(td->td_proc, RUSAGE_NSEMOP)) {
+			PROC_UNLOCK(td->td_proc);
+			return (E2BIG);
+		}
+		PROC_UNLOCK(td->td_proc);
+
 		sops = malloc(nsops * sizeof(*sops), M_TEMP, M_WAITOK);
+	}
 	if ((error = copyin(uap->sops, sops, nsops * sizeof(sops[0]))) != 0) {
 		DPRINTF(("error = %d from copyin(%p, %p, %d)\n", error,
 		    uap->sops, sops, nsops * sizeof(sops[0])));

==== //depot/projects/soc2009/trasz_limits/sys/kern/sysv_shm.c#12 (text+ko) ====

@@ -670,12 +670,17 @@
 		shm_last_free = -1;
 	}
 	shmseg = &shmsegs[segnum];
-	if (rusage_add(td->td_proc, RUSAGE_NSHM, 1))
+	PROC_LOCK(td->td_proc);
+	if (rusage_add(td->td_proc, RUSAGE_NSHM, 1)) {
+		PROC_UNLOCK(td->td_proc);
 		return (ENOSPC);
+	}
 	if (rusage_add(td->td_proc, RUSAGE_SHMSIZE, size)) {
 		rusage_sub(td->td_proc, RUSAGE_NSHM, 1);
+		PROC_UNLOCK(td->td_proc);
 		return (ENOMEM);
 	}
+	PROC_UNLOCK(td->td_proc);
 	/*
 	 * In case we sleep in malloc(), mark the segment present but deleted
 	 * so that noone else tries to create the same key.
@@ -692,8 +697,10 @@
 	shm_object = vm_pager_allocate(shm_use_phys ? OBJT_PHYS : OBJT_SWAP,
 	    0, size, VM_PROT_DEFAULT, 0, cred);
 	if (shm_object == NULL) {
+		PROC_LOCK(td->td_proc);
 		rusage_sub(td->td_proc, RUSAGE_NSHM, 1);
 		rusage_sub(td->td_proc, RUSAGE_SHMSIZE, size);
+		PROC_UNLOCK(td->td_proc);
 		return (ENOMEM);
 	}
 	VM_OBJECT_LOCK(shm_object);

==== //depot/projects/soc2009/trasz_limits/sys/kern/tty_pts.c#24 (text+ko) ====

@@ -721,16 +721,19 @@
 	struct ucred *cred = td->td_ucred;
 
 	/* Resource limiting. */
+	PROC_LOCK(p);
 	error = rusage_add(p, RUSAGE_NPTS, 1);
-	if (error != 0)
+	if (error != 0) {
+		PROC_UNLOCK(p);
 		return (EAGAIN);
-	PROC_LOCK(p);
+	}
 	ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(p, RLIMIT_NPTS));
-	PROC_UNLOCK(p);
 	if (!ok) {
 		rusage_sub(p, RUSAGE_NPTS, 1);
+		PROC_UNLOCK(p);
 		return (EAGAIN);
 	}
+	PROC_UNLOCK(p);
 
 	/* Try to allocate a new pts unit number. */
 	unit = alloc_unr(pts_pool);
@@ -772,16 +775,19 @@
 	struct ucred *cred = td->td_ucred;
 
 	/* Resource limiting. */
+	PROC_LOCK(p);
 	error = rusage_add(p, RUSAGE_NPTS, 1);
-	if (error != 0)
+	if (error != 0) {
+		PROC_UNLOCK(p);
 		return (EAGAIN);
-	PROC_LOCK(p);
+	}
 	ok = chgptscnt(cred->cr_ruidinfo, 1, lim_cur(p, RLIMIT_NPTS));
-	PROC_UNLOCK(p);
 	if (!ok) {
 		rusage_sub(p, RUSAGE_NPTS, 1);
+		PROC_UNLOCK(p);
 		return (EAGAIN);
 	}
+	PROC_UNLOCK(p);
 
 	/* Allocate TTY and softc. */
 	psc = malloc(sizeof(struct pts_softc), M_PTS, M_WAITOK|M_ZERO);

==== //depot/projects/soc2009/trasz_limits/sys/kern/uipc_sockbuf.c#8 (text+ko) ====

@@ -307,8 +307,8 @@
 	if (td != NULL) {
 		PROC_LOCK(td->td_proc);
 		sbsize_limit = lim_cur(td->td_proc, RLIMIT_SBSIZE);
+		error = rusage_add(td->td_proc, RUSAGE_SBSIZE, cc);
 		PROC_UNLOCK(td->td_proc);
-		error = rusage_add(td->td_proc, RUSAGE_SBSIZE, cc);
 		if (error != 0)
 			return (0);
 	} else {

==== //depot/projects/soc2009/trasz_limits/sys/vm/swap_pager.c#18 (text+ko) ====

@@ -192,7 +192,10 @@
 	if (incr & PAGE_MASK)
 		panic("swap_reserve: & PAGE_MASK");
 
-	if (rusage_add(curproc, RUSAGE_SWAP, incr))
+	PROC_LOCK(curproc);
+	error = rusage_add(curproc, RUSAGE_SWAP, incr);
+	PROC_UNLOCK(curproc);
+	if (error != 0)
 		return (0);
 
 	res = 0;
@@ -233,8 +236,11 @@
 		    curproc->p_pid, uip->ui_uid, incr);
 	}
 
-	if (!res)
+	if (!res) {
+		PROC_LOCK(curproc);
 		rusage_sub(curproc, RUSAGE_SWAP, incr);
+		PROC_UNLOCK(curproc);
+	}
 
 	return (res);
 }
@@ -248,7 +254,9 @@
 	swap_reserved += incr;
 	mtx_unlock(&sw_dev_mtx);
 
+	PROC_LOCK(curproc);
 	rusage_add_force(curproc, RUSAGE_SWAP, incr);
+	PROC_UNLOCK(curproc);
 
 	uip = curthread->td_ucred->cr_ruidinfo;
 	PROC_LOCK(curproc);

==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_glue.c#13 (text+ko) ====

@@ -202,6 +202,10 @@
 		PROC_UNLOCK(curproc);
 		return (ENOMEM);
 	}
+	if (rusage_set(curproc, RUSAGE_MEMLOCK, nsize)) {
+		PROC_UNLOCK(curproc);
+		return (ENOMEM);
+	}
 	PROC_UNLOCK(curproc);
 #if 0
 	/*
@@ -216,13 +220,14 @@
 	if (npages + cnt.v_wire_count > vm_page_max_wired)
 		return (EAGAIN);
 #endif
-	if (rusage_set(curproc, RUSAGE_MEMLOCK, nsize))
-		return (ENOMEM);
 	error = vm_map_wire(&curproc->p_vmspace->vm_map, start, end,
 	    VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
-	if (error != KERN_SUCCESS)
+	if (error != KERN_SUCCESS) {
+		PROC_LOCK(curproc);
 		rusage_set(curproc, RUSAGE_MEMLOCK, 
 		    ptoa(pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map))));
+		PROC_UNLOCK(curproc);
+	}
 	/*
 	 * Return EFAULT on error to match copy{in,out}() behaviour
 	 * rather than returning ENOMEM like mlock() would.
@@ -239,8 +244,10 @@
 	    trunc_page((vm_offset_t)addr), round_page((vm_offset_t)addr + len),
 	    VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
 
+	PROC_LOCK(curproc);
 	rusage_set(curproc, RUSAGE_MEMLOCK,
 	    ptoa(pmap_wired_count(vm_map_pmap(&curproc->p_vmspace->vm_map))));
+	PROC_UNLOCK(curproc);
 }
 
 /*

==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_map.c#31 (text+ko) ====

@@ -318,11 +318,13 @@
 vmspace_container_reset(struct proc *p)
 {
 
+	PROC_LOCK(p);
 	rusage_set(p, RUSAGE_DATA, 0);
 	rusage_set(p, RUSAGE_STACK, 0);
 	rusage_set(p, RUSAGE_RSS, 0);
 	rusage_set(p, RUSAGE_MEMLOCK, 0);
 	rusage_set(p, RUSAGE_VMEM, 0);
+	PROC_UNLOCK(p);
 }
 
 static inline void
@@ -3397,11 +3399,14 @@
 		vm_map_unlock_read(map);
 		return (KERN_NO_SPACE);
 	}
+	PROC_LOCK(p);
 	if (is_procstack &&
 	    rusage_set(p, RUSAGE_STACK, ctob(vm->vm_ssize) + grow_amount)) {
+		PROC_UNLOCK(p);
 		vm_map_unlock_read(map);
 		return (KERN_NO_SPACE);
 	}
+	PROC_UNLOCK(p);
 
 	/* Round up the grow amount modulo SGROWSIZ */
 	grow_amount = roundup (grow_amount, sgrowsiz);
@@ -3412,7 +3417,9 @@
 		    ctob(vm->vm_ssize);
 	}
 #ifdef notyet
+	PROC_LOCK(p);
 	limit = rusage_get_available(p, RUSAGE_STACK);
+	PROC_UNLOCK(p);
 	if (is_procstack && (ctob(vm->vm_ssize) + grow_amount > limit))
 		grow_amount = limit - ctob(vm->vm_ssize);
 #endif
@@ -3423,11 +3430,14 @@
 		rv = KERN_NO_SPACE;
 		goto out;
 	}
+	PROC_LOCK(p);
 	if (rusage_set(p, RUSAGE_VMEM, map->size + grow_amount)) {
+		PROC_UNLOCK(p);
 		vm_map_unlock_read(map);
 		rv = KERN_NO_SPACE;
 		goto out;
 	}
+	PROC_UNLOCK(p);
 
 	if (vm_map_lock_upgrade(map))
 		goto Retry;
@@ -3528,10 +3538,12 @@
 
 out:
 	if (rv != KERN_SUCCESS) {
+		PROC_LOCK(p);
 		error = rusage_set(p, RUSAGE_VMEM, map->size);
 		KASSERT(error == 0, ("decreasing RUSAGE_VMEM failed"));
 	    	error = rusage_set(p, RUSAGE_STACK, ctob(vm->vm_ssize));
 		KASSERT(error == 0, ("decreasing RUSAGE_STACK failed"));
+		PROC_UNLOCK(p);
 	}
 
 	return (rv);

==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_mmap.c#23 (text+ko) ====

@@ -1058,13 +1058,19 @@
 	PROC_UNLOCK(proc);
 	if (npages + cnt.v_wire_count > vm_page_max_wired)
 		return (EAGAIN);
-	if (rusage_set(proc, RUSAGE_MEMLOCK, nsize))
+	PROC_LOCK(proc);
+	error = rusage_set(proc, RUSAGE_MEMLOCK, nsize);
+	PROC_UNLOCK(proc);
+	if (error != 0)
 		return (ENOMEM);
 	error = vm_map_wire(&proc->p_vmspace->vm_map, start, end,
 	    VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
-	if (error != KERN_SUCCESS)
+	if (error != KERN_SUCCESS) {
+		PROC_LOCK(proc);
 		rusage_set(proc, RUSAGE_MEMLOCK,
 		    ptoa(pmap_wired_count(vm_map_pmap(&proc->p_vmspace->vm_map))));
+		PROC_UNLOCK(proc);
+	}
 	return (error == KERN_SUCCESS ? 0 : ENOMEM);
 }
 
@@ -1107,7 +1113,10 @@
 	if (error)
 		return (error);
 #endif
-	if (rusage_set(td->td_proc, RUSAGE_MEMLOCK, map->size))
+	PROC_LOCK(td->td_proc);
+	error = rusage_set(td->td_proc, RUSAGE_MEMLOCK, map->size);
+	PROC_UNLOCK(td->td_proc);
+	if (error != 0)
 		return (ENOMEM);
 
 	if (uap->how & MCL_FUTURE) {
@@ -1128,9 +1137,12 @@
 		    VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
 		error = (error == KERN_SUCCESS ? 0 : EAGAIN);
 	}
-	if (error != KERN_SUCCESS)
+	if (error != KERN_SUCCESS) {
+		PROC_LOCK(td->td_proc);
 		rusage_set(td->td_proc, RUSAGE_MEMLOCK,
 		    ptoa(pmap_wired_count(vm_map_pmap(&td->td_proc->p_vmspace->vm_map))));
+		PROC_UNLOCK(td->td_proc);
+	}
 
 	return (error);
 }
@@ -1165,8 +1177,11 @@
 	/* Forcibly unwire all pages. */
 	error = vm_map_unwire(map, vm_map_min(map), vm_map_max(map),
 	    VM_MAP_WIRE_USER|VM_MAP_WIRE_HOLESOK);
-	if (error == KERN_SUCCESS)
+	if (error == KERN_SUCCESS) {
+		PROC_LOCK(td->td_proc);
 		rusage_set(td->td_proc, RUSAGE_MEMLOCK, 0);
+		PROC_UNLOCK(td->td_proc);
+	}
 
 	return (error);
 }
@@ -1201,8 +1216,11 @@
 		return (EINVAL);
 	error = vm_map_unwire(&td->td_proc->p_vmspace->vm_map, start, end,
 	    VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES);
-	if (error == KERN_SUCCESS)
+	if (error == KERN_SUCCESS) {
+		PROC_LOCK(td->td_proc);
 		rusage_sub(td->td_proc, RUSAGE_MEMLOCK, ptoa(end - start));
+		PROC_UNLOCK(td->td_proc);
+	}
 	return (error == KERN_SUCCESS ? 0 : ENOMEM);
 }
 
@@ -1435,10 +1453,12 @@
 		PROC_UNLOCK(td->td_proc);
 		return(ENOMEM);
 	}
-	PROC_UNLOCK(td->td_proc);
 	if (rusage_set(td->td_proc, RUSAGE_VMEM,
-	    td->td_proc->p_vmspace->vm_map.size + size))
+	    td->td_proc->p_vmspace->vm_map.size + size)) {
+		PROC_UNLOCK(td->td_proc);
 		return (ENOMEM);
+	}
+	PROC_UNLOCK(td->td_proc);
 
 	/*
 	 * We currently can only deal with page aligned file offsets.

==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_pageout.c#24 (text+ko) ====

@@ -1711,8 +1711,10 @@
 				    &vm->vm_map, limit);
 			}
 			rsize = IDX_TO_OFF(size);
+			PROC_LOCK(p);
 			rusage_set(p, RUSAGE_RSS, rsize);
 			ravailable = rusage_get_available(p, RUSAGE_RSS);
+			PROC_UNLOCK(p);
 			if (rsize > ravailable) {
 				/*
 				 * Don't be overly aggressive; this might be
@@ -1730,7 +1732,9 @@
 				/* Update RSS usage after paging out. */
 				size = vmspace_resident_count(vm);
 				rsize = IDX_TO_OFF(size);
+				PROC_LOCK(p);
 				rusage_set(p, RUSAGE_RSS, rsize);
+				PROC_UNLOCK(p);
 				if (rsize > ravailable)
 					tryagain++;
 				if (tryagain > 20) {

==== //depot/projects/soc2009/trasz_limits/sys/vm/vm_unix.c#14 (text+ko) ====

@@ -117,8 +117,10 @@
 			error = ENOMEM;
 			goto done;
 		}
+		PROC_LOCK(td->td_proc);
 		error = rusage_set(td->td_proc, RUSAGE_DATA, new - base);
 		if (error != 0) {
+			PROC_UNLOCK(td->td_proc);
 			error = ENOMEM;
 			goto done;
 		}
@@ -126,14 +128,18 @@
 		    vm->vm_map.size + (new - old));
 		if (error != 0) {
 			rusage_set_force(td->td_proc, RUSAGE_DATA, old - base);
+			PROC_UNLOCK(td->td_proc);
 			error = ENOMEM;
 			goto done;
 		}
+		PROC_UNLOCK(td->td_proc);
 		rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new,
 		    VM_PROT_RW, VM_PROT_ALL, 0);
 		if (rv != KERN_SUCCESS) {
+			PROC_LOCK(td->td_proc);
 			rusage_set_force(td->td_proc, RUSAGE_DATA, old - base);
 			rusage_set_force(td->td_proc, RUSAGE_VMEM, vm->vm_map.size);
+			PROC_UNLOCK(td->td_proc);
 			error = ENOMEM;
 			goto done;
 		}
@@ -159,8 +165,10 @@
 			goto done;
 		}
 		vm->vm_dsize -= btoc(old - new);
+		PROC_LOCK(td->td_proc);
 		rusage_set_force(td->td_proc, RUSAGE_DATA, new - base);
 		rusage_set_force(td->td_proc, RUSAGE_VMEM, vm->vm_map.size);
+		PROC_UNLOCK(td->td_proc);
 	}
 done:
 	vm_map_unlock(&vm->vm_map);


More information about the p4-projects mailing list