xref: /illumos-gate/usr/src/uts/common/sys/cap_util.h (revision b885580b)
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 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_CAP_UTIL_H
28 #define	_SYS_CAP_UTIL_H
29 
30 
31 #ifdef	__cplusplus
32 extern "C" {
33 #endif
34 
35 #include <sys/types.h>
36 #include <sys/kcpc.h>
37 #include <sys/cpc_impl.h>
38 #include <sys/pghw.h>
39 #include <sys/cmt.h>
40 
41 #ifdef	_KERNEL
42 
43 /*
44  * Capacity and utilization flags for each CPU
45  */
46 #define	CU_CPU_CNTRS_ON		1	/* CPU performance counters are on */
47 #define	CU_CPU_CNTRS_OFF_ON	2	/* Off -> on transition */
48 
49 /*
50  * Macro that returns whether CPU performance counters turned on for given CPU
51  */
52 #define	CU_CPC_ON(cp) \
53 	((cp) != NULL && (cp)->cpu_cu_info != NULL && \
54 	    ((cp)->cpu_cu_info->cu_flag & CU_CPU_CNTRS_ON))
55 
56 
57 /*
58  * Per counter statistics
59  */
60 typedef struct cu_cntr_stats {
61 	hrtime_t	cs_time_running; /* running total of time counting */
62 	hrtime_t	cs_time_stopped; /* ... time not counting */
63 	hrtime_t	cs_time_start;	/* start time of current sample  */
64 	uint64_t	cs_value_start;	/* starting value for next sample */
65 	uint64_t	cs_value_last;	/* last value */
66 	uint64_t	cs_value_total;	/* running total */
67 	uint64_t	cs_rate;	/* observed rate since last */
68 	uint64_t	cs_rate_max;	/* maximum rate */
69 	kcpc_request_t	*cs_cpc_req;	/* corresponding CPC request */
70 	struct cpu	*cs_cpu_start;	/* CPU where starting value gotten */
71 } cu_cntr_stats_t;
72 
73 
74 /*
75  * Counter info for a PG hardware sharing relationship
76  */
77 typedef struct cu_cntr_info {
78 	cpu_t		*ci_cpu;	/* CPU being measured */
79 	pghw_t		*ci_pg;		/* hardware PG being measured */
80 	kstat_t		*ci_kstat;	/* kstats being exported */
81 	cu_cntr_stats_t	*ci_stats;	/* counter statistics */
82 	uint_t		ci_nstats;	/* number of statistics */
83 } cu_cntr_info_t;
84 
85 
86 /*
87  * Each CPU can have one or more CPC contexts for measuring capacity and
88  * utilization
89  *
90  * One CPC context is needed per CPU if the counter events needed to measure
91  * capacity and utilization on each CPU can be programmed onto all the counters
92  * on a CPU at the same time and there are fewer or same number of desired
93  * counter events as counters on each CPU.  Otherwise, the desired counter
94  * events are assigned across multiple CPC contexts, so the contexts and their
95  * counter events can be multiplexed onto the counters over time to get the
96  * data for all of the counter events.
97  */
98 typedef struct cu_cpc_ctx {
99 	int		cur_index;	/* index for current context */
100 	int		nctx;		/* number of CPC contexts */
101 	kcpc_ctx_t	**ctx_ptr_array; /* array of context pointers */
102 	size_t		ctx_ptr_array_sz; /* size of array */
103 } cu_cpc_ctx_t;
104 
105 /*
106  * Per CPU capacity and utilization info
107  */
108 typedef struct cu_cpu_info {
109 	struct cpu	*cu_cpu;	/* CPU for the statistics */
110 	uint_t		cu_flag;	/* capacity & utilization flag */
111 	hrtime_t	cu_sample_time;	/* when last sample taken */
112 	cu_cpc_ctx_t	cu_cpc_ctx;	/* performance counter contexts */
113 	cu_cntr_stats_t	*cu_cntr_stats;	/* counter statistics array */
114 	uint_t		cu_ncntr_stats;	/* number of counter statistics */
115 	uint_t		cu_disabled;	/* count of disable requests */
116 	/*
117 	 * Per PG hardware sharing relationship counter info
118 	 */
119 	cu_cntr_info_t	*cu_cntr_info[PGHW_NUM_COMPONENTS];
120 } cu_cpu_info_t;
121 
122 /*
123  * COMMON INTERFACE ROUTINES
124  */
125 
126 /*
127  * Setup capacity and utilization support
128  */
129 extern void	cu_init(void);
130 
131 /*
132  * Tear down capacity and utilization support
133  */
134 extern int	cu_fini(void);
135 
136 /*
137  * Program CPC for capacity and utilization on given CPU
138  */
139 extern void	cu_cpc_program(struct cpu *, int *);
140 
141 /*
142  * Unprogram CPC for capacity and utilization on given CPU
143  */
144 extern void	cu_cpc_unprogram(struct cpu *, int *);
145 
146 /*
147  * Update counter statistics on a given CPU
148  */
149 extern int	cu_cpu_update(struct cpu *, boolean_t);
150 
151 /*
152  * Update utilization and capacity data for CMT PG
153  */
154 extern void	cu_pg_update(pghw_t *);
155 
156 /*
157  * Disable or enable capacity and utilization on all CPUs
158  */
159 extern void	cu_disable(void);
160 extern void	cu_enable(void);
161 
162 /*
163  * PLATFORM SPECIFIC INTERFACE ROUTINES
164  */
165 extern int	cu_plat_cpc_init(cpu_t *, kcpc_request_list_t *, int);
166 
167 #endif	/* _KERNEL */
168 
169 #ifdef	__cplusplus
170 }
171 #endif
172 
173 #endif /* _SYS_CAP_UTIL_H */
174