1097055e2SEdward Tomasz Napierala /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3c4e20cadSPedro F. Giffuni *
4097055e2SEdward Tomasz Napierala * Copyright (c) 2010 The FreeBSD Foundation
5097055e2SEdward Tomasz Napierala *
6097055e2SEdward Tomasz Napierala * This software was developed by Edward Tomasz Napierala under sponsorship
7097055e2SEdward Tomasz Napierala * from the FreeBSD Foundation.
8097055e2SEdward Tomasz Napierala *
9097055e2SEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without
10097055e2SEdward Tomasz Napierala * modification, are permitted provided that the following conditions
11097055e2SEdward Tomasz Napierala * are met:
12097055e2SEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright
13097055e2SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer.
14097055e2SEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright
15097055e2SEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the
16097055e2SEdward Tomasz Napierala * documentation and/or other materials provided with the distribution.
17097055e2SEdward Tomasz Napierala *
18097055e2SEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19097055e2SEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20097055e2SEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21097055e2SEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22097055e2SEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23097055e2SEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24097055e2SEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25097055e2SEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26097055e2SEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27097055e2SEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28097055e2SEdward Tomasz Napierala * SUCH DAMAGE.
29097055e2SEdward Tomasz Napierala */
30097055e2SEdward Tomasz Napierala
31097055e2SEdward Tomasz Napierala /*
32097055e2SEdward Tomasz Napierala * Resource accounting.
33097055e2SEdward Tomasz Napierala */
34097055e2SEdward Tomasz Napierala
35097055e2SEdward Tomasz Napierala #ifndef _RACCT_H_
36097055e2SEdward Tomasz Napierala #define _RACCT_H_
37097055e2SEdward Tomasz Napierala
38097055e2SEdward Tomasz Napierala #include <sys/types.h>
392b4035eeSEdward Tomasz Napierala #include <sys/queue.h>
402b4035eeSEdward Tomasz Napierala #include <sys/stdint.h>
412b4035eeSEdward Tomasz Napierala #include <sys/sysctl.h>
42097055e2SEdward Tomasz Napierala
43ae34b6ffSEdward Tomasz Napierala struct buf;
44097055e2SEdward Tomasz Napierala struct proc;
45097055e2SEdward Tomasz Napierala struct rctl_rule_link;
46097055e2SEdward Tomasz Napierala struct ucred;
47097055e2SEdward Tomasz Napierala
48097055e2SEdward Tomasz Napierala /*
49097055e2SEdward Tomasz Napierala * Resources.
50097055e2SEdward Tomasz Napierala */
51097055e2SEdward Tomasz Napierala #define RACCT_UNDEFINED -1
52097055e2SEdward Tomasz Napierala #define RACCT_CPU 0
537e2548aeSEdward Tomasz Napierala #define RACCT_DATA 1
547e2548aeSEdward Tomasz Napierala #define RACCT_STACK 2
557e2548aeSEdward Tomasz Napierala #define RACCT_CORE 3
567e2548aeSEdward Tomasz Napierala #define RACCT_RSS 4
577e2548aeSEdward Tomasz Napierala #define RACCT_MEMLOCK 5
587e2548aeSEdward Tomasz Napierala #define RACCT_NPROC 6
597e2548aeSEdward Tomasz Napierala #define RACCT_NOFILE 7
607e2548aeSEdward Tomasz Napierala #define RACCT_VMEM 8
617e2548aeSEdward Tomasz Napierala #define RACCT_NPTS 9
627e2548aeSEdward Tomasz Napierala #define RACCT_SWAP 10
637e2548aeSEdward Tomasz Napierala #define RACCT_NTHR 11
647e2548aeSEdward Tomasz Napierala #define RACCT_MSGQQUEUED 12
657e2548aeSEdward Tomasz Napierala #define RACCT_MSGQSIZE 13
667e2548aeSEdward Tomasz Napierala #define RACCT_NMSGQ 14
677e2548aeSEdward Tomasz Napierala #define RACCT_NSEM 15
687e2548aeSEdward Tomasz Napierala #define RACCT_NSEMOP 16
697e2548aeSEdward Tomasz Napierala #define RACCT_NSHM 17
707e2548aeSEdward Tomasz Napierala #define RACCT_SHMSIZE 18
717e2548aeSEdward Tomasz Napierala #define RACCT_WALLCLOCK 19
7236af9869SEdward Tomasz Napierala #define RACCT_PCTCPU 20
73ae34b6ffSEdward Tomasz Napierala #define RACCT_READBPS 21
74ae34b6ffSEdward Tomasz Napierala #define RACCT_WRITEBPS 22
75ae34b6ffSEdward Tomasz Napierala #define RACCT_READIOPS 23
76ae34b6ffSEdward Tomasz Napierala #define RACCT_WRITEIOPS 24
77ae34b6ffSEdward Tomasz Napierala #define RACCT_MAX RACCT_WRITEIOPS
78097055e2SEdward Tomasz Napierala
79097055e2SEdward Tomasz Napierala /*
80097055e2SEdward Tomasz Napierala * Resource properties.
81097055e2SEdward Tomasz Napierala */
8285a2f1b4SEdward Tomasz Napierala #define RACCT_IN_MILLIONS 0x01
83097055e2SEdward Tomasz Napierala #define RACCT_RECLAIMABLE 0x02
84097055e2SEdward Tomasz Napierala #define RACCT_INHERITABLE 0x04
85097055e2SEdward Tomasz Napierala #define RACCT_DENIABLE 0x08
86097055e2SEdward Tomasz Napierala #define RACCT_SLOPPY 0x10
8736af9869SEdward Tomasz Napierala #define RACCT_DECAYING 0x20
88097055e2SEdward Tomasz Napierala
89097055e2SEdward Tomasz Napierala extern int racct_types[];
90eec8d0a3SMateusz Guzik extern bool racct_enable;
914b5c9cf6SEdward Tomasz Napierala
924b5c9cf6SEdward Tomasz Napierala #define ASSERT_RACCT_ENABLED() KASSERT(racct_enable, \
934b5c9cf6SEdward Tomasz Napierala ("%s called with !racct_enable", __func__))
94097055e2SEdward Tomasz Napierala
95097055e2SEdward Tomasz Napierala /*
9685a2f1b4SEdward Tomasz Napierala * Amount stored in c_resources[] is 10**6 times bigger than what's
97097055e2SEdward Tomasz Napierala * visible to the userland. It gets fixed up when retrieving resource
98097055e2SEdward Tomasz Napierala * usage or adding rules.
99097055e2SEdward Tomasz Napierala */
1008691cc73SConrad Meyer #define RACCT_IS_IN_MILLIONS(X) \
1018691cc73SConrad Meyer ((X) != RACCT_UNDEFINED && (racct_types[(X)] & RACCT_IN_MILLIONS) != 0)
102097055e2SEdward Tomasz Napierala
103097055e2SEdward Tomasz Napierala /*
10436af9869SEdward Tomasz Napierala * Resource usage can drop, as opposed to only grow. When the process
105c4563b16SEdward Tomasz Napierala * terminates, its resource usage is subtracted from the respective
10636af9869SEdward Tomasz Napierala * per-credential racct containers.
107097055e2SEdward Tomasz Napierala */
1084fe84775SEdward Tomasz Napierala #define RACCT_IS_RECLAIMABLE(X) (racct_types[X] & RACCT_RECLAIMABLE)
109097055e2SEdward Tomasz Napierala
110097055e2SEdward Tomasz Napierala /*
111097055e2SEdward Tomasz Napierala * Children inherit resource usage.
112097055e2SEdward Tomasz Napierala */
1134fe84775SEdward Tomasz Napierala #define RACCT_IS_INHERITABLE(X) (racct_types[X] & RACCT_INHERITABLE)
114097055e2SEdward Tomasz Napierala
115097055e2SEdward Tomasz Napierala /*
116097055e2SEdward Tomasz Napierala * racct_{add,set}(9) can actually return an error and not update resource
117097055e2SEdward Tomasz Napierala * usage counters. Note that even when resource is not deniable, allocating
118097055e2SEdward Tomasz Napierala * resource might cause signals to be sent by RCTL code.
119097055e2SEdward Tomasz Napierala */
1204fe84775SEdward Tomasz Napierala #define RACCT_IS_DENIABLE(X) (racct_types[X] & RACCT_DENIABLE)
121097055e2SEdward Tomasz Napierala
122097055e2SEdward Tomasz Napierala /*
123097055e2SEdward Tomasz Napierala * Per-process resource usage information makes no sense, but per-credential
124097055e2SEdward Tomasz Napierala * one does. This kind of resources are usually allocated for process, but
125097055e2SEdward Tomasz Napierala * freed using credentials.
126097055e2SEdward Tomasz Napierala */
1274fe84775SEdward Tomasz Napierala #define RACCT_IS_SLOPPY(X) (racct_types[X] & RACCT_SLOPPY)
128097055e2SEdward Tomasz Napierala
129097055e2SEdward Tomasz Napierala /*
13036af9869SEdward Tomasz Napierala * When a process terminates, its resource usage is not automatically
13136af9869SEdward Tomasz Napierala * subtracted from per-credential racct containers. Instead, the resource
13236af9869SEdward Tomasz Napierala * usage of per-credential racct containers decays in time.
133c4563b16SEdward Tomasz Napierala * Resource usage can also drop for such resource.
13436af9869SEdward Tomasz Napierala */
13536af9869SEdward Tomasz Napierala #define RACCT_IS_DECAYING(X) (racct_types[X] & RACCT_DECAYING)
13636af9869SEdward Tomasz Napierala
13736af9869SEdward Tomasz Napierala /*
13836af9869SEdward Tomasz Napierala * Resource usage can drop, as opposed to only grow.
13936af9869SEdward Tomasz Napierala */
14036af9869SEdward Tomasz Napierala #define RACCT_CAN_DROP(X) (RACCT_IS_RECLAIMABLE(X) | RACCT_IS_DECAYING(X))
14136af9869SEdward Tomasz Napierala
14236af9869SEdward Tomasz Napierala /*
143097055e2SEdward Tomasz Napierala * The 'racct' structure defines resource consumption for a particular
144097055e2SEdward Tomasz Napierala * subject, such as process or jail.
145097055e2SEdward Tomasz Napierala *
146097055e2SEdward Tomasz Napierala * This structure must be filled with zeroes initially.
147097055e2SEdward Tomasz Napierala */
148097055e2SEdward Tomasz Napierala struct racct {
149097055e2SEdward Tomasz Napierala int64_t r_resources[RACCT_MAX + 1];
150097055e2SEdward Tomasz Napierala LIST_HEAD(, rctl_rule_link) r_rule_links;
151097055e2SEdward Tomasz Napierala };
152097055e2SEdward Tomasz Napierala
1532b4035eeSEdward Tomasz Napierala SYSCTL_DECL(_kern_racct);
1542b4035eeSEdward Tomasz Napierala
155dd2390beSMateusz Guzik #ifdef RACCT
156dd2390beSMateusz Guzik
157bbe4eb6dSEdward Tomasz Napierala extern struct mtx racct_lock;
158bbe4eb6dSEdward Tomasz Napierala
159bbe4eb6dSEdward Tomasz Napierala #define RACCT_LOCK() mtx_lock(&racct_lock)
160bbe4eb6dSEdward Tomasz Napierala #define RACCT_UNLOCK() mtx_unlock(&racct_lock)
161bbe4eb6dSEdward Tomasz Napierala #define RACCT_LOCK_ASSERT() mtx_assert(&racct_lock, MA_OWNED)
162bbe4eb6dSEdward Tomasz Napierala
163448db4f7SMateusz Guzik #define RACCT_ENABLED() __predict_false(racct_enable)
164448db4f7SMateusz Guzik
1652554f86aSMateusz Guzik #define RACCT_PROC_LOCK(p) do { \
166448db4f7SMateusz Guzik if (RACCT_ENABLED()) \
1672554f86aSMateusz Guzik PROC_LOCK(p); \
1682554f86aSMateusz Guzik } while (0)
1692554f86aSMateusz Guzik #define RACCT_PROC_UNLOCK(p) do { \
170448db4f7SMateusz Guzik if (RACCT_ENABLED()) \
1712554f86aSMateusz Guzik PROC_UNLOCK(p); \
1722554f86aSMateusz Guzik } while (0)
1732554f86aSMateusz Guzik
174097055e2SEdward Tomasz Napierala int racct_add(struct proc *p, int resource, uint64_t amount);
175097055e2SEdward Tomasz Napierala void racct_add_cred(struct ucred *cred, int resource, uint64_t amount);
176097055e2SEdward Tomasz Napierala void racct_add_force(struct proc *p, int resource, uint64_t amount);
177ae34b6ffSEdward Tomasz Napierala void racct_add_buf(struct proc *p, const struct buf *bufp, int is_write);
178097055e2SEdward Tomasz Napierala int racct_set(struct proc *p, int resource, uint64_t amount);
179448db4f7SMateusz Guzik int racct_set_unlocked(struct proc *p, int resource, uint64_t amount);
180097055e2SEdward Tomasz Napierala void racct_set_force(struct proc *p, int resource, uint64_t amount);
181097055e2SEdward Tomasz Napierala void racct_sub(struct proc *p, int resource, uint64_t amount);
182097055e2SEdward Tomasz Napierala void racct_sub_cred(struct ucred *cred, int resource, uint64_t amount);
183097055e2SEdward Tomasz Napierala uint64_t racct_get_limit(struct proc *p, int resource);
184097055e2SEdward Tomasz Napierala uint64_t racct_get_available(struct proc *p, int resource);
185097055e2SEdward Tomasz Napierala
186097055e2SEdward Tomasz Napierala void racct_create(struct racct **racctp);
187097055e2SEdward Tomasz Napierala void racct_destroy(struct racct **racctp);
188097055e2SEdward Tomasz Napierala
189097055e2SEdward Tomasz Napierala int racct_proc_fork(struct proc *parent, struct proc *child);
19072a401d9SEdward Tomasz Napierala void racct_proc_fork_done(struct proc *child);
191097055e2SEdward Tomasz Napierala void racct_proc_exit(struct proc *p);
192097055e2SEdward Tomasz Napierala
193097055e2SEdward Tomasz Napierala void racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
194097055e2SEdward Tomasz Napierala struct ucred *newcred);
195c34bbd2aSEdward Tomasz Napierala void racct_move(struct racct *dest, struct racct *src);
196ae34b6ffSEdward Tomasz Napierala void racct_proc_throttle(struct proc *p, int timeout);
197097055e2SEdward Tomasz Napierala
198dd2390beSMateusz Guzik #else
199dd2390beSMateusz Guzik
2002554f86aSMateusz Guzik #define RACCT_PROC_LOCK(p) do { } while (0)
2012554f86aSMateusz Guzik #define RACCT_PROC_UNLOCK(p) do { } while (0)
2022554f86aSMateusz Guzik
203dd2390beSMateusz Guzik static inline int
racct_add(struct proc * p,int resource,uint64_t amount)204dd2390beSMateusz Guzik racct_add(struct proc *p, int resource, uint64_t amount)
205dd2390beSMateusz Guzik {
206dd2390beSMateusz Guzik
207dd2390beSMateusz Guzik return (0);
208dd2390beSMateusz Guzik }
209dd2390beSMateusz Guzik
210dd2390beSMateusz Guzik static inline void
racct_add_cred(struct ucred * cred,int resource,uint64_t amount)211dd2390beSMateusz Guzik racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
212dd2390beSMateusz Guzik {
213dd2390beSMateusz Guzik }
214dd2390beSMateusz Guzik
215dd2390beSMateusz Guzik static inline void
racct_add_force(struct proc * p,int resource,uint64_t amount)216dd2390beSMateusz Guzik racct_add_force(struct proc *p, int resource, uint64_t amount)
217dd2390beSMateusz Guzik {
218dd2390beSMateusz Guzik }
219dd2390beSMateusz Guzik
220dd2390beSMateusz Guzik static inline int
racct_set(struct proc * p,int resource,uint64_t amount)221dd2390beSMateusz Guzik racct_set(struct proc *p, int resource, uint64_t amount)
222dd2390beSMateusz Guzik {
223dd2390beSMateusz Guzik
224dd2390beSMateusz Guzik return (0);
225dd2390beSMateusz Guzik }
226dd2390beSMateusz Guzik
227dd2390beSMateusz Guzik static inline void
racct_set_force(struct proc * p,int resource,uint64_t amount)228dd2390beSMateusz Guzik racct_set_force(struct proc *p, int resource, uint64_t amount)
229dd2390beSMateusz Guzik {
230dd2390beSMateusz Guzik }
231dd2390beSMateusz Guzik
232dd2390beSMateusz Guzik static inline void
racct_sub(struct proc * p,int resource,uint64_t amount)233dd2390beSMateusz Guzik racct_sub(struct proc *p, int resource, uint64_t amount)
234dd2390beSMateusz Guzik {
235dd2390beSMateusz Guzik }
236dd2390beSMateusz Guzik
237dd2390beSMateusz Guzik static inline void
racct_sub_cred(struct ucred * cred,int resource,uint64_t amount)238dd2390beSMateusz Guzik racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
239dd2390beSMateusz Guzik {
240dd2390beSMateusz Guzik }
241dd2390beSMateusz Guzik
242dd2390beSMateusz Guzik static inline uint64_t
racct_get_limit(struct proc * p,int resource)243dd2390beSMateusz Guzik racct_get_limit(struct proc *p, int resource)
244dd2390beSMateusz Guzik {
245dd2390beSMateusz Guzik
246dd2390beSMateusz Guzik return (UINT64_MAX);
247dd2390beSMateusz Guzik }
248dd2390beSMateusz Guzik
249dd2390beSMateusz Guzik static inline uint64_t
racct_get_available(struct proc * p,int resource)250dd2390beSMateusz Guzik racct_get_available(struct proc *p, int resource)
251dd2390beSMateusz Guzik {
252dd2390beSMateusz Guzik
253dd2390beSMateusz Guzik return (UINT64_MAX);
254dd2390beSMateusz Guzik }
255dd2390beSMateusz Guzik
256dff9862cSMateusz Guzik #define racct_create(x)
257dff9862cSMateusz Guzik #define racct_destroy(x)
258dd2390beSMateusz Guzik
259dd2390beSMateusz Guzik static inline int
racct_proc_fork(struct proc * parent,struct proc * child)260dd2390beSMateusz Guzik racct_proc_fork(struct proc *parent, struct proc *child)
261dd2390beSMateusz Guzik {
262dd2390beSMateusz Guzik
263dd2390beSMateusz Guzik return (0);
264dd2390beSMateusz Guzik }
265dd2390beSMateusz Guzik
266dd2390beSMateusz Guzik static inline void
racct_proc_fork_done(struct proc * child)267dd2390beSMateusz Guzik racct_proc_fork_done(struct proc *child)
268dd2390beSMateusz Guzik {
269dd2390beSMateusz Guzik }
270dd2390beSMateusz Guzik
271dd2390beSMateusz Guzik static inline void
racct_proc_exit(struct proc * p)272dd2390beSMateusz Guzik racct_proc_exit(struct proc *p)
273dd2390beSMateusz Guzik {
274dd2390beSMateusz Guzik }
275dd2390beSMateusz Guzik
276dd2390beSMateusz Guzik #endif
277dd2390beSMateusz Guzik
278097055e2SEdward Tomasz Napierala #endif /* !_RACCT_H_ */
279