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