kern_racct.c revision 225944
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: head/sys/kern/kern_racct.c 225944 2011-10-03 17:40:55Z trasz $
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/kern/kern_racct.c 225944 2011-10-03 17:40:55Z trasz $");
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
65FEATURE(racct, "Resource Accounting");
66
67static struct mtx racct_lock;
68MTX_SYSINIT(racct_lock, &racct_lock, "racct lock", MTX_DEF);
69
70static uma_zone_t racct_zone;
71
72static void racct_sub_racct(struct racct *dest, const struct racct *src);
73static void racct_sub_cred_locked(struct ucred *cred, int resource,
74		uint64_t amount);
75static void racct_add_cred_locked(struct ucred *cred, int resource,
76		uint64_t amount);
77
78SDT_PROVIDER_DEFINE(racct);
79SDT_PROBE_DEFINE3(racct, kernel, rusage, add, add, "struct proc *", "int",
80    "uint64_t");
81SDT_PROBE_DEFINE3(racct, kernel, rusage, add_failure, add-failure,
82    "struct proc *", "int", "uint64_t");
83SDT_PROBE_DEFINE3(racct, kernel, rusage, add_cred, add-cred, "struct ucred *",
84    "int", "uint64_t");
85SDT_PROBE_DEFINE3(racct, kernel, rusage, add_force, add-force, "struct proc *",
86    "int", "uint64_t");
87SDT_PROBE_DEFINE3(racct, kernel, rusage, set, set, "struct proc *", "int",
88    "uint64_t");
89SDT_PROBE_DEFINE3(racct, kernel, rusage, set_failure, set-failure,
90    "struct proc *", "int", "uint64_t");
91SDT_PROBE_DEFINE3(racct, kernel, rusage, sub, sub, "struct proc *", "int",
92    "uint64_t");
93SDT_PROBE_DEFINE3(racct, kernel, rusage, sub_cred, sub-cred, "struct ucred *",
94    "int", "uint64_t");
95SDT_PROBE_DEFINE1(racct, kernel, racct, create, create, "struct racct *");
96SDT_PROBE_DEFINE1(racct, kernel, racct, destroy, destroy, "struct racct *");
97SDT_PROBE_DEFINE2(racct, kernel, racct, join, join, "struct racct *",
98    "struct racct *");
99SDT_PROBE_DEFINE2(racct, kernel, racct, join_failure, join-failure,
100    "struct racct *", "struct racct *");
101SDT_PROBE_DEFINE2(racct, kernel, racct, leave, leave, "struct racct *",
102    "struct racct *");
103
104int racct_types[] = {
105	[RACCT_CPU] =
106		RACCT_IN_MILLIONS,
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_MILLIONS };
145
146static void
147racct_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
165static void
166racct_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
195void
196racct_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
206static void
207racct_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
234void
235racct_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 */
248static void
249racct_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
264static int
265racct_add_locked(struct proc *p, int resource, uint64_t amount)
266{
267#ifdef RCTL
268	int error;
269#endif
270
271	if (p->p_flag & P_SYSTEM)
272		return (0);
273
274	SDT_PROBE(racct, kernel, rusage, add, p, resource, amount, 0, 0);
275
276	/*
277	 * We need proc lock to dereference p->p_ucred.
278	 */
279	PROC_LOCK_ASSERT(p, MA_OWNED);
280
281#ifdef RCTL
282	error = rctl_enforce(p, resource, amount);
283	if (error && RACCT_IS_DENIABLE(resource)) {
284		SDT_PROBE(racct, kernel, rusage, add_failure, p, resource,
285		    amount, 0, 0);
286		return (error);
287	}
288#endif
289	racct_alloc_resource(p->p_racct, resource, amount);
290	racct_add_cred_locked(p->p_ucred, resource, amount);
291
292	return (0);
293}
294
295/*
296 * Increase allocation of 'resource' by 'amount' for process 'p'.
297 * Return 0 if it's below limits, or errno, if it's not.
298 */
299int
300racct_add(struct proc *p, int resource, uint64_t amount)
301{
302	int error;
303
304	mtx_lock(&racct_lock);
305	error = racct_add_locked(p, resource, amount);
306	mtx_unlock(&racct_lock);
307	return (error);
308}
309
310static void
311racct_add_cred_locked(struct ucred *cred, int resource, uint64_t amount)
312{
313	struct prison *pr;
314
315	SDT_PROBE(racct, kernel, rusage, add_cred, cred, resource, amount,
316	    0, 0);
317
318	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, amount);
319	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
320		racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
321		    amount);
322	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, amount);
323}
324
325/*
326 * Increase allocation of 'resource' by 'amount' for credential 'cred'.
327 * Doesn't check for limits and never fails.
328 *
329 * XXX: Shouldn't this ever return an error?
330 */
331void
332racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
333{
334
335	mtx_lock(&racct_lock);
336	racct_add_cred_locked(cred, resource, amount);
337	mtx_unlock(&racct_lock);
338}
339
340/*
341 * Increase allocation of 'resource' by 'amount' for process 'p'.
342 * Doesn't check for limits and never fails.
343 */
344void
345racct_add_force(struct proc *p, int resource, uint64_t amount)
346{
347
348	if (p->p_flag & P_SYSTEM)
349		return;
350
351	SDT_PROBE(racct, kernel, rusage, add_force, p, resource, amount, 0, 0);
352
353	/*
354	 * We need proc lock to dereference p->p_ucred.
355	 */
356	PROC_LOCK_ASSERT(p, MA_OWNED);
357
358	mtx_lock(&racct_lock);
359	racct_alloc_resource(p->p_racct, resource, amount);
360	mtx_unlock(&racct_lock);
361	racct_add_cred(p->p_ucred, resource, amount);
362}
363
364static int
365racct_set_locked(struct proc *p, int resource, uint64_t amount)
366{
367	int64_t diff;
368#ifdef RCTL
369	int error;
370#endif
371
372	if (p->p_flag & P_SYSTEM)
373		return (0);
374
375	SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
376
377	/*
378	 * We need proc lock to dereference p->p_ucred.
379	 */
380	PROC_LOCK_ASSERT(p, MA_OWNED);
381
382	diff = amount - p->p_racct->r_resources[resource];
383#ifdef notyet
384	KASSERT(diff >= 0 || RACCT_IS_RECLAIMABLE(resource),
385	    ("racct_set: usage of non-reclaimable resource %d dropping",
386	     resource));
387#endif
388#ifdef RCTL
389	if (diff > 0) {
390		error = rctl_enforce(p, resource, diff);
391		if (error && RACCT_IS_DENIABLE(resource)) {
392			SDT_PROBE(racct, kernel, rusage, set_failure, p,
393			    resource, amount, 0, 0);
394			return (error);
395		}
396	}
397#endif
398	racct_alloc_resource(p->p_racct, resource, diff);
399	if (diff > 0)
400		racct_add_cred_locked(p->p_ucred, resource, diff);
401	else if (diff < 0)
402		racct_sub_cred_locked(p->p_ucred, resource, -diff);
403
404	return (0);
405}
406
407/*
408 * Set allocation of 'resource' to 'amount' for process 'p'.
409 * Return 0 if it's below limits, or errno, if it's not.
410 *
411 * Note that decreasing the allocation always returns 0,
412 * even if it's above the limit.
413 */
414int
415racct_set(struct proc *p, int resource, uint64_t amount)
416{
417	int error;
418
419	mtx_lock(&racct_lock);
420	error = racct_set_locked(p, resource, amount);
421	mtx_unlock(&racct_lock);
422	return (error);
423}
424
425void
426racct_set_force(struct proc *p, int resource, uint64_t amount)
427{
428	int64_t diff;
429
430	if (p->p_flag & P_SYSTEM)
431		return;
432
433	SDT_PROBE(racct, kernel, rusage, set, p, resource, amount, 0, 0);
434
435	/*
436	 * We need proc lock to dereference p->p_ucred.
437	 */
438	PROC_LOCK_ASSERT(p, MA_OWNED);
439
440	mtx_lock(&racct_lock);
441	diff = amount - p->p_racct->r_resources[resource];
442	racct_alloc_resource(p->p_racct, resource, diff);
443	if (diff > 0)
444		racct_add_cred_locked(p->p_ucred, resource, diff);
445	else if (diff < 0)
446		racct_sub_cred_locked(p->p_ucred, resource, -diff);
447	mtx_unlock(&racct_lock);
448}
449
450/*
451 * Returns amount of 'resource' the process 'p' can keep allocated.
452 * Allocating more than that would be denied, unless the resource
453 * is marked undeniable.  Amount of already allocated resource does
454 * not matter.
455 */
456uint64_t
457racct_get_limit(struct proc *p, int resource)
458{
459
460#ifdef RCTL
461	return (rctl_get_limit(p, resource));
462#else
463	return (UINT64_MAX);
464#endif
465}
466
467/*
468 * Returns amount of 'resource' the process 'p' can keep allocated.
469 * Allocating more than that would be denied, unless the resource
470 * is marked undeniable.  Amount of already allocated resource does
471 * matter.
472 */
473uint64_t
474racct_get_available(struct proc *p, int resource)
475{
476
477#ifdef RCTL
478	return (rctl_get_available(p, resource));
479#else
480	return (UINT64_MAX);
481#endif
482}
483
484/*
485 * Decrease allocation of 'resource' by 'amount' for process 'p'.
486 */
487void
488racct_sub(struct proc *p, int resource, uint64_t amount)
489{
490
491	if (p->p_flag & P_SYSTEM)
492		return;
493
494	SDT_PROBE(racct, kernel, rusage, sub, p, resource, amount, 0, 0);
495
496	/*
497	 * We need proc lock to dereference p->p_ucred.
498	 */
499	PROC_LOCK_ASSERT(p, MA_OWNED);
500	KASSERT(RACCT_IS_RECLAIMABLE(resource),
501	    ("racct_sub: called for non-reclaimable resource %d", resource));
502
503	mtx_lock(&racct_lock);
504	KASSERT(amount <= p->p_racct->r_resources[resource],
505	    ("racct_sub: freeing %ju of resource %d, which is more "
506	     "than allocated %jd for %s (pid %d)", amount, resource,
507	    (intmax_t)p->p_racct->r_resources[resource], p->p_comm, p->p_pid));
508
509	racct_alloc_resource(p->p_racct, resource, -amount);
510	racct_sub_cred_locked(p->p_ucred, resource, amount);
511	mtx_unlock(&racct_lock);
512}
513
514static void
515racct_sub_cred_locked(struct ucred *cred, int resource, uint64_t amount)
516{
517	struct prison *pr;
518
519	SDT_PROBE(racct, kernel, rusage, sub_cred, cred, resource, amount,
520	    0, 0);
521
522#ifdef notyet
523	KASSERT(RACCT_IS_RECLAIMABLE(resource),
524	    ("racct_sub_cred: called for non-reclaimable resource %d",
525	     resource));
526#endif
527
528	racct_alloc_resource(cred->cr_ruidinfo->ui_racct, resource, -amount);
529	for (pr = cred->cr_prison; pr != NULL; pr = pr->pr_parent)
530		racct_alloc_resource(pr->pr_prison_racct->prr_racct, resource,
531		    -amount);
532	racct_alloc_resource(cred->cr_loginclass->lc_racct, resource, -amount);
533}
534
535/*
536 * Decrease allocation of 'resource' by 'amount' for credential 'cred'.
537 */
538void
539racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
540{
541
542	mtx_lock(&racct_lock);
543	racct_sub_cred_locked(cred, resource, amount);
544	mtx_unlock(&racct_lock);
545}
546
547/*
548 * Inherit resource usage information from the parent process.
549 */
550int
551racct_proc_fork(struct proc *parent, struct proc *child)
552{
553	int i, error = 0;
554
555	/*
556	 * Create racct for the child process.
557	 */
558	racct_create(&child->p_racct);
559
560	/*
561	 * No resource accounting for kernel processes.
562	 */
563	if (child->p_flag & P_SYSTEM)
564		return (0);
565
566	PROC_LOCK(parent);
567	PROC_LOCK(child);
568	mtx_lock(&racct_lock);
569
570	/*
571	 * Inherit resource usage.
572	 */
573	for (i = 0; i <= RACCT_MAX; i++) {
574		if (parent->p_racct->r_resources[i] == 0 ||
575		    !RACCT_IS_INHERITABLE(i))
576			continue;
577
578		error = racct_set_locked(child, i,
579		    parent->p_racct->r_resources[i]);
580		if (error != 0)
581			goto out;
582	}
583
584#ifdef RCTL
585	error = rctl_proc_fork(parent, child);
586	if (error != 0)
587		goto out;
588#endif
589
590	error = racct_add_locked(child, RACCT_NPROC, 1);
591	error += racct_add_locked(child, RACCT_NTHR, 1);
592
593out:
594	mtx_unlock(&racct_lock);
595	PROC_UNLOCK(child);
596	PROC_UNLOCK(parent);
597
598	return (error);
599}
600
601/*
602 * Called at the end of fork1(), to handle rules that require the process
603 * to be fully initialized.
604 */
605void
606racct_proc_fork_done(struct proc *child)
607{
608
609#ifdef RCTL
610	PROC_LOCK(child);
611	mtx_lock(&racct_lock);
612	rctl_enforce(child, RACCT_NPROC, 0);
613	rctl_enforce(child, RACCT_NTHR, 0);
614	mtx_unlock(&racct_lock);
615	PROC_UNLOCK(child);
616#endif
617}
618
619void
620racct_proc_exit(struct proc *p)
621{
622	int i;
623	uint64_t runtime;
624
625	PROC_LOCK(p);
626	/*
627	 * We don't need to calculate rux, proc_reap() has already done this.
628	 */
629	runtime = cputick2usec(p->p_rux.rux_runtime);
630#ifdef notyet
631	KASSERT(runtime >= p->p_prev_runtime, ("runtime < p_prev_runtime"));
632#else
633	if (runtime < p->p_prev_runtime)
634		runtime = p->p_prev_runtime;
635#endif
636	mtx_lock(&racct_lock);
637	racct_set_locked(p, RACCT_CPU, runtime);
638
639	for (i = 0; i <= RACCT_MAX; i++) {
640		if (p->p_racct->r_resources[i] == 0)
641			continue;
642	    	if (!RACCT_IS_RECLAIMABLE(i))
643			continue;
644		racct_set_locked(p, i, 0);
645	}
646
647	mtx_unlock(&racct_lock);
648	PROC_UNLOCK(p);
649
650#ifdef RCTL
651	rctl_racct_release(p->p_racct);
652#endif
653	racct_destroy(&p->p_racct);
654}
655
656/*
657 * Called after credentials change, to move resource utilisation
658 * between raccts.
659 */
660void
661racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
662    struct ucred *newcred)
663{
664	struct uidinfo *olduip, *newuip;
665	struct loginclass *oldlc, *newlc;
666	struct prison *oldpr, *newpr, *pr;
667
668	PROC_LOCK_ASSERT(p, MA_NOTOWNED);
669
670	newuip = newcred->cr_ruidinfo;
671	olduip = oldcred->cr_ruidinfo;
672	newlc = newcred->cr_loginclass;
673	oldlc = oldcred->cr_loginclass;
674	newpr = newcred->cr_prison;
675	oldpr = oldcred->cr_prison;
676
677	mtx_lock(&racct_lock);
678	if (newuip != olduip) {
679		racct_sub_racct(olduip->ui_racct, p->p_racct);
680		racct_add_racct(newuip->ui_racct, p->p_racct);
681	}
682	if (newlc != oldlc) {
683		racct_sub_racct(oldlc->lc_racct, p->p_racct);
684		racct_add_racct(newlc->lc_racct, p->p_racct);
685	}
686	if (newpr != oldpr) {
687		for (pr = oldpr; pr != NULL; pr = pr->pr_parent)
688			racct_sub_racct(pr->pr_prison_racct->prr_racct,
689			    p->p_racct);
690		for (pr = newpr; pr != NULL; pr = pr->pr_parent)
691			racct_add_racct(pr->pr_prison_racct->prr_racct,
692			    p->p_racct);
693	}
694	mtx_unlock(&racct_lock);
695
696#ifdef RCTL
697	rctl_proc_ucred_changed(p, newcred);
698#endif
699}
700
701static void
702racctd(void)
703{
704	struct thread *td;
705	struct proc *p;
706	struct timeval wallclock;
707	uint64_t runtime;
708
709	for (;;) {
710		sx_slock(&allproc_lock);
711
712		FOREACH_PROC_IN_SYSTEM(p) {
713			if (p->p_state != PRS_NORMAL)
714				continue;
715			if (p->p_flag & P_SYSTEM)
716				continue;
717
718			microuptime(&wallclock);
719			timevalsub(&wallclock, &p->p_stats->p_start);
720			PROC_LOCK(p);
721			PROC_SLOCK(p);
722			FOREACH_THREAD_IN_PROC(p, td) {
723				ruxagg(p, td);
724				thread_lock(td);
725				thread_unlock(td);
726			}
727			runtime = cputick2usec(p->p_rux.rux_runtime);
728			PROC_SUNLOCK(p);
729#ifdef notyet
730			KASSERT(runtime >= p->p_prev_runtime,
731			    ("runtime < p_prev_runtime"));
732#else
733			if (runtime < p->p_prev_runtime)
734				runtime = p->p_prev_runtime;
735#endif
736			p->p_prev_runtime = runtime;
737			mtx_lock(&racct_lock);
738			racct_set_locked(p, RACCT_CPU, runtime);
739			racct_set_locked(p, RACCT_WALLCLOCK,
740			    wallclock.tv_sec * 1000000 + wallclock.tv_usec);
741			mtx_unlock(&racct_lock);
742			PROC_UNLOCK(p);
743		}
744		sx_sunlock(&allproc_lock);
745		pause("-", hz);
746	}
747}
748
749static struct kproc_desc racctd_kp = {
750	"racctd",
751	racctd,
752	NULL
753};
754SYSINIT(racctd, SI_SUB_RACCTD, SI_ORDER_FIRST, kproc_start, &racctd_kp);
755
756static void
757racct_init(void)
758{
759
760	racct_zone = uma_zcreate("racct", sizeof(struct racct),
761	    NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
762	/*
763	 * XXX: Move this somewhere.
764	 */
765	prison0.pr_prison_racct = prison_racct_find("0");
766}
767SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL);
768
769#else /* !RACCT */
770
771int
772racct_add(struct proc *p, int resource, uint64_t amount)
773{
774
775	return (0);
776}
777
778void
779racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
780{
781}
782
783void
784racct_add_force(struct proc *p, int resource, uint64_t amount)
785{
786
787	return;
788}
789
790int
791racct_set(struct proc *p, int resource, uint64_t amount)
792{
793
794	return (0);
795}
796
797void
798racct_set_force(struct proc *p, int resource, uint64_t amount)
799{
800}
801
802void
803racct_sub(struct proc *p, int resource, uint64_t amount)
804{
805}
806
807void
808racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
809{
810}
811
812uint64_t
813racct_get_limit(struct proc *p, int resource)
814{
815
816	return (UINT64_MAX);
817}
818
819uint64_t
820racct_get_available(struct proc *p, int resource)
821{
822
823	return (UINT64_MAX);
824}
825
826void
827racct_create(struct racct **racctp)
828{
829}
830
831void
832racct_destroy(struct racct **racctp)
833{
834}
835
836int
837racct_proc_fork(struct proc *parent, struct proc *child)
838{
839
840	return (0);
841}
842
843void
844racct_proc_fork_done(struct proc *child)
845{
846}
847
848void
849racct_proc_exit(struct proc *p)
850{
851}
852
853#endif /* !RACCT */
854