xref: /titanic_44/usr/src/uts/common/sys/cpc_impl.h (revision 2b24ab6b3865caeede9eeb9db6b83e1d89dcd1ea)
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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_SYS_CPC_IMPL_H
27 #define	_SYS_CPC_IMPL_H
28 
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/ksynch.h>
32 
33 #if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
34 #include <sys/types32.h>
35 #endif
36 
37 #ifdef	__cplusplus
38 extern "C" {
39 #endif
40 
41 typedef struct {
42 	char		*ca_name;
43 	uint64_t	ca_val;
44 } cpc_attr_t;
45 
46 /*
47  * Flag arguments to cpc_bind_event and cpc_ctx_bind_event
48  */
49 #define	CPC_BIND_LWP_INHERIT	(0x1)
50 #define	CPC_BIND_EMT_OVF	(0x2)
51 
52 #define	CPC_MAX_IMPL_NAME	512	/* Max len of PCBE's description str */
53 #define	CPC_MAX_CPUREF		1024	/* Max len of PCBE's CPU ref string */
54 
55 #define	CPC_OVF_NOTIFY_EMT	0x1
56 #define	CPC_COUNT_USER		0x2
57 #define	CPC_COUNT_SYSTEM	0x4
58 #define	CPC_COUNT_HV		0x8
59 
60 #define	KCPC_REQ_ALL_FLAGS	(CPC_OVF_NOTIFY_EMT | CPC_COUNT_USER | \
61 		CPC_COUNT_SYSTEM | CPC_COUNT_HV)
62 #define	KCPC_REQ_VALID_FLAGS(flags) \
63 		(((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS)
64 
65 /*
66  * CPC Capabilities
67  */
68 #define	CPC_CAP_OVERFLOW_INTERRUPT	0x1
69 #define	CPC_CAP_OVERFLOW_PRECISE	0x2
70 
71 /*
72  * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in
73  * cpc_event.h for backwards compatibility.
74  */
75 #define	CPC_SET_ALL_FLAGS	0x1
76 #define	CPC_SET_VALID_FLAGS(flags) \
77 		(((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS)
78 
79 /*
80  * These system call subcodes and ioctls allow the implementation of the
81  * libcpc library to store and retrieve performance counter data.  Subject
82  * to arbitrary change without notice at any time.  Do not invoke them
83  * directly!
84  */
85 #define	CPC_BIND		0
86 #define	CPC_SAMPLE		1
87 #define	CPC_INVALIDATE		2
88 #define	CPC_RELE		3
89 #define	CPC_EVLIST_SIZE		4
90 #define	CPC_LIST_EVENTS		5
91 #define	CPC_ATTRLIST_SIZE	6
92 #define	CPC_LIST_ATTRS		7
93 #define	CPC_IMPL_NAME		8
94 #define	CPC_CPUREF		9
95 #define	CPC_USR_EVENTS		10
96 #define	CPC_SYS_EVENTS		11
97 #define	CPC_NPIC		12
98 #define	CPC_CAPS		13
99 #define	CPC_ENABLE		14
100 #define	CPC_DISABLE		15
101 #define	CPC_PRESET		16
102 #define	CPC_RESTART		17
103 
104 #define	_CPCIO_IOC	((((('c'<<8)|'p')<<8)|'c')<<8)
105 
106 #define	CPCIO_BIND			(_CPCIO_IOC | 0x1)
107 #define	CPCIO_SAMPLE			(_CPCIO_IOC | 0x2)
108 #define	CPCIO_RELE			(_CPCIO_IOC | 0x3)
109 
110 /*
111  * Forward declarations.
112  */
113 struct _kthread;
114 struct _kcpc_set;
115 
116 #define	CPC_MAX_EVENT_LEN	512
117 #define	CPC_MAX_ATTR_LEN	32
118 
119 typedef struct _kcpc_attr {
120 	char		ka_name[CPC_MAX_ATTR_LEN];
121 	uint64_t	ka_val;
122 } kcpc_attr_t;
123 
124 typedef struct _kcpc_pic {
125 	uint_t			kp_flags;
126 	struct _kcpc_request	*kp_req;   /* request this PIC counts for */
127 } kcpc_pic_t;
128 
129 typedef struct _kcpc_ctx kcpc_ctx_t;
130 
131 struct _kcpc_ctx {
132 	struct _kcpc_set *kc_set;	/* linked list of all bound sets */
133 	uint32_t	kc_flags;
134 	kcpc_pic_t	*kc_pics;	/* pointer to array of per-pic data */
135 	hrtime_t	kc_hrtime;	/* gethrtime() at last sample */
136 	uint64_t	kc_vtick;	/* virtualized %tick */
137 	uint64_t	kc_rawtick;	/* last snapshot of tick/tsc */
138 	struct _kthread	*kc_thread;	/* thread this context is measuring */
139 	int		kc_cpuid;	/* CPU this context is measuring */
140 	kcpc_ctx_t	*kc_next;	/* Global list of all contexts */
141 	kmutex_t	kc_lock;	/* protects kc_flags */
142 	kcondvar_t	kc_condv;	/* wait for kcpc_restore completion */
143 };
144 
145 typedef struct __cpc_args {
146 	void *udata1;
147 	void *udata2;
148 	void *udata3;
149 } __cpc_args_t;
150 
151 #ifdef _KERNEL
152 
153 #ifdef _MULTI_DATAMODEL
154 typedef struct __cpc_args32 {
155 	caddr32_t udata1;
156 	caddr32_t udata2;
157 	caddr32_t udata3;
158 } __cpc_args32_t;
159 #endif /* _MULTI_DATAMODEL */
160 
161 #define	KCPC_LOG2_HASH_BUCKETS	6	/* => 64 buckets for now */
162 #define	CPC_HASH_BUCKETS		(1l << KCPC_LOG2_HASH_BUCKETS)
163 #define	CPC_HASH_CTX(ctx)		((((long)(ctx)) >> 7) &		       \
164 						(CPC_HASH_BUCKETS - 1))
165 
166 /*
167  * Context flags.
168  */
169 #define	KCPC_CTX_FREEZE		0x1	/* => no sampling */
170 #define	KCPC_CTX_SIGOVF		0x2	/* => send signal on overflow */
171 #define	KCPC_CTX_NONPRIV	0x4	/* => non-priv access to counters */
172 #define	KCPC_CTX_LWPINHERIT	0x8	/* => lwp_create inherits ctx */
173 #define	KCPC_CTX_INVALID	0x100	/* => context stolen; discard */
174 #define	KCPC_CTX_INVALID_STOPPED 0x200	/* => invalid ctx has been stopped */
175 #define	KCPC_CTX_RESTORE	0x400	/* => kcpc_restore in progress */
176 
177 /*
178  * PIC flags.
179  */
180 #define	KCPC_PIC_OVERFLOWED	0x1	/* pic overflowed & requested notify */
181 
182 /*
183  * The following flags are used by the DTrace CPU performance counter provider
184  * and the overflow handler. The 'DCPC_INTR_*' flags are used to synchronize
185  * performance counter configuration events performed by the cpc provider and
186  * interrupt processing carried out by the overflow handler.  The 'DCPC_?MASK'
187  * flags are used by the dcpc provider to indicate which type of mask attribute
188  * a platform supports.
189  */
190 
191 /* No configuration events or overflow interrupts are currently in process. */
192 #define	DCPC_INTR_FREE 0
193 
194 /* An overflow interrupt is currently being processed. */
195 #define	DCPC_INTR_PROCESSING 1
196 
197 /* The cpc subsystem is currently being configured by the dcpc provider. */
198 #define	DCPC_INTR_CONFIG 2
199 
200 #define	DCPC_UMASK 1	/* The platform supports a "umask" attribute. */
201 #define	DCPC_EMASK 2	/* The platform supports an "emask" attribute. */
202 
203 #ifdef __sparc
204 extern uint64_t ultra_gettick(void);
205 #define	KCPC_GET_TICK ultra_gettick
206 #else
207 extern hrtime_t tsc_read(void);
208 #define	KCPC_GET_TICK tsc_read
209 #endif /* __sparc */
210 
211 #define	PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */
212 
213 struct cpu;
214 
215 extern uint_t cpc_ncounters;
216 extern kmutex_t	kcpc_ctx_llock[];	/* protects ctx_list */
217 extern kcpc_ctx_t *kcpc_ctx_list[];	/* head of list */
218 extern krwlock_t kcpc_cpuctx_lock;	/* lock for 'kcpc_cpuctx' below */
219 extern int	kcpc_cpuctx;		/* number of cpu-specific contexts */
220 
221 extern void kcpc_invalidate_all(void);
222 
223 extern void kcpc_passivate(void);
224 extern void kcpc_remote_stop(struct cpu *cp);
225 extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t);
226 extern void kcpc_remote_program(struct cpu *cp);
227 extern void kcpc_register_dcpc(void (*func)(uint64_t));
228 extern void kcpc_unregister_dcpc(void);
229 extern kcpc_ctx_t *kcpc_ctx_alloc(void);
230 extern int kcpc_assign_reqs(struct _kcpc_set *, kcpc_ctx_t *);
231 extern void kcpc_ctx_free(kcpc_ctx_t *);
232 extern int kcpc_configure_reqs(kcpc_ctx_t *, struct _kcpc_set *, int *);
233 extern void kcpc_free_configs(struct _kcpc_set *);
234 
235 #endif /* _KERNEL */
236 
237 /*
238  * Error subcodes.
239  */
240 #define	CPC_INVALID_EVENT		1	/* Unknown event */
241 #define	CPC_INVALID_PICNUM		2	/* Requested PIC out of range */
242 #define	CPC_INVALID_ATTRIBUTE		3	/* Unknown attribute */
243 #define	CPC_ATTRIBUTE_OUT_OF_RANGE	4	/* Attribute val out of range */
244 #define	CPC_RESOURCE_UNAVAIL		5	/* Can't get needed resource */
245 #define	CPC_PIC_NOT_CAPABLE		6	/* PIC can't count this event */
246 #define	CPC_REQ_INVALID_FLAGS		7	/* Invalid flags in req(s) */
247 #define	CPC_CONFLICTING_REQS		8	/* Reqs in the set conflict */
248 #define	CPC_ATTR_REQUIRES_PRIVILEGE	9	/* Insufficient privs for atr */
249 #define	CPC_PBIND_FAILED		10	/* Couldn't bind to processor */
250 #define	CPC_HV_NO_ACCESS		11	/* No perm for HV events */
251 
252 #ifdef	__cplusplus
253 }
254 #endif
255 
256 #endif	/* _SYS_CPC_IMPL_H */
257