xref: /freebsd/sys/kern/kern_racct.c (revision 43764a7ffa9ad6eba3275410bc2397d3d398f75f)
1 /*-
2  * Copyright (c) 2010 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Edward Tomasz Napierala under sponsorship
6  * from the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34 
35 #include "opt_kdtrace.h"
36 
37 #include <sys/param.h>
38 #include <sys/eventhandler.h>
39 #include <sys/param.h>
40 #include <sys/jail.h>
41 #include <sys/kernel.h>
42 #include <sys/kthread.h>
43 #include <sys/lock.h>
44 #include <sys/loginclass.h>
45 #include <sys/malloc.h>
46 #include <sys/mutex.h>
47 #include <sys/proc.h>
48 #include <sys/racct.h>
49 #include <sys/resourcevar.h>
50 #include <sys/sbuf.h>
51 #include <sys/sched.h>
52 #include <sys/sdt.h>
53 #include <sys/sx.h>
54 #include <sys/sysent.h>
55 #include <sys/sysproto.h>
56 #include <sys/systm.h>
57 #include <sys/umtx.h>
58 
59 #ifdef RCTL
60 #include <sys/rctl.h>
61 #endif
62 
63 #ifdef RACCT
64 
65 FEATURE(racct, "Resource Accounting");
66 
67 static struct mtx racct_lock;
68 MTX_SYSINIT(racct_lock, &racct_lock, "racct lock", MTX_DEF);
69 
70 static uma_zone_t racct_zone;
71 
72 static void racct_sub_racct(struct racct *dest, const struct racct *src);
73 static void racct_sub_cred_locked(struct ucred *cred, int resource,
74 		uint64_t amount);
75 static void racct_add_cred_locked(struct ucred *cred, int resource,
76 		uint64_t amount);
77 
78 SDT_PROVIDER_DEFINE(racct);
79 SDT_PROBE_DEFINE3(racct, kernel, rusage, add, add, "struct proc *", "int",
80     "uint64_t");
81 SDT_PROBE_DEFINE3(racct, kernel, rusage, add_failure, add-failure,
82     "struct proc *", "int", "uint64_t");
83 SDT_PROBE_DEFINE3(racct, kernel, rusage, add_cred, add-cred, "struct ucred *",
84     "int", "uint64_t");
85 SDT_PROBE_DEFINE3(racct, kernel, rusage, add_force, add-force, "struct proc *",
86     "int", "uint64_t");
87 SDT_PROBE_DEFINE3(racct, kernel, rusage, set, set, "struct proc *", "int",
88     "uint64_t");
89 SDT_PROBE_DEFINE3(racct, kernel, rusage, set_failure, set-failure,
90     "struct proc *", "int", "uint64_t");
91 SDT_PROBE_DEFINE3(racct, kernel, rusage, sub, sub, "struct proc *", "int",
92     "uint64_t");
93 SDT_PROBE_DEFINE3(racct, kernel, rusage, sub_cred, sub-cred, "struct ucred *",
94     "int", "uint64_t");
95 SDT_PROBE_DEFINE1(racct, kernel, racct, create, create, "struct racct *");
96 SDT_PROBE_DEFINE1(racct, kernel, racct, destroy, destroy, "struct racct *");
97 SDT_PROBE_DEFINE2(racct, kernel, racct, join, join, "struct racct *",
98     "struct racct *");
99 SDT_PROBE_DEFINE2(racct, kernel, racct, join_failure, join-failure,
100     "struct racct *", "struct racct *");
101 SDT_PROBE_DEFINE2(racct, kernel, racct, leave, leave, "struct racct *",
102     "struct racct *");
103 
104 int racct_types[] = {
105 	[RACCT_CPU] =
106 		RACCT_IN_THOUSANDS,
107 	[RACCT_DATA] =
108 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
109 	[RACCT_STACK] =
110 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
111 	[RACCT_CORE] =
112 		RACCT_DENIABLE,
113 	[RACCT_RSS] =
114 		RACCT_RECLAIMABLE,
115 	[RACCT_MEMLOCK] =
116 		RACCT_RECLAIMABLE | RACCT_DENIABLE,
117 	[RACCT_NPROC] =
118 		RACCT_RECLAIMABLE | RACCT_DENIABLE,
119 	[RACCT_NOFILE] =
120 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
121 	[RACCT_VMEM] =
122 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
123 	[RACCT_NPTS] =
124 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
125 	[RACCT_SWAP] =
126 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
127 	[RACCT_NTHR] =
128 		RACCT_RECLAIMABLE | RACCT_DENIABLE,
129 	[RACCT_MSGQQUEUED] =
130 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
131 	[RACCT_MSGQSIZE] =
132 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
133 	[RACCT_NMSGQ] =
134 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
135 	[RACCT_NSEM] =
136 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
137 	[RACCT_NSEMOP] =
138 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
139 	[RACCT_NSHM] =
140 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
141 	[RACCT_SHMSIZE] =
142 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
143 	[RACCT_WALLCLOCK] =
144 		RACCT_IN_THOUSANDS };
145 
146 static void
147 racct_add_racct(struct racct *dest, const struct racct *src)
148 {
149 	int i;
150 
151 	mtx_assert(&racct_lock, MA_OWNED);
152 
153 	/*
154 	 * Update resource usage in dest.
155 	 */
156 	for (i = 0; i <= RACCT_MAX; i++) {
157 		KASSERT(dest->r_resources[i] >= 0,
158 		    ("racct propagation meltdown: dest < 0"));
159 		KASSERT(src->r_resources[i] >= 0,
160 		    ("racct propagation meltdown: src < 0"));
161 		dest->r_resources[i] += src->r_resources[i];
162 	}
163 }
164 
165 static void
166 racct_sub_racct(struct racct *dest, const struct racct *src)
167 {
168 	int i;
169 
170 	mtx_assert(&racct_lock, MA_OWNED);
171 
172 	/*
173 	 * Update resource usage in dest.
174 	 */
175 	for (i = 0; i <= RACCT_MAX; i++) {
176 		if (!racct_is_sloppy(i)) {
177 			KASSERT(dest->r_resources[i] >= 0,
178 			    ("racct propagation meltdown: dest < 0"));
179 			KASSERT(src->r_resources[i] >= 0,
180 			    ("racct propagation meltdown: src < 0"));
181 			KASSERT(src->r_resources[i] <= dest->r_resources[i],
182 			    ("racct propagation meltdown: src > dest"));
183 		}
184 		if (racct_is_reclaimable(i)) {
185 			dest->r_resources[i] -= src->r_resources[i];
186 			if (dest->r_resources[i] < 0) {
187 				KASSERT(racct_is_sloppy(i),
188 				    ("racct_sub_racct: usage < 0"));
189 				dest->r_resources[i] = 0;
190 			}
191 		}
192 	}
193 }
194 
195 void
196 racct_create(struct racct **racctp)
197 {
198 
199 	SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0);
200 
201 	KASSERT(*racctp == NULL, ("racct already allocated"));
202 
203 	*racctp = uma_zalloc(racct_zone, M_WAITOK | M_ZERO);
204 }
205 
206 static void
207 racct_destroy_locked(struct racct **racctp)
208 {
209 	int i;
210 	struct racct *racct;
211 
212 	SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0);
213 
214 	mtx_assert(&racct_lock, MA_OWNED);
215 	KASSERT(racctp != NULL, ("NULL racctp"));
216 	KASSERT(*racctp != NULL, ("NULL racct"));
217 
218 	racct = *racctp;
219 
220 	for (i = 0; i <= RACCT_MAX; i++) {
221 		if (racct_is_sloppy(i))
222 			continue;
223 		if (!racct_is_reclaimable(i))
224 			continue;
225 		KASSERT(racct->r_resources[i] == 0,
226 		    ("destroying non-empty racct: "
227 		    "%ju allocated for resource %d\n",
228 		    racct->r_resources[i], i));
229 	}
230 	uma_zfree(racct_zone, racct);
231 	*racctp = NULL;
232 }
233 
234 void
235 racct_destroy(struct racct **racct)
236 {
237 
238 	mtx_lock(&racct_lock);
239 	racct_destroy_locked(racct);
240 	mtx_unlock(&racct_lock);
241 }
242 
243 /*
244  * Increase consumption of 'resource' by 'amount' for 'racct'
245  * and all its parents.  Differently from other cases, 'amount' here
246  * may be less than zero.
247  */
248 static void
249 racct_alloc_resource(struct racct *racct, int resource,
250     uint64_t amount)
251 {
252 
253 	mtx_assert(&racct_lock, MA_OWNED);
254 	KASSERT(racct != NULL, ("NULL racct"));
255 
256 	racct->r_resources[resource] += amount;
257 	if (racct->r_resources[resource] < 0) {
258 		KASSERT(racct_is_sloppy(resource),
259 		    ("racct_alloc_resource: usage < 0"));
260 		racct->r_resources[resource] = 0;
261 	}
262 }
263 
264 /*
265  * Increase allocation of 'resource' by 'amount' for process 'p'.
266  * Return 0 if it's below limits, or errno, if it's not.
267  */
268 int
269 racct_add(struct proc *p, int resource, uint64_t amount)
270 {
271 #ifdef RCTL
272 	int error;
273 #endif
274 
275 	if (p->p_flag & P_SYSTEM)
276 		return (0);
277 
278 	SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0);
279 
280 	/*
281 	 * We need proc lock to dereference p->p_ucred.
282 	 */
283 	PROC_LOCK_ASSERT(p, MA_OWNED);
284 
285 	mtx_lock(&racct_lock);
286 #ifdef RCTL
287 	error = rctl_enforce(p, resource, amount);
288 	if (error && racct_is_deniable(resource)) {
289 		SDT_PROBE(racct, kernel, rusage, add_failure, p, resource,
290 		    amount, 0, 0);
291 		mtx_unlock(&racct_lock);
292 		return (error);
293 	}
294 #endif
295 	racct_alloc_resource(p->p_racct, resource, amount);
296 	racct_add_cred_locked(p->p_ucred, resource, amount);
297 	mtx_unlock(&racct_lock);
298 
299 	return (0);
300 }
301 
302 static void
303 racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount)
304 {
305 	struct prison *pr;
306 
307 	SDT_PROBE(racct, kernel, rusage, add_cred, cred, resource, amount,
308 	    0, 0);
309 
310 	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
311 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
312 		racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
313 		    amount);
314 	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount);
315 }
316 
317 /*
318  * Increase allocation of 'resource' by 'amount' for credential 'cred'.
319  * Doesn't check for limits and never fails.
320  *
321  * XXX: Shouldn't this ever return an error?
322  */
323 void
324 racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
325 {
326 
327 	mtx_lock(&racct_lock);
328 	racct_add_cred_locked(cred, resource, amount);
329 	mtx_unlock(&racct_lock);
330 }
331 
332 /*
333  * Increase allocation of 'resource' by 'amount' for process 'p'.
334  * Doesn't check for limits and never fails.
335  */
336 void
337 racct_add_force(struct proc *p, int resource, uint64_t amount)
338 {
339 
340 	if (p->p_flag & P_SYSTEM)
341 		return;
342 
343 	SDT_PROBE(racct, kernel, rusage, add_force, p, resource, amount, 0, 0);
344 
345 	/*
346 	 * We need proc lock to dereference p->p_ucred.
347 	 */
348 	PROC_LOCK_ASSERT(p, MA_OWNED);
349 
350 	mtx_lock(&racct_lock);
351 	racct_alloc_resource(p->p_racct, resource, amount);
352 	mtx_unlock(&racct_lock);
353 	racct_add_cred(p->p_ucred, resource, amount);
354 }
355 
356 static int
357 racct_set_locked(struct proc *p, int resource, uint64_t amount)
358 {
359 	int64_t diff;
360 #ifdef RCTL
361 	int error;
362 #endif
363 
364 	if (p->p_flag & P_SYSTEM)
365 		return (0);
366 
367 	SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
368 
369 	/*
370 	 * We need proc lock to dereference p->p_ucred.
371 	 */
372 	PROC_LOCK_ASSERT(p, MA_OWNED);
373 
374 	diff = amount - p->p_racct->r_resources[resource];
375 #ifdef notyet
376 	KASSERT(diff >= 0 || racct_is_reclaimable(resource),
377 	    ("racct_set: usage of non-reclaimable resource %d dropping",
378 	     resource));
379 #endif
380 #ifdef RCTL
381 	if (diff > 0) {
382 		error = rctl_enforce(p, resource, diff);
383 		if (error && racct_is_deniable(resource)) {
384 			SDT_PROBE(racct, kernel, rusage, set_failure, p,
385 			    resource, amount, 0, 0);
386 			return (error);
387 		}
388 	}
389 #endif
390 	racct_alloc_resource(p->p_racct, resource, diff);
391 	if (diff > 0)
392 		racct_add_cred_locked(p->p_ucred, resource, diff);
393 	else if (diff < 0)
394 		racct_sub_cred_locked(p->p_ucred, resource, -diff);
395 
396 	return (0);
397 }
398 
399 /*
400  * Set allocation of 'resource' to 'amount' for process 'p'.
401  * Return 0 if it's below limits, or errno, if it's not.
402  *
403  * Note that decreasing the allocation always returns 0,
404  * even if it's above the limit.
405  */
406 int
407 racct_set(struct proc *p, int resource, uint64_t amount)
408 {
409 	int error;
410 
411 	mtx_lock(&racct_lock);
412 	error = racct_set_locked(p, resource, amount);
413 	mtx_unlock(&racct_lock);
414 	return (error);
415 }
416 
417 void
418 racct_set_force(struct proc *p, int resource, uint64_t amount)
419 {
420 	int64_t diff;
421 
422 	if (p->p_flag & P_SYSTEM)
423 		return;
424 
425 	SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
426 
427 	/*
428 	 * We need proc lock to dereference p->p_ucred.
429 	 */
430 	PROC_LOCK_ASSERT(p, MA_OWNED);
431 
432 	mtx_lock(&racct_lock);
433 	diff = amount - p->p_racct->r_resources[resource];
434 	racct_alloc_resource(p->p_racct, resource, diff);
435 	if (diff > 0)
436 		racct_add_cred_locked(p->p_ucred, resource, diff);
437 	else if (diff < 0)
438 		racct_sub_cred_locked(p->p_ucred, resource, -diff);
439 	mtx_unlock(&racct_lock);
440 }
441 
442 /*
443  * Returns amount of 'resource' the process 'p' can keep allocated.
444  * Allocating more than that would be denied, unless the resource
445  * is marked undeniable.  Amount of already allocated resource does
446  * not matter.
447  */
448 uint64_t
449 racct_get_limit(struct proc *p, int resource)
450 {
451 
452 #ifdef RCTL
453 	return (rctl_get_limit(p, resource));
454 #else
455 	return (UINT64_MAX);
456 #endif
457 }
458 
459 /*
460  * Returns amount of 'resource' the process 'p' can keep allocated.
461  * Allocating more than that would be denied, unless the resource
462  * is marked undeniable.  Amount of already allocated resource does
463  * matter.
464  */
465 uint64_t
466 racct_get_available(struct proc *p, int resource)
467 {
468 
469 #ifdef RCTL
470 	return (rctl_get_available(p, resource));
471 #else
472 	return (UINT64_MAX);
473 #endif
474 }
475 
476 /*
477  * Decrease allocation of 'resource' by 'amount' for process 'p'.
478  */
479 void
480 racct_sub(struct proc *p, int resource, uint64_t amount)
481 {
482 
483 	if (p->p_flag & P_SYSTEM)
484 		return;
485 
486 	SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0);
487 
488 	/*
489 	 * We need proc lock to dereference p->p_ucred.
490 	 */
491 	PROC_LOCK_ASSERT(p, MA_OWNED);
492 	KASSERT(racct_is_reclaimable(resource),
493 	    ("racct_sub: called for non-reclaimable resource %d", resource));
494 
495 	mtx_lock(&racct_lock);
496 	KASSERT(amount <= p->p_racct->r_resources[resource],
497 	    ("racct_sub: freeing %ju of resource %d, which is more "
498 	     "than allocated %jd for %s (pid %d)", amount, resource,
499 	    (intmax_t)p->p_racct->r_resources[resource], p->p_comm, p->p_pid));
500 
501 	racct_alloc_resource(p->p_racct, resource, -amount);
502 	racct_sub_cred_locked(p->p_ucred, resource, amount);
503 	mtx_unlock(&racct_lock);
504 }
505 
506 static void
507 racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount)
508 {
509 	struct prison *pr;
510 
511 	SDT_PROBE(racct, kernel, rusage, sub_cred, cred, resource, amount,
512 	    0, 0);
513 
514 #ifdef notyet
515 	KASSERT(racct_is_reclaimable(resource),
516 	    ("racct_sub_cred: called for non-reclaimable resource %d",
517 	     resource));
518 #endif
519 
520 	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
521 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
522 		racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
523 		    -amount);
524 	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount);
525 }
526 
527 /*
528  * Decrease allocation of 'resource' by 'amount' for credential 'cred'.
529  */
530 void
531 racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
532 {
533 
534 	mtx_lock(&racct_lock);
535 	racct_sub_cred_locked(cred, resource, amount);
536 	mtx_unlock(&racct_lock);
537 }
538 
539 /*
540  * Inherit resource usage information from the parent process.
541  */
542 int
543 racct_proc_fork(struct proc *parent, struct proc *child)
544 {
545 	int i, error = 0;
546 
547 	/*
548 	 * Create racct for the child process.
549 	 */
550 	racct_create(&child->p_racct);
551 
552 	/*
553 	 * No resource accounting for kernel processes.
554 	 */
555 	if (child->p_flag & P_SYSTEM)
556 		return (0);
557 
558 	PROC_LOCK(parent);
559 	PROC_LOCK(child);
560 	mtx_lock(&racct_lock);
561 
562 	/*
563 	 * Inherit resource usage.
564 	 */
565 	for (i = 0; i <= RACCT_MAX; i++) {
566 		if (parent->p_racct->r_resources[i] == 0 ||
567 		    !racct_is_inheritable(i))
568 			continue;
569 
570 		error = racct_set_locked(child, i,
571 		    parent->p_racct->r_resources[i]);
572 		if (error != 0) {
573 			/*
574 			 * XXX: The only purpose of these two lines is
575 			 * to prevent from tripping checks in racct_destroy().
576 			 */
577 			for (i = 0; i <= RACCT_MAX; i++)
578 				racct_set_locked(child, i, 0);
579 			goto out;
580 		}
581 	}
582 
583 #ifdef RCTL
584 	error = rctl_proc_fork(parent, child);
585 	if (error != 0) {
586 		/*
587 		 * XXX: The only purpose of these two lines is to prevent from
588 		 * tripping checks in racct_destroy().
589 		 */
590 		for (i = 0; i <= RACCT_MAX; i++)
591 			racct_set_locked(child, i, 0);
592 	}
593 #endif
594 
595 out:
596 	if (error != 0)
597 		racct_destroy_locked(&child->p_racct);
598 	mtx_unlock(&racct_lock);
599 	PROC_UNLOCK(child);
600 	PROC_UNLOCK(parent);
601 
602 	return (error);
603 }
604 
605 void
606 racct_proc_exit(struct proc *p)
607 {
608 	uint64_t runtime;
609 
610 	PROC_LOCK(p);
611 	/*
612 	 * We don't need to calculate rux, proc_reap() has already done this.
613 	 */
614 	runtime = cputick2usec(p->p_rux.rux_runtime);
615 #ifdef notyet
616 	KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime"));
617 #else
618 	if (runtime < p->p_prev_runtime)
619 		runtime = p->p_prev_runtime;
620 #endif
621 	racct_set(p, RACCT_CPU, runtime);
622 
623 	/*
624 	 * XXX: Free this some other way.
625 	 */
626 	racct_set(p, RACCT_NPTS, 0);
627 	racct_set(p, RACCT_NTHR, 0);
628 	racct_set(p, RACCT_RSS, 0);
629 	PROC_UNLOCK(p);
630 
631 #ifdef RCTL
632 	rctl_racct_release(p->p_racct);
633 #endif
634 	racct_destroy(&p->p_racct);
635 }
636 
637 /*
638  * Called after credentials change, to move resource utilisation
639  * between raccts.
640  */
641 void
642 racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
643     struct ucred *newcred)
644 {
645 	struct uidinfo *olduip, *newuip;
646 	struct loginclass *oldlc, *newlc;
647 	struct prison *oldpr, *newpr, *pr;
648 
649 	PROC_LOCK_ASSERT(p, MA_NOTOWNED);
650 
651 	newuip = newcred->cr_ruidinfo;
652 	olduip = oldcred->cr_ruidinfo;
653 	newlc = newcred->cr_loginclass;
654 	oldlc = oldcred->cr_loginclass;
655 	newpr = newcred->cr_prison;
656 	oldpr = oldcred->cr_prison;
657 
658 	mtx_lock(&racct_lock);
659 	if (newuip != olduip) {
660 		racct_sub_racct(olduip->ui_racct, p->p_racct);
661 		racct_add_racct(newuip->ui_racct, p->p_racct);
662 	}
663 	if (newlc != oldlc) {
664 		racct_sub_racct(oldlc->lc_racct, p->p_racct);
665 		racct_add_racct(newlc->lc_racct, p->p_racct);
666 	}
667 	if (newpr != oldpr) {
668 		for (pr = oldpr; pr != NULL; pr = pr->pr_parent)
669 			racct_sub_racct(pr->pr_prison_racct->prr_racct,
670 			    p->p_racct);
671 		for (pr = newpr; pr != NULL; pr = pr->pr_parent)
672 			racct_add_racct(pr->pr_prison_racct->prr_racct,
673 			    p->p_racct);
674 	}
675 	mtx_unlock(&racct_lock);
676 
677 #ifdef RCTL
678 	rctl_proc_ucred_changed(p, newcred);
679 #endif
680 }
681 
682 static void
683 racctd(void)
684 {
685 	struct thread *td;
686 	struct proc *p;
687 	struct timeval wallclock;
688 	uint64_t runtime;
689 
690 	for (;;) {
691 		sx_slock(&allproc_lock);
692 
693 		FOREACH_PROC_IN_SYSTEM(p) {
694 			if (p->p_state != PRS_NORMAL)
695 				continue;
696 			if (p->p_flag & P_SYSTEM)
697 				continue;
698 
699 			microuptime(&wallclock);
700 			timevalsub(&wallclock, &p->p_stats->p_start);
701 			PROC_LOCK(p);
702 			PROC_SLOCK(p);
703 			FOREACH_THREAD_IN_PROC(p, td) {
704 				ruxagg(p, td);
705 				thread_lock(td);
706 				thread_unlock(td);
707 			}
708 			runtime = cputick2usec(p->p_rux.rux_runtime);
709 			PROC_SUNLOCK(p);
710 #ifdef notyet
711 			KASSERT(runtime >= p->p_prev_runtime,
712 			    ("runtime < p_prev_runtime"));
713 #else
714 			if (runtime < p->p_prev_runtime)
715 				runtime = p->p_prev_runtime;
716 #endif
717 			p->p_prev_runtime = runtime;
718 			mtx_lock(&racct_lock);
719 			racct_set_locked(p, RACCT_CPU, runtime);
720 			racct_set_locked(p, RACCT_WALLCLOCK,
721 			    wallclock.tv_sec * 1000000 + wallclock.tv_usec);
722 			mtx_unlock(&racct_lock);
723 			PROC_UNLOCK(p);
724 		}
725 		sx_sunlock(&allproc_lock);
726 		pause("-", hz);
727 	}
728 }
729 
730 static struct kproc_desc racctd_kp = {
731 	"racctd",
732 	racctd,
733 	NULL
734 };
735 SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, kproc_start, &racctd_kp);
736 
737 static void
738 racct_init(void)
739 {
740 
741 	racct_zone = uma_zcreate("racct", sizeof(struct racct),
742 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
743 	/*
744 	 * XXX: Move this somewhere.
745 	 */
746 	prison0.pr_prison_racct = prison_racct_find("0");
747 }
748 SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL);
749 
750 #else /* !RACCT */
751 
752 int
753 racct_add(struct proc *p, int resource, uint64_t amount)
754 {
755 
756 	return (0);
757 }
758 
759 void
760 racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
761 {
762 }
763 
764 void
765 racct_add_force(struct proc *p, int resource, uint64_t amount)
766 {
767 
768 	return;
769 }
770 
771 int
772 racct_set(struct proc *p, int resource, uint64_t amount)
773 {
774 
775 	return (0);
776 }
777 
778 void
779 racct_set_force(struct proc *p, int resource, uint64_t amount)
780 {
781 }
782 
783 void
784 racct_sub(struct proc *p, int resource, uint64_t amount)
785 {
786 }
787 
788 void
789 racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
790 {
791 }
792 
793 uint64_t
794 racct_get_limit(struct proc *p, int resource)
795 {
796 
797 	return (UINT64_MAX);
798 }
799 
800 uint64_t
801 racct_get_available(struct proc *p, int resource)
802 {
803 
804 	return (UINT64_MAX);
805 }
806 
807 void
808 racct_create(struct racct **racctp)
809 {
810 }
811 
812 void
813 racct_destroy(struct racct **racctp)
814 {
815 }
816 
817 int
818 racct_proc_fork(struct proc *parent, struct proc *child)
819 {
820 
821 	return (0);
822 }
823 
824 void
825 racct_proc_exit(struct proc *p)
826 {
827 }
828 
829 #endif /* !RACCT */
830