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
33extern "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 */
60extern 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 */
68extern void cpucaps_init(void);
69
70/*
71 * Notify caps framework of a new project coming in or existing project
72 * going away
73 */
74extern void cpucaps_project_add(kproject_t *);
75extern void cpucaps_project_remove(kproject_t *);
76
77/*
78 * Notify caps framework when a zone is going away.
79 */
80extern void cpucaps_zone_remove(zone_t *);
81
82/*
83 * Set project/zone cap to specified value. Value of MAXCAP should disable caps.
84 */
85extern int cpucaps_project_set(kproject_t *, rctl_qty_t);
86extern int cpucaps_zone_set(zone_t *, rctl_qty_t);
87
88/*
89 * Get current CPU usage for a project/zone.
90 */
91extern rctl_qty_t cpucaps_project_get(kproject_t *);
92extern 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 */
110typedef struct caps_sc {
111	hrtime_t	csc_cputime;
112} caps_sc_t;
113
114/*
115 * Initialize per-thread cpu-caps specific data.
116 */
117extern 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 */
127typedef 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 */
136extern 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 */
143extern 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 */
149extern void (*cpucaps_clock_callout)(void);
150
151#endif	/* _KERNEL */
152
153#ifdef	__cplusplus
154}
155#endif
156
157#endif	/* _SYS_CPUCAPS_H */
158