summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/cap_util.h
blob: 7e25ba669748aa05ffa380bf9294401eda94a328 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_CAP_UTIL_H
#define	_SYS_CAP_UTIL_H


#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/kcpc.h>
#include <sys/cpc_impl.h>
#include <sys/pghw.h>
#include <sys/cmt.h>

#ifdef	_KERNEL

/*
 * Capacity and utilization flags for each CPU
 */
#define	CU_CPU_CNTRS_ON		1	/* CPU performance counters are on */
#define	CU_CPU_CNTRS_OFF_ON	2	/* Off -> on transition */

/*
 * Macro that returns whether CPU performance counters turned on for given CPU
 */
#define	CU_CPC_ON(cp) \
	((cp) != NULL && (cp)->cpu_cu_info != NULL && \
	    ((cp)->cpu_cu_info->cu_flag & CU_CPU_CNTRS_ON))


/*
 * Per counter statistics
 */
typedef struct cu_cntr_stats {
	hrtime_t	cs_time_running; /* running total of time counting */
	hrtime_t	cs_time_stopped; /* ... time not counting */
	hrtime_t	cs_time_start;	/* start time of current sample  */
	uint64_t	cs_value_start;	/* starting value for next sample */
	uint64_t	cs_value_last;	/* last value */
	uint64_t	cs_value_total;	/* running total */
	uint64_t	cs_rate;	/* observed rate since last */
	uint64_t	cs_rate_max;	/* maximum rate */
	kcpc_request_t	*cs_cpc_req;	/* corresponding CPC request */
	struct cpu	*cs_cpu_start;	/* CPU where starting value gotten */
} cu_cntr_stats_t;


/*
 * Counter info for a PG hardware sharing relationship
 */
typedef struct cu_cntr_info {
	cpu_t		*ci_cpu;	/* CPU being measured */
	pghw_t		*ci_pg;		/* hardware PG being measured */
	kstat_t		*ci_kstat;	/* kstats being exported */
	cu_cntr_stats_t	*ci_stats;	/* counter statistics */
	uint_t		ci_nstats;	/* number of statistics */
} cu_cntr_info_t;


/*
 * Each CPU can have one or more CPC contexts for measuring capacity and
 * utilization
 *
 * One CPC context is needed per CPU if the counter events needed to measure
 * capacity and utilization on each CPU can be programmed onto all the counters
 * on a CPU at the same time and there are fewer or same number of desired
 * counter events as counters on each CPU.  Otherwise, the desired counter
 * events are assigned across multiple CPC contexts, so the contexts and their
 * counter events can be multiplexed onto the counters over time to get the
 * data for all of the counter events.
 */
typedef struct cu_cpc_ctx {
	int		cur_index;	/* index for current context */
	int		nctx;		/* number of CPC contexts */
	kcpc_ctx_t	**ctx_ptr_array; /* array of context pointers */
	size_t		ctx_ptr_array_sz; /* size of array */
} cu_cpc_ctx_t;

/*
 * Per CPU capacity and utilization info
 */
typedef struct cu_cpu_info {
	struct cpu	*cu_cpu;	/* CPU for the statistics */
	uint_t		cu_flag;	/* capacity & utilization flag */
	hrtime_t	cu_sample_time;	/* when last sample taken */
	cu_cpc_ctx_t	cu_cpc_ctx;	/* performance counter contexts */
	cu_cntr_stats_t	*cu_cntr_stats;	/* counter statistics array */
	uint_t		cu_ncntr_stats;	/* number of counter statistics */
	uint_t		cu_disabled;	/* count of disable requests */
	/*
	 * Per PG hardware sharing relationship counter info
	 */
	cu_cntr_info_t	*cu_cntr_info[PGHW_NUM_COMPONENTS];
} cu_cpu_info_t;

/*
 * COMMON INTERFACE ROUTINES
 */

/*
 * Setup capacity and utilization support
 */
extern void	cu_init(void);

/*
 * Tear down capacity and utilization support
 */
extern int	cu_fini(void);

/*
 * Program CPC for capacity and utilization on given CPU
 */
extern void	cu_cpc_program(struct cpu *, int *);

/*
 * Unprogram CPC for capacity and utilization on given CPU
 */
extern void	cu_cpc_unprogram(struct cpu *, int *);

/*
 * Update counter statistics on a given CPU
 */
extern int	cu_cpu_update(struct cpu *, boolean_t);

/*
 * Update utilization and capacity data for CMT PG
 */
extern void	cu_pg_update(pghw_t *);

/*
 * Disable or enable capacity and utilization on all CPUs
 */
extern void	cu_disable(void);
extern void	cu_enable(void);

/*
 * PLATFORM SPECIFIC INTERFACE ROUTINES
 */
extern int	cu_plat_cpc_init(cpu_t *, kcpc_request_list_t *, int);

#endif	/* _KERNEL */

#ifdef	__cplusplus
}
#endif

#endif /* _SYS_CAP_UTIL_H */