aboutsummaryrefslogtreecommitdiff
path: root/sys/sys/racct.h
blob: ec3322bdfdf90ed0e4dbaceacfad0ada01b3ae53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*-
 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
 *
 * Copyright (c) 2010 The FreeBSD Foundation
 * All rights reserved.
 *
 * This software was developed by Edward Tomasz Napierala under sponsorship
 * from the FreeBSD Foundation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD$
 */

/*
 * Resource accounting.
 */

#ifndef _RACCT_H_
#define	_RACCT_H_

#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/stdint.h>
#include <sys/sysctl.h>

struct buf;
struct proc;
struct rctl_rule_link;
struct ucred;

/*
 * Resources.
 */
#define	RACCT_UNDEFINED		-1
#define	RACCT_CPU		0
#define	RACCT_DATA		1
#define	RACCT_STACK		2
#define	RACCT_CORE		3
#define	RACCT_RSS		4
#define	RACCT_MEMLOCK		5
#define	RACCT_NPROC		6
#define	RACCT_NOFILE		7
#define	RACCT_VMEM		8
#define	RACCT_NPTS		9
#define	RACCT_SWAP		10
#define	RACCT_NTHR		11
#define	RACCT_MSGQQUEUED	12
#define	RACCT_MSGQSIZE		13
#define	RACCT_NMSGQ		14
#define	RACCT_NSEM		15
#define	RACCT_NSEMOP		16
#define	RACCT_NSHM		17
#define	RACCT_SHMSIZE		18
#define	RACCT_WALLCLOCK		19
#define	RACCT_PCTCPU		20
#define	RACCT_READBPS		21
#define	RACCT_WRITEBPS		22
#define	RACCT_READIOPS		23
#define	RACCT_WRITEIOPS		24
#define	RACCT_MAX		RACCT_WRITEIOPS

/*
 * Resource properties.
 */
#define	RACCT_IN_MILLIONS	0x01
#define	RACCT_RECLAIMABLE	0x02
#define	RACCT_INHERITABLE	0x04
#define	RACCT_DENIABLE		0x08
#define	RACCT_SLOPPY		0x10
#define	RACCT_DECAYING		0x20

extern int racct_types[];
extern int racct_enable;

#define ASSERT_RACCT_ENABLED()	KASSERT(racct_enable, \
				    ("%s called with !racct_enable", __func__))

/*
 * Amount stored in c_resources[] is 10**6 times bigger than what's
 * visible to the userland.  It gets fixed up when retrieving resource
 * usage or adding rules.
 */
#define	RACCT_IS_IN_MILLIONS(X)	\
    ((X) != RACCT_UNDEFINED && (racct_types[(X)] & RACCT_IN_MILLIONS) != 0)

/*
 * Resource usage can drop, as opposed to only grow.  When the process
 * terminates, its resource usage is subtracted from the respective
 * per-credential racct containers.
 */
#define	RACCT_IS_RECLAIMABLE(X)	(racct_types[X] & RACCT_RECLAIMABLE)

/*
 * Children inherit resource usage.
 */
#define	RACCT_IS_INHERITABLE(X)	(racct_types[X] & RACCT_INHERITABLE)

/*
 * racct_{add,set}(9) can actually return an error and not update resource
 * usage counters.  Note that even when resource is not deniable, allocating
 * resource might cause signals to be sent by RCTL code.
 */
#define	RACCT_IS_DENIABLE(X)		(racct_types[X] & RACCT_DENIABLE)

/*
 * Per-process resource usage information makes no sense, but per-credential
 * one does.  This kind of resources are usually allocated for process, but
 * freed using credentials.
 */
#define	RACCT_IS_SLOPPY(X)		(racct_types[X] & RACCT_SLOPPY)

/*
 * When a process terminates, its resource usage is not automatically
 * subtracted from per-credential racct containers.  Instead, the resource
 * usage of per-credential racct containers decays in time.
 * Resource usage can also drop for such resource.
 */
#define RACCT_IS_DECAYING(X)		(racct_types[X] & RACCT_DECAYING)

/*
 * Resource usage can drop, as opposed to only grow.
 */
#define RACCT_CAN_DROP(X)		(RACCT_IS_RECLAIMABLE(X) | RACCT_IS_DECAYING(X))

/*
 * The 'racct' structure defines resource consumption for a particular
 * subject, such as process or jail.
 *
 * This structure must be filled with zeroes initially.
 */
struct racct {
	int64_t				r_resources[RACCT_MAX + 1];
	LIST_HEAD(, rctl_rule_link)	r_rule_links;
};

SYSCTL_DECL(_kern_racct);

#ifdef RACCT

extern struct mtx racct_lock;

#define RACCT_LOCK()		mtx_lock(&racct_lock)
#define RACCT_UNLOCK()		mtx_unlock(&racct_lock)
#define RACCT_LOCK_ASSERT()	mtx_assert(&racct_lock, MA_OWNED)

int	racct_add(struct proc *p, int resource, uint64_t amount);
void	racct_add_cred(struct ucred *cred, int resource, uint64_t amount);
void	racct_add_force(struct proc *p, int resource, uint64_t amount);
void	racct_add_buf(struct proc *p, const struct buf *bufp, int is_write);
int	racct_set(struct proc *p, int resource, uint64_t amount);
void	racct_set_force(struct proc *p, int resource, uint64_t amount);
void	racct_sub(struct proc *p, int resource, uint64_t amount);
void	racct_sub_cred(struct ucred *cred, int resource, uint64_t amount);
uint64_t	racct_get_limit(struct proc *p, int resource);
uint64_t	racct_get_available(struct proc *p, int resource);

void	racct_create(struct racct **racctp);
void	racct_destroy(struct racct **racctp);

int	racct_proc_fork(struct proc *parent, struct proc *child);
void	racct_proc_fork_done(struct proc *child);
void	racct_proc_exit(struct proc *p);

void	racct_proc_ucred_changed(struct proc *p, struct ucred *oldcred,
	    struct ucred *newcred);
void	racct_move(struct racct *dest, struct racct *src);
void	racct_proc_throttle(struct proc *p, int timeout);

#else

static inline int
racct_add(struct proc *p, int resource, uint64_t amount)
{

	return (0);
}

static inline void
racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
{
}

static inline void
racct_add_force(struct proc *p, int resource, uint64_t amount)
{
}

static inline int
racct_set(struct proc *p, int resource, uint64_t amount)
{

	return (0);
}

static inline void
racct_set_force(struct proc *p, int resource, uint64_t amount)
{
}

static inline void
racct_sub(struct proc *p, int resource, uint64_t amount)
{
}

static inline void
racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
{
}

static inline uint64_t
racct_get_limit(struct proc *p, int resource)
{

	return (UINT64_MAX);
}

static inline uint64_t
racct_get_available(struct proc *p, int resource)
{

	return (UINT64_MAX);
}

#define	racct_create(x)
#define	racct_destroy(x)

static inline int
racct_proc_fork(struct proc *parent, struct proc *child)
{

	return (0);
}

static inline void
racct_proc_fork_done(struct proc *child)
{
}

static inline void
racct_proc_exit(struct proc *p)
{
}

#endif

#endif /* !_RACCT_H_ */