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