xref: /freebsd/sys/kern/kern_racct.c (revision d51f8d20247c373ab2c2db8aed596b8ac44e7a34)
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_FSIZE] =
108 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
109 	[RACCT_DATA] =
110 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
111 	[RACCT_STACK] =
112 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
113 	[RACCT_CORE] =
114 		RACCT_DENIABLE,
115 	[RACCT_RSS] =
116 		RACCT_RECLAIMABLE,
117 	[RACCT_MEMLOCK] =
118 		RACCT_RECLAIMABLE | RACCT_DENIABLE,
119 	[RACCT_NPROC] =
120 		RACCT_RECLAIMABLE | RACCT_DENIABLE,
121 	[RACCT_NOFILE] =
122 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
123 	[RACCT_SBSIZE] =
124 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
125 	[RACCT_VMEM] =
126 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
127 	[RACCT_NPTS] =
128 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
129 	[RACCT_SWAP] =
130 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
131 	[RACCT_NTHR] =
132 		RACCT_RECLAIMABLE | RACCT_DENIABLE,
133 	[RACCT_MSGQQUEUED] =
134 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
135 	[RACCT_MSGQSIZE] =
136 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
137 	[RACCT_NMSGQ] =
138 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
139 	[RACCT_NSEM] =
140 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
141 	[RACCT_NSEMOP] =
142 		RACCT_RECLAIMABLE | RACCT_INHERITABLE | RACCT_DENIABLE,
143 	[RACCT_NSHM] =
144 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
145 	[RACCT_SHMSIZE] =
146 		RACCT_RECLAIMABLE | RACCT_DENIABLE | RACCT_SLOPPY,
147 	[RACCT_WALLCLOCK] =
148 		RACCT_IN_THOUSANDS };
149 
150 static void
151 racct_add_racct(struct racct *dest, const struct racct *src)
152 {
153 	int i;
154 
155 	mtx_assert(&racct_lock, MA_OWNED);
156 
157 	/*
158 	 * Update resource usage in dest.
159 	 */
160 	for (i = 0; i <= RACCT_MAX; i++) {
161 		KASSERT(dest->r_resources[i] >= 0,
162 		    ("racct propagation meltdown: dest < 0"));
163 		KASSERT(src->r_resources[i] >= 0,
164 		    ("racct propagation meltdown: src < 0"));
165 		dest->r_resources[i] += src->r_resources[i];
166 	}
167 }
168 
169 static void
170 racct_sub_racct(struct racct *dest, const struct racct *src)
171 {
172 	int i;
173 
174 	mtx_assert(&racct_lock, MA_OWNED);
175 
176 	/*
177 	 * Update resource usage in dest.
178 	 */
179 	for (i = 0; i <= RACCT_MAX; i++) {
180 		if (!racct_is_sloppy(i)) {
181 			KASSERT(dest->r_resources[i] >= 0,
182 			    ("racct propagation meltdown: dest < 0"));
183 			KASSERT(src->r_resources[i] >= 0,
184 			    ("racct propagation meltdown: src < 0"));
185 			KASSERT(src->r_resources[i] <= dest->r_resources[i],
186 			    ("racct propagation meltdown: src > dest"));
187 		}
188 		if (racct_is_reclaimable(i)) {
189 			dest->r_resources[i] -= src->r_resources[i];
190 			if (dest->r_resources[i] < 0) {
191 				KASSERT(racct_is_sloppy(i),
192 				    ("racct_sub_racct: usage < 0"));
193 				dest->r_resources[i] = 0;
194 			}
195 		}
196 	}
197 }
198 
199 void
200 racct_create(struct racct **racctp)
201 {
202 
203 	SDT_PROBE(racct, kernel, racct, create, racctp, 0, 0, 0, 0);
204 
205 	KASSERT(*racctp == NULL, ("racct already allocated"));
206 
207 	*racctp = uma_zalloc(racct_zone, M_WAITOK | M_ZERO);
208 }
209 
210 static void
211 racct_destroy_locked(struct racct **racctp)
212 {
213 	int i;
214 	struct racct *racct;
215 
216 	SDT_PROBE(racct, kernel, racct, destroy, racctp, 0, 0, 0, 0);
217 
218 	mtx_assert(&racct_lock, MA_OWNED);
219 	KASSERT(racctp != NULL, ("NULL racctp"));
220 	KASSERT(*racctp != NULL, ("NULL racct"));
221 
222 	racct = *racctp;
223 
224 	for (i = 0; i <= RACCT_MAX; i++) {
225 		if (racct_is_sloppy(i))
226 			continue;
227 		if (!racct_is_reclaimable(i))
228 			continue;
229 		KASSERT(racct->r_resources[i] == 0,
230 		    ("destroying non-empty racct: "
231 		    "%ju allocated for resource %d\n",
232 		    racct->r_resources[i], i));
233 	}
234 	uma_zfree(racct_zone, racct);
235 	*racctp = NULL;
236 }
237 
238 void
239 racct_destroy(struct racct **racct)
240 {
241 
242 	mtx_lock(&racct_lock);
243 	racct_destroy_locked(racct);
244 	mtx_unlock(&racct_lock);
245 }
246 
247 /*
248  * Increase consumption of 'resource' by 'amount' for 'racct'
249  * and all its parents.  Differently from other cases, 'amount' here
250  * may be less than zero.
251  */
252 static void
253 racct_alloc_resource(struct racct *racct, int resource,
254     uint64_t amount)
255 {
256 
257 	mtx_assert(&racct_lock, MA_OWNED);
258 	KASSERT(racct != NULL, ("NULL racct"));
259 
260 	racct->r_resources[resource] += amount;
261 	if (racct->r_resources[resource] < 0) {
262 		KASSERT(racct_is_sloppy(resource),
263 		    ("racct_alloc_resource: usage < 0"));
264 		racct->r_resources[resource] = 0;
265 	}
266 }
267 
268 /*
269  * Increase allocation of 'resource' by 'amount' for process 'p'.
270  * Return 0 if it's below limits, or errno, if it's not.
271  */
272 int
273 racct_add(struct proc *p, int resource, uint64_t amount)
274 {
275 #ifdef RCTL
276 	int error;
277 #endif
278 
279 	if (p->p_flag & P_SYSTEM)
280 		return (0);
281 
282 	SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0);
283 
284 	/*
285 	 * We need proc lock to dereference p->p_ucred.
286 	 */
287 	PROC_LOCK_ASSERT(p, MA_OWNED);
288 
289 	mtx_lock(&racct_lock);
290 #ifdef RCTL
291 	error = rctl_enforce(p, resource, amount);
292 	if (error && racct_is_deniable(resource)) {
293 		SDT_PROBE(racct, kernel, rusage, add_failure, p, resource,
294 		    amount, 0, 0);
295 		mtx_unlock(&racct_lock);
296 		return (error);
297 	}
298 #endif
299 	racct_alloc_resource(p->p_racct, resource, amount);
300 	racct_add_cred_locked(p->p_ucred, resource, amount);
301 	mtx_unlock(&racct_lock);
302 
303 	return (0);
304 }
305 
306 static void
307 racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount)
308 {
309 	struct prison *pr;
310 
311 	SDT_PROBE(racct, kernel, rusage, add_cred, cred, resource, amount,
312 	    0, 0);
313 
314 	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
315 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
316 		racct_alloc_resource(pr->pr_racct, resource, amount);
317 	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount);
318 }
319 
320 /*
321  * Increase allocation of 'resource' by 'amount' for credential 'cred'.
322  * Doesn't check for limits and never fails.
323  *
324  * XXX: Shouldn't this ever return an error?
325  */
326 void
327 racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
328 {
329 
330 	mtx_lock(&racct_lock);
331 	racct_add_cred_locked(cred, resource, amount);
332 	mtx_unlock(&racct_lock);
333 }
334 
335 /*
336  * Increase allocation of 'resource' by 'amount' for process 'p'.
337  * Doesn't check for limits and never fails.
338  */
339 void
340 racct_add_force(struct proc *p, int resource, uint64_t amount)
341 {
342 
343 	if (p->p_flag & P_SYSTEM)
344 		return;
345 
346 	SDT_PROBE(racct, kernel, rusage, add_force, p, resource, amount, 0, 0);
347 
348 	/*
349 	 * We need proc lock to dereference p->p_ucred.
350 	 */
351 	PROC_LOCK_ASSERT(p, MA_OWNED);
352 
353 	mtx_lock(&racct_lock);
354 	racct_alloc_resource(p->p_racct, resource, amount);
355 	mtx_unlock(&racct_lock);
356 	racct_add_cred(p->p_ucred, resource, amount);
357 }
358 
359 static int
360 racct_set_locked(struct proc *p, int resource, uint64_t amount)
361 {
362 	int64_t diff;
363 #ifdef RCTL
364 	int error;
365 #endif
366 
367 	if (p->p_flag & P_SYSTEM)
368 		return (0);
369 
370 	SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
371 
372 	/*
373 	 * We need proc lock to dereference p->p_ucred.
374 	 */
375 	PROC_LOCK_ASSERT(p, MA_OWNED);
376 
377 	diff = amount - p->p_racct->r_resources[resource];
378 #ifdef notyet
379 	KASSERT(diff >= 0 || racct_is_reclaimable(resource),
380 	    ("racct_set: usage of non-reclaimable resource %d dropping",
381 	     resource));
382 #endif
383 #ifdef RCTL
384 	if (diff > 0) {
385 		error = rctl_enforce(p, resource, diff);
386 		if (error && racct_is_deniable(resource)) {
387 			SDT_PROBE(racct, kernel, rusage, set_failure, p,
388 			    resource, amount, 0, 0);
389 			return (error);
390 		}
391 	}
392 #endif
393 	racct_alloc_resource(p->p_racct, resource, diff);
394 	if (diff > 0)
395 		racct_add_cred_locked(p->p_ucred, resource, diff);
396 	else if (diff < 0)
397 		racct_sub_cred_locked(p->p_ucred, resource, -diff);
398 
399 	return (0);
400 }
401 
402 /*
403  * Set allocation of 'resource' to 'amount' for process 'p'.
404  * Return 0 if it's below limits, or errno, if it's not.
405  *
406  * Note that decreasing the allocation always returns 0,
407  * even if it's above the limit.
408  */
409 int
410 racct_set(struct proc *p, int resource, uint64_t amount)
411 {
412 	int error;
413 
414 	mtx_lock(&racct_lock);
415 	error = racct_set_locked(p, resource, amount);
416 	mtx_unlock(&racct_lock);
417 	return (error);
418 }
419 
420 void
421 racct_set_force(struct proc *p, int resource, uint64_t amount)
422 {
423 	int64_t diff;
424 
425 	if (p->p_flag & P_SYSTEM)
426 		return;
427 
428 	SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
429 
430 	/*
431 	 * We need proc lock to dereference p->p_ucred.
432 	 */
433 	PROC_LOCK_ASSERT(p, MA_OWNED);
434 
435 	mtx_lock(&racct_lock);
436 	diff = amount - p->p_racct->r_resources[resource];
437 	racct_alloc_resource(p->p_racct, resource, diff);
438 	if (diff > 0)
439 		racct_add_cred_locked(p->p_ucred, resource, diff);
440 	else if (diff < 0)
441 		racct_sub_cred_locked(p->p_ucred, resource, -diff);
442 	mtx_unlock(&racct_lock);
443 }
444 
445 /*
446  * Returns amount of 'resource' the process 'p' can keep allocated.
447  * Allocating more than that would be denied, unless the resource
448  * is marked undeniable.  Amount of already allocated resource does
449  * not matter.
450  */
451 uint64_t
452 racct_get_limit(struct proc *p, int resource)
453 {
454 
455 #ifdef RCTL
456 	return (rctl_get_limit(p, resource));
457 #else
458 	return (UINT64_MAX);
459 #endif
460 }
461 
462 /*
463  * Returns amount of 'resource' the process 'p' can keep allocated.
464  * Allocating more than that would be denied, unless the resource
465  * is marked undeniable.  Amount of already allocated resource does
466  * matter.
467  */
468 uint64_t
469 racct_get_available(struct proc *p, int resource)
470 {
471 
472 #ifdef RCTL
473 	return (rctl_get_available(p, resource));
474 #else
475 	return (UINT64_MAX);
476 #endif
477 }
478 
479 /*
480  * Decrease allocation of 'resource' by 'amount' for process 'p'.
481  */
482 void
483 racct_sub(struct proc *p, int resource, uint64_t amount)
484 {
485 
486 	if (p->p_flag & P_SYSTEM)
487 		return;
488 
489 	SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0);
490 
491 	/*
492 	 * We need proc lock to dereference p->p_ucred.
493 	 */
494 	PROC_LOCK_ASSERT(p, MA_OWNED);
495 	KASSERT(racct_is_reclaimable(resource),
496 	    ("racct_sub: called for non-reclaimable resource %d", resource));
497 
498 	mtx_lock(&racct_lock);
499 	KASSERT(amount <= p->p_racct->r_resources[resource],
500 	    ("racct_sub: freeing %ju of resource %d, which is more "
501 	     "than allocated %jd for %s (pid %d)", amount, resource,
502 	    (intmax_t)p->p_racct->r_resources[resource], p->p_comm, p->p_pid));
503 
504 	racct_alloc_resource(p->p_racct, resource, -amount);
505 	racct_sub_cred_locked(p->p_ucred, resource, amount);
506 	mtx_unlock(&racct_lock);
507 }
508 
509 static void
510 racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount)
511 {
512 	struct prison *pr;
513 
514 	SDT_PROBE(racct, kernel, rusage, sub_cred, cred, resource, amount,
515 	    0, 0);
516 
517 #ifdef notyet
518 	KASSERT(racct_is_reclaimable(resource),
519 	    ("racct_sub_cred: called for non-reclaimable resource %d",
520 	     resource));
521 #endif
522 
523 	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
524 	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
525 		racct_alloc_resource(pr->pr_racct, resource, -amount);
526 	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount);
527 }
528 
529 /*
530  * Decrease allocation of 'resource' by 'amount' for credential 'cred'.
531  */
532 void
533 racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
534 {
535 
536 	mtx_lock(&racct_lock);
537 	racct_sub_cred_locked(cred, resource, amount);
538 	mtx_unlock(&racct_lock);
539 }
540 
541 /*
542  * Inherit resource usage information from the parent process.
543  */
544 int
545 racct_proc_fork(struct proc *parent, struct proc *child)
546 {
547 	int i, error = 0;
548 
549 	/*
550 	 * Create racct for the child process.
551 	 */
552 	racct_create(&child->p_racct);
553 
554 	/*
555 	 * No resource accounting for kernel processes.
556 	 */
557 	if (child->p_flag & P_SYSTEM)
558 		return (0);
559 
560 	PROC_LOCK(parent);
561 	PROC_LOCK(child);
562 	mtx_lock(&racct_lock);
563 
564 	/*
565 	 * Inherit resource usage.
566 	 */
567 	for (i = 0; i <= RACCT_MAX; i++) {
568 		if (parent->p_racct->r_resources[i] == 0 ||
569 		    !racct_is_inheritable(i))
570 			continue;
571 
572 		error = racct_set_locked(child, i,
573 		    parent->p_racct->r_resources[i]);
574 		if (error != 0) {
575 			/*
576 			 * XXX: The only purpose of these two lines is
577 			 * to prevent from tripping checks in racct_destroy().
578 			 */
579 			for (i = 0; i <= RACCT_MAX; i++)
580 				racct_set_locked(child, i, 0);
581 			goto out;
582 		}
583 	}
584 
585 #ifdef RCTL
586 	error = rctl_proc_fork(parent, child);
587 	if (error != 0) {
588 		/*
589 		 * XXX: The only purpose of these two lines is to prevent from
590 		 * tripping checks in racct_destroy().
591 		 */
592 		for (i = 0; i <= RACCT_MAX; i++)
593 			racct_set_locked(child, i, 0);
594 	}
595 #endif
596 
597 out:
598 	if (error != 0)
599 		racct_destroy_locked(&child->p_racct);
600 	mtx_unlock(&racct_lock);
601 	PROC_UNLOCK(child);
602 	PROC_UNLOCK(parent);
603 
604 	return (error);
605 }
606 
607 void
608 racct_proc_exit(struct proc *p)
609 {
610 	uint64_t runtime;
611 
612 	PROC_LOCK(p);
613 	/*
614 	 * We don't need to calculate rux, proc_reap() has already done this.
615 	 */
616 	runtime = cputick2usec(p->p_rux.rux_runtime);
617 #ifdef notyet
618 	KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime"));
619 #else
620 	if (runtime < p->p_prev_runtime)
621 		runtime = p->p_prev_runtime;
622 #endif
623 	racct_set(p, RACCT_CPU, runtime);
624 
625 	/*
626 	 * XXX: Free this some other way.
627 	 */
628 	racct_set(p, RACCT_FSIZE, 0);
629 	racct_set(p, RACCT_NPTS, 0);
630 	racct_set(p, RACCT_NTHR, 0);
631 	racct_set(p, RACCT_RSS, 0);
632 	PROC_UNLOCK(p);
633 
634 #ifdef RCTL
635 	rctl_racct_release(p->p_racct);
636 #endif
637 	racct_destroy(&p->p_racct);
638 }
639 
640 /*
641  * Called after credentials change, to move resource utilisation
642  * between raccts.
643  */
644 void
645 racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
646     struct ucred *newcred)
647 {
648 	struct uidinfo *olduip, *newuip;
649 	struct loginclass *oldlc, *newlc;
650 	struct prison *oldpr, *newpr, *pr;
651 
652 	PROC_LOCK_ASSERT(p, MA_NOTOWNED);
653 
654 	newuip = newcred->cr_ruidinfo;
655 	olduip = oldcred->cr_ruidinfo;
656 	newlc = newcred->cr_loginclass;
657 	oldlc = oldcred->cr_loginclass;
658 	newpr = newcred->cr_prison;
659 	oldpr = oldcred->cr_prison;
660 
661 	mtx_lock(&racct_lock);
662 	if (newuip != olduip) {
663 		racct_sub_racct(olduip->ui_racct, p->p_racct);
664 		racct_add_racct(newuip->ui_racct, p->p_racct);
665 	}
666 	if (newlc != oldlc) {
667 		racct_sub_racct(oldlc->lc_racct, p->p_racct);
668 		racct_add_racct(newlc->lc_racct, p->p_racct);
669 	}
670 	if (newpr != oldpr) {
671 		for (pr = oldpr; pr != NULL; pr = pr->pr_parent)
672 			racct_sub_racct(pr->pr_racct, p->p_racct);
673 		for (pr = newpr; pr != NULL; pr = pr->pr_parent)
674 			racct_add_racct(pr->pr_racct, p->p_racct);
675 	}
676 	mtx_unlock(&racct_lock);
677 
678 #ifdef RCTL
679 	rctl_proc_ucred_changed(p, newcred);
680 #endif
681 }
682 
683 static void
684 racctd(void)
685 {
686 	struct thread *td;
687 	struct proc *p;
688 	struct timeval wallclock;
689 	uint64_t runtime;
690 
691 	for (;;) {
692 		sx_slock(&allproc_lock);
693 
694 		FOREACH_PROC_IN_SYSTEM(p) {
695 			if (p->p_state != PRS_NORMAL)
696 				continue;
697 			if (p->p_flag & P_SYSTEM)
698 				continue;
699 
700 			microuptime(&wallclock);
701 			timevalsub(&wallclock, &p->p_stats->p_start);
702 			PROC_LOCK(p);
703 			PROC_SLOCK(p);
704 			FOREACH_THREAD_IN_PROC(p, td) {
705 				ruxagg(p, td);
706 				thread_lock(td);
707 				thread_unlock(td);
708 			}
709 			runtime = cputick2usec(p->p_rux.rux_runtime);
710 			PROC_SUNLOCK(p);
711 #ifdef notyet
712 			KASSERT(runtime >= p->p_prev_runtime,
713 			    ("runtime < p_prev_runtime"));
714 #else
715 			if (runtime < p->p_prev_runtime)
716 				runtime = p->p_prev_runtime;
717 #endif
718 			p->p_prev_runtime = runtime;
719 			mtx_lock(&racct_lock);
720 			racct_set_locked(p, RACCT_CPU, runtime);
721 			racct_set_locked(p, RACCT_WALLCLOCK,
722 			    wallclock.tv_sec * 1000000 + wallclock.tv_usec);
723 			mtx_unlock(&racct_lock);
724 			PROC_UNLOCK(p);
725 		}
726 		sx_sunlock(&allproc_lock);
727 		pause("-", hz);
728 	}
729 }
730 
731 static struct kproc_desc racctd_kp = {
732 	"racctd",
733 	racctd,
734 	NULL
735 };
736 SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, kproc_start, &racctd_kp);
737 
738 static void
739 racct_init(void)
740 {
741 
742 	racct_zone = uma_zcreate("racct", sizeof(struct racct),
743 	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
744 	/*
745 	 * XXX: Move this somewhere.
746 	 */
747 	racct_create(&prison0.pr_racct);
748 }
749 SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL);
750 
751 #else /* !RACCT */
752 
753 int
754 racct_add(struct proc *p, int resource, uint64_t amount)
755 {
756 
757 	return (0);
758 }
759 
760 void
761 racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
762 {
763 }
764 
765 void
766 racct_add_force(struct proc *p, int resource, uint64_t amount)
767 {
768 
769 	return;
770 }
771 
772 int
773 racct_set(struct proc *p, int resource, uint64_t amount)
774 {
775 
776 	return (0);
777 }
778 
779 void
780 racct_set_force(struct proc *p, int resource, uint64_t amount)
781 {
782 }
783 
784 void
785 racct_sub(struct proc *p, int resource, uint64_t amount)
786 {
787 }
788 
789 void
790 racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
791 {
792 }
793 
794 uint64_t
795 racct_get_limit(struct proc *p, int resource)
796 {
797 
798 	return (UINT64_MAX);
799 }
800 
801 uint64_t
802 racct_get_available(struct proc *p, int resource)
803 {
804 
805 	return (UINT64_MAX);
806 }
807 
808 void
809 racct_create(struct racct **racctp)
810 {
811 }
812 
813 void
814 racct_destroy(struct racct **racctp)
815 {
816 }
817 
818 int
819 racct_proc_fork(struct proc *parent, struct proc *child)
820 {
821 
822 	return (0);
823 }
824 
825 void
826 racct_proc_exit(struct proc *p)
827 {
828 }
829 
830 #endif /* !RACCT */
831