xref: /illumos-gate/usr/src/uts/common/sys/cpc_impl.h (revision 40cb5e5daa7b80bb70fcf8dadfb20f9281566331)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_CPC_IMPL_H
28 #define	_SYS_CPC_IMPL_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/types.h>
33 #include <sys/time.h>
34 #include <sys/rwlock.h>
35 
36 #if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
37 #include <sys/types32.h>
38 #endif
39 
40 #ifdef	__cplusplus
41 extern "C" {
42 #endif
43 
44 typedef struct {
45 	char		*ca_name;
46 	uint64_t	ca_val;
47 } cpc_attr_t;
48 
49 /*
50  * Flag arguments to cpc_bind_event and cpc_ctx_bind_event
51  */
52 #define	CPC_BIND_LWP_INHERIT	(0x1)
53 #define	CPC_BIND_EMT_OVF	(0x2)
54 
55 #define	CPC_MAX_IMPL_NAME	512	/* Max len of PCBE's description str */
56 #define	CPC_MAX_CPUREF		1024	/* Max len of PCBE's CPU ref string */
57 
58 #define	CPC_OVF_NOTIFY_EMT	0x1
59 #define	CPC_COUNT_USER		0x2
60 #define	CPC_COUNT_SYSTEM	0x4
61 
62 #define	KCPC_REQ_ALL_FLAGS	0x7
63 #define	KCPC_REQ_VALID_FLAGS(flags) \
64 		(((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS)
65 
66 /*
67  * CPC Capabilities
68  */
69 #define	CPC_CAP_OVERFLOW_INTERRUPT	0x1
70 #define	CPC_CAP_OVERFLOW_PRECISE	0x2
71 
72 /*
73  * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in
74  * cpc_event.h for backwards compatibility.
75  */
76 #define	CPC_SET_ALL_FLAGS	0x1
77 #define	CPC_SET_VALID_FLAGS(flags) \
78 		(((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS)
79 
80 /*
81  * These system call subcodes and ioctls allow the implementation of the
82  * libcpc library to store and retrieve performance counter data.  Subject
83  * to arbitrary change without notice at any time.  Do not invoke them
84  * directly!
85  */
86 #define	CPC_BIND		0
87 #define	CPC_SAMPLE		1
88 #define	CPC_INVALIDATE		2
89 #define	CPC_RELE		3
90 #define	CPC_EVLIST_SIZE		4
91 #define	CPC_LIST_EVENTS		5
92 #define	CPC_ATTRLIST_SIZE	6
93 #define	CPC_LIST_ATTRS		7
94 #define	CPC_IMPL_NAME		8
95 #define	CPC_CPUREF		9
96 #define	CPC_USR_EVENTS		10
97 #define	CPC_SYS_EVENTS		11
98 #define	CPC_NPIC		12
99 #define	CPC_CAPS		13
100 #define	CPC_ENABLE		14
101 #define	CPC_DISABLE		15
102 #define	CPC_PRESET		16
103 #define	CPC_RESTART		17
104 
105 #define	_CPCIO_IOC	((((('c'<<8)|'p')<<8)|'c')<<8)
106 
107 #define	CPCIO_BIND			(_CPCIO_IOC | 0x1)
108 #define	CPCIO_SAMPLE			(_CPCIO_IOC | 0x2)
109 #define	CPCIO_RELE			(_CPCIO_IOC | 0x3)
110 
111 /*
112  * Forward declarations.
113  */
114 struct _kthread;
115 struct _kcpc_set;
116 
117 #define	CPC_MAX_EVENT_LEN	512
118 #define	CPC_MAX_ATTR_LEN	32
119 
120 typedef struct _kcpc_attr {
121 	char		ka_name[CPC_MAX_ATTR_LEN];
122 	uint64_t	ka_val;
123 } kcpc_attr_t;
124 
125 typedef struct _kcpc_pic {
126 	uint_t			kp_flags;
127 	struct _kcpc_request	*kp_req;   /* request this PIC counts for */
128 } kcpc_pic_t;
129 
130 typedef struct _kcpc_ctx kcpc_ctx_t;
131 
132 struct _kcpc_ctx {
133 	struct _kcpc_set *kc_set;	/* linked list of all bound sets */
134 	uint32_t	kc_flags;
135 	kcpc_pic_t	*kc_pics;	/* pointer to array of per-pic data */
136 	hrtime_t	kc_hrtime;	/* gethrtime() at last sample */
137 	uint64_t	kc_vtick;	/* virtualized %tick */
138 	uint64_t	kc_rawtick;	/* last snapshot of tick/tsc */
139 	struct _kthread	*kc_thread;	/* thread this context is measuring */
140 	int		kc_cpuid;	/* CPU this context is measuring */
141 	kcpc_ctx_t	*kc_next;	/* Global list of all contexts */
142 };
143 
144 typedef struct __cpc_args {
145 	void *udata1;
146 	void *udata2;
147 	void *udata3;
148 } __cpc_args_t;
149 
150 #ifdef _KERNEL
151 
152 #ifdef _MULTI_DATAMODEL
153 typedef struct __cpc_args32 {
154 	caddr32_t udata1;
155 	caddr32_t udata2;
156 	caddr32_t udata3;
157 } __cpc_args32_t;
158 #endif /* _MULTI_DATAMODEL */
159 
160 #define	KCPC_LOG2_HASH_BUCKETS	6	/* => 64 buckets for now */
161 #define	CPC_HASH_BUCKETS		(1l << KCPC_LOG2_HASH_BUCKETS)
162 #define	CPC_HASH_CTX(ctx)		((((long)(ctx)) >> 7) &		       \
163 						(CPC_HASH_BUCKETS - 1))
164 
165 /*
166  * Context flags.
167  */
168 #define	KCPC_CTX_FREEZE		0x1	/* => no sampling */
169 #define	KCPC_CTX_SIGOVF		0x2	/* => send signal on overflow */
170 #define	KCPC_CTX_NONPRIV	0x4	/* => non-priv access to counters */
171 #define	KCPC_CTX_LWPINHERIT	0x8	/* => lwp_create inherits ctx */
172 #define	KCPC_CTX_INVALID	0x100	/* => context stolen; discard */
173 #define	KCPC_CTX_INVALID_STOPPED 0x200	/* => invalid ctx has been stopped */
174 
175 /*
176  * PIC flags.
177  */
178 #define	KCPC_PIC_OVERFLOWED	0x1	/* pic overflowed & requested notify */
179 
180 #ifdef __sparc
181 extern uint64_t ultra_gettick(void);
182 #define	KCPC_GET_TICK ultra_gettick
183 #else
184 extern hrtime_t tsc_read(void);
185 #define	KCPC_GET_TICK tsc_read
186 #endif /* __sparc */
187 
188 #define	PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */
189 
190 struct cpu;
191 
192 extern uint_t cpc_ncounters;
193 extern kmutex_t	kcpc_ctx_llock[];	/* protects ctx_list */
194 extern kcpc_ctx_t *kcpc_ctx_list[];	/* head of list */
195 extern krwlock_t kcpc_cpuctx_lock;	/* lock for 'kcpc_cpuctx' below */
196 extern int	kcpc_cpuctx;		/* number of cpu-specific contexts */
197 
198 extern void kcpc_invalidate_all(void);
199 
200 extern void kcpc_passivate(void);
201 extern void kcpc_remote_stop(struct cpu *cp);
202 extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t);
203 
204 #endif /* _KERNEL */
205 
206 /*
207  * Error subcodes.
208  */
209 #define	CPC_INVALID_EVENT		1	/* Unknown event */
210 #define	CPC_INVALID_PICNUM		2	/* Requested PIC out of range */
211 #define	CPC_INVALID_ATTRIBUTE		3	/* Unknown attribute */
212 #define	CPC_ATTRIBUTE_OUT_OF_RANGE	4	/* Attribute val out of range */
213 #define	CPC_RESOURCE_UNAVAIL		5	/* Can't get needed resource */
214 #define	CPC_PIC_NOT_CAPABLE		6	/* PIC can't count this event */
215 #define	CPC_REQ_INVALID_FLAGS		7	/* Invalid flags in req(s) */
216 #define	CPC_CONFLICTING_REQS		8	/* Reqs in the set conflict */
217 #define	CPC_ATTR_REQUIRES_PRIVILEGE	9	/* Insufficient privs for atr */
218 #define	CPC_PBIND_FAILED		10	/* Couldn't bind to processor */
219 
220 #ifdef	__cplusplus
221 }
222 #endif
223 
224 #endif	/* _SYS_CPC_IMPL_H */
225