xref: /illumos-gate/usr/src/uts/common/sys/cpucaps.h (revision a0955b86cd77e22e80846428a5065e871b6d8eb8)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_CPUCAPS_H
28 #define	_SYS_CPUCAPS_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #include <sys/types.h>
37 #include <sys/zone.h>
38 #include <sys/project.h>
39 #include <sys/time.h>
40 #include <sys/rctl.h>
41 
42 /*
43  * CPU caps provide an absolute hard CPU usage limit which is enforced even if
44  * some CPUs are idle. It can be enforced at project or zone level.
45  */
46 
47 #ifdef _KERNEL
48 
49 /*
50  * Valid caps values go from 1 to MAXCAP - 1. Specifying the MAXCAP as the cap
51  * value is equivalent to disabling the cap.
52  */
53 #define	MAXCAP		UINT_MAX
54 
55 /*
56  * cpucaps_enabled is used to quickly check whether any CPU caps specific code
57  * should be invoked. Users outside CPU Caps framework should use CPUCAPS_ON()
58  * and CPUCAPS_OFF() macros.
59  */
60 extern boolean_t cpucaps_enabled;
61 
62 #define	CPUCAPS_ON()	cpucaps_enabled
63 #define	CPUCAPS_OFF()	(!cpucaps_enabled)
64 
65 /*
66  * Initialize the CPU caps framework.
67  */
68 extern void cpucaps_init(void);
69 
70 /*
71  * Notify caps framework of a new project coming in or existing project
72  * going away
73  */
74 extern void cpucaps_project_add(kproject_t *);
75 extern void cpucaps_project_remove(kproject_t *);
76 
77 /*
78  * Notify caps framework when a zone is going away.
79  */
80 extern void cpucaps_zone_remove(zone_t *);
81 
82 /*
83  * Set project/zone cap to specified value. Value of MAXCAP should disable caps.
84  */
85 extern int cpucaps_project_set(kproject_t *, rctl_qty_t);
86 extern int cpucaps_zone_set(zone_t *, rctl_qty_t);
87 
88 /*
89  * Get current CPU usage for a project/zone.
90  */
91 extern rctl_qty_t cpucaps_project_get(kproject_t *);
92 extern rctl_qty_t cpucaps_zone_get(zone_t *);
93 
94 /*
95  * Scheduling class hooks into CPU caps framework.
96  */
97 
98 /*
99  * CPU caps specific data for each scheduling class.
100  *
101  * There is a small amount of accounting data that should be kept by each
102  * scheduling class for each thread which is only used by CPU caps code. This
103  * data is kept in the caps_sc structure which is transparent for all scheduling
104  * classes. The fields in the structure are:
105  *
106  *     csc_cputime -  Total time spent on CPU during thread lifetime, obtained
107  *                    as the sum of user, system and trap time, reported by
108  *                    microstate accounting.
109  */
110 typedef struct caps_sc {
111 	hrtime_t	csc_cputime;
112 } caps_sc_t;
113 
114 /*
115  * Initialize per-thread cpu-caps specific data.
116  */
117 extern void cpucaps_sc_init(caps_sc_t *);
118 
119 /*
120  * Modus operandi for cpucaps_charge() function.
121  *
122  *   CPUCAPS_CHARGE_ENFORCE - charge a thread for its CPU time and
123  *				flag it to be placed on wait queue.
124  *
125  *   CPUCAPS_CHARGE_ONLY    - charge a thread for its CPU time.
126  */
127 typedef enum {
128 	CPUCAPS_CHARGE_ENFORCE,
129 	CPUCAPS_CHARGE_ONLY
130 } cpucaps_charge_t;
131 
132 /*
133  * Add accumulated CPU usage of a thread to its cap.
134  * Return True if thread should be placed on waitq.
135  */
136 extern boolean_t cpucaps_charge(kthread_t *, caps_sc_t *, cpucaps_charge_t);
137 #define	CPUCAPS_CHARGE(t, scp, flag) \
138 	(CPUCAPS_ON() && cpucaps_charge(t, scp, flag))
139 
140 /*
141  * Request a thread to be placed on a wait queue because the cap is exceeded
142  */
143 extern boolean_t cpucaps_enforce(kthread_t *);
144 #define	CPUCAPS_ENFORCE(t) (CPUCAPS_ON() && cpucaps_enforce(t))
145 
146 /*
147  * CPU Caps hook into clock().
148  */
149 extern void (*cpucaps_clock_callout)(void);
150 
151 #endif	/* _KERNEL */
152 
153 #ifdef	__cplusplus
154 }
155 #endif
156 
157 #endif	/* _SYS_CPUCAPS_H */
158