| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright (c) 2010 The FreeBSD Foundation |
| 5 | * |
| 6 | * This software was developed by Edward Tomasz Napierala under sponsorship |
| 7 | * from the FreeBSD Foundation. |
| 8 | * |
| 9 | * Redistribution and use in source and binary forms, with or without |
| 10 | * modification, are permitted provided that the following conditions |
| 11 | * are met: |
| 12 | * 1. Redistributions of source code must retain the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer. |
| 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| 15 | * notice, this list of conditions and the following disclaimer in the |
| 16 | * documentation and/or other materials provided with the distribution. |
| 17 | * |
| 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 22 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 28 | * SUCH DAMAGE. |
| 29 | */ |
| 30 | |
| 31 | /* |
| 32 | * Resource accounting. |
| 33 | */ |
| 34 | |
| 35 | #ifndef _RACCT_H_ |
| 36 | #define	_RACCT_H_ |
| 37 | |
| 38 | #include <sys/types.h> |
| 39 | #include <sys/queue.h> |
| 40 | #include <sys/stdint.h> |
| 41 | #include <sys/sysctl.h> |
| 42 | |
| 43 | struct buf; |
| 44 | struct proc; |
| 45 | struct rctl_rule_link; |
| 46 | struct ucred; |
| 47 | |
| 48 | /* |
| 49 | * Resources. |
| 50 | */ |
| 51 | #define	RACCT_UNDEFINED		-1 |
| 52 | #define	RACCT_CPU		0 |
| 53 | #define	RACCT_DATA		1 |
| 54 | #define	RACCT_STACK		2 |
| 55 | #define	RACCT_CORE		3 |
| 56 | #define	RACCT_RSS		4 |
| 57 | #define	RACCT_MEMLOCK		5 |
| 58 | #define	RACCT_NPROC		6 |
| 59 | #define	RACCT_NOFILE		7 |
| 60 | #define	RACCT_VMEM		8 |
| 61 | #define	RACCT_NPTS		9 |
| 62 | #define	RACCT_SWAP		10 |
| 63 | #define	RACCT_NTHR		11 |
| 64 | #define	RACCT_MSGQQUEUED	12 |
| 65 | #define	RACCT_MSGQSIZE		13 |
| 66 | #define	RACCT_NMSGQ		14 |
| 67 | #define	RACCT_NSEM		15 |
| 68 | #define	RACCT_NSEMOP		16 |
| 69 | #define	RACCT_NSHM		17 |
| 70 | #define	RACCT_SHMSIZE		18 |
| 71 | #define	RACCT_WALLCLOCK		19 |
| 72 | #define	RACCT_PCTCPU		20 |
| 73 | #define	RACCT_READBPS		21 |
| 74 | #define	RACCT_WRITEBPS		22 |
| 75 | #define	RACCT_READIOPS		23 |
| 76 | #define	RACCT_WRITEIOPS		24 |
| 77 | #define	RACCT_MAX		RACCT_WRITEIOPS |
| 78 | |
| 79 | /* |
| 80 | * Resource properties. |
| 81 | */ |
| 82 | #define	RACCT_IN_MILLIONS	0x01 |
| 83 | #define	RACCT_RECLAIMABLE	0x02 |
| 84 | #define	RACCT_INHERITABLE	0x04 |
| 85 | #define	RACCT_DENIABLE		0x08 |
| 86 | #define	RACCT_SLOPPY		0x10 |
| 87 | #define	RACCT_DECAYING		0x20 |
| 88 | |
| 89 | extern int racct_types[]; |
| 90 | extern bool racct_enable; |
| 91 | |
| 92 | #define ASSERT_RACCT_ENABLED()	KASSERT(racct_enable, \ |
| 93 | 				 ("%s called with !racct_enable", __func__)) |
| 94 | |
| 95 | /* |
| 96 | * Amount stored in c_resources[] is 10**6 times bigger than what's |
| 97 | * visible to the userland. It gets fixed up when retrieving resource |
| 98 | * usage or adding rules. |
| 99 | */ |
| 100 | #define	RACCT_IS_IN_MILLIONS(X)	\ |
| 101 | ((X) != RACCT_UNDEFINED && (racct_types[(X)] & RACCT_IN_MILLIONS) != 0) |
| 102 | |
| 103 | /* |
| 104 | * Resource usage can drop, as opposed to only grow. When the process |
| 105 | * terminates, its resource usage is subtracted from the respective |
| 106 | * per-credential racct containers. |
| 107 | */ |
| 108 | #define	RACCT_IS_RECLAIMABLE(X)	(racct_types[X] & RACCT_RECLAIMABLE) |
| 109 | |
| 110 | /* |
| 111 | * Children inherit resource usage. |
| 112 | */ |
| 113 | #define	RACCT_IS_INHERITABLE(X)	(racct_types[X] & RACCT_INHERITABLE) |
| 114 | |
| 115 | /* |
| 116 | * racct_{add,set}(9) can actually return an error and not update resource |
| 117 | * usage counters. Note that even when resource is not deniable, allocating |
| 118 | * resource might cause signals to be sent by RCTL code. |
| 119 | */ |
| 120 | #define	RACCT_IS_DENIABLE(X)		(racct_types[X] & RACCT_DENIABLE) |
| 121 | |
| 122 | /* |
| 123 | * Per-process resource usage information makes no sense, but per-credential |
| 124 | * one does. This kind of resources are usually allocated for process, but |
| 125 | * freed using credentials. |
| 126 | */ |
| 127 | #define	RACCT_IS_SLOPPY(X)		(racct_types[X] & RACCT_SLOPPY) |
| 128 | |
| 129 | /* |
| 130 | * When a process terminates, its resource usage is not automatically |
| 131 | * subtracted from per-credential racct containers. Instead, the resource |
| 132 | * usage of per-credential racct containers decays in time. |
| 133 | * Resource usage can also drop for such resource. |
| 134 | */ |
| 135 | #define RACCT_IS_DECAYING(X)		(racct_types[X] & RACCT_DECAYING) |
| 136 | |
| 137 | /* |
| 138 | * Resource usage can drop, as opposed to only grow. |
| 139 | */ |
| 140 | #define RACCT_CAN_DROP(X)		(RACCT_IS_RECLAIMABLE(X) | RACCT_IS_DECAYING(X)) |
| 141 | |
| 142 | /* |
| 143 | * The 'racct' structure defines resource consumption for a particular |
| 144 | * subject, such as process or jail. It also contains the total |
| 145 | * cpu time and real time of the subject, recorded at the most recent |
| 146 | * time that RACCT_PCPU was updated. |
| 147 | * |
| 148 | * This structure must be filled with zeroes initially. |
| 149 | */ |
| 150 | struct racct { |
| 151 | 	int64_t				r_resources[RACCT_MAX + 1]; |
| 152 | 	LIST_HEAD(, rctl_rule_link)	r_rule_links; |
| 153 | 	uint64_t			r_runtime; |
| 154 | 	struct timeval			r_time; |
| 155 | }; |
| 156 | |
| 157 | SYSCTL_DECL(_kern_racct); |
| 158 | |
| 159 | #ifdef RACCT |
| 160 | |
| 161 | extern struct mtx racct_lock; |
| 162 | |
| 163 | #define RACCT_LOCK()		mtx_lock(&racct_lock) |
| 164 | #define RACCT_UNLOCK()		mtx_unlock(&racct_lock) |
| 165 | #define RACCT_LOCK_ASSERT()	mtx_assert(&racct_lock, MA_OWNED) |
| 166 | |
| 167 | #define RACCT_ENABLED()		__predict_false(racct_enable) |
| 168 | |
| 169 | #define	RACCT_PROC_LOCK(p)	do {		\ |
| 170 | 	if (RACCT_ENABLED())			\ |
| 171 | 		PROC_LOCK(p);			\ |
| 172 | } while (0) |
| 173 | #define	RACCT_PROC_UNLOCK(p)	do {		\ |
| 174 | 	if (RACCT_ENABLED())			\ |
| 175 | 		PROC_UNLOCK(p);			\ |
| 176 | } while (0) |
| 177 | |
| 178 | int	racct_add(struct proc *p, int resource, uint64_t amount); |
| 179 | void	racct_add_cred(struct ucred *cred, int resource, uint64_t amount); |
| 180 | void	racct_add_force(struct proc *p, int resource, uint64_t amount); |
| 181 | void	racct_add_buf(struct proc *p, const struct buf *bufp, int is_write); |
| 182 | int	racct_set(struct proc *p, int resource, uint64_t amount); |
| 183 | int	racct_set_unlocked(struct proc *p, int resource, uint64_t amount); |
| 184 | void	racct_set_force(struct proc *p, int resource, uint64_t amount); |
| 185 | void	racct_sub(struct proc *p, int resource, uint64_t amount); |
| 186 | void	racct_sub_cred(struct ucred *cred, int resource, uint64_t amount); |
| 187 | uint64_t	racct_get_limit(struct proc *p, int resource); |
| 188 | uint64_t	racct_get_available(struct proc *p, int resource); |
| 189 | |
| 190 | void	racct_create(struct racct **racctp); |
| 191 | void	racct_destroy(struct racct **racctp); |
| 192 | |
| 193 | int	racct_proc_fork(struct proc *parent, struct proc *child); |
| 194 | void	racct_proc_fork_done(struct proc *child); |
| 195 | void	racct_proc_exit(struct proc *p); |
| 196 | |
| 197 | void	racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred, |
| 198 | 	 struct ucred *newcred); |
| 199 | void	racct_move(struct racct *dest, struct racct *src); |
| 200 | void	racct_proc_throttle(struct proc *p, int timeout); |
| 201 | |
| 202 | #else |
| 203 | |
| 204 | #define	RACCT_PROC_LOCK(p)	do { } while (0) |
| 205 | #define	RACCT_PROC_UNLOCK(p)	do { } while (0) |
| 206 | |
| 207 | static inline int |
| 208 | racct_add(struct proc *p, int resource, uint64_t amount) |
| 209 | { |
| 210 | |
| 211 | 	return (0); |
| 212 | } |
| 213 | |
| 214 | static inline void |
| 215 | racct_add_cred(struct ucred *cred, int resource, uint64_t amount) |
| 216 | { |
| 217 | } |
| 218 | |
| 219 | static inline void |
| 220 | racct_add_force(struct proc *p, int resource, uint64_t amount) |
| 221 | { |
| 222 | } |
| 223 | |
| 224 | static inline int |
| 225 | racct_set(struct proc *p, int resource, uint64_t amount) |
| 226 | { |
| 227 | |
| 228 | 	return (0); |
| 229 | } |
| 230 | |
| 231 | static inline void |
| 232 | racct_set_force(struct proc *p, int resource, uint64_t amount) |
| 233 | { |
| 234 | } |
| 235 | |
| 236 | static inline void |
| 237 | racct_sub(struct proc *p, int resource, uint64_t amount) |
| 238 | { |
| 239 | } |
| 240 | |
| 241 | static inline void |
| 242 | racct_sub_cred(struct ucred *cred, int resource, uint64_t amount) |
| 243 | { |
| 244 | } |
| 245 | |
| 246 | static inline uint64_t |
| 247 | racct_get_limit(struct proc *p, int resource) |
| 248 | { |
| 249 | |
| 250 | 	return (UINT64_MAX); |
| 251 | } |
| 252 | |
| 253 | static inline uint64_t |
| 254 | racct_get_available(struct proc *p, int resource) |
| 255 | { |
| 256 | |
| 257 | 	return (UINT64_MAX); |
| 258 | } |
| 259 | |
| 260 | #define	racct_create(x) |
| 261 | #define	racct_destroy(x) |
| 262 | |
| 263 | static inline int |
| 264 | racct_proc_fork(struct proc *parent, struct proc *child) |
| 265 | { |
| 266 | |
| 267 | 	return (0); |
| 268 | } |
| 269 | |
| 270 | static inline void |
| 271 | racct_proc_fork_done(struct proc *child) |
| 272 | { |
| 273 | } |
| 274 | |
| 275 | static inline void |
| 276 | racct_proc_exit(struct proc *p) |
| 277 | { |
| 278 | } |
| 279 | |
| 280 | #endif |
| 281 | |
| 282 | #endif /* !_RACCT_H_ */ |