xref: /illumos-gate/usr/src/uts/common/sys/cpc_impl.h (revision af4595ed)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
58d4e547dSae112802  * Common Development and Distribution License (the "License").
68d4e547dSae112802  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*af4595edSJonathan Haslam  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_CPC_IMPL_H
277c478bd9Sstevel@tonic-gate #define	_SYS_CPC_IMPL_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/time.h>
314568bee7Strevtom #include <sys/ksynch.h>
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
347c478bd9Sstevel@tonic-gate #include <sys/types32.h>
357c478bd9Sstevel@tonic-gate #endif
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
387c478bd9Sstevel@tonic-gate extern "C" {
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate typedef struct {
427c478bd9Sstevel@tonic-gate 	char		*ca_name;
437c478bd9Sstevel@tonic-gate 	uint64_t	ca_val;
447c478bd9Sstevel@tonic-gate } cpc_attr_t;
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate  * Flag arguments to cpc_bind_event and cpc_ctx_bind_event
487c478bd9Sstevel@tonic-gate  */
497c478bd9Sstevel@tonic-gate #define	CPC_BIND_LWP_INHERIT	(0x1)
507c478bd9Sstevel@tonic-gate #define	CPC_BIND_EMT_OVF	(0x2)
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define	CPC_MAX_IMPL_NAME	512	/* Max len of PCBE's description str */
537c478bd9Sstevel@tonic-gate #define	CPC_MAX_CPUREF		1024	/* Max len of PCBE's CPU ref string */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate #define	CPC_OVF_NOTIFY_EMT	0x1
567c478bd9Sstevel@tonic-gate #define	CPC_COUNT_USER		0x2
577c478bd9Sstevel@tonic-gate #define	CPC_COUNT_SYSTEM	0x4
588d4e547dSae112802 #define	CPC_COUNT_HV		0x8
594df55fdeSJanie Lu #define	CPC_COUNT_SAMPLE_MODE	0x10
607c478bd9Sstevel@tonic-gate 
618d4e547dSae112802 #define	KCPC_REQ_ALL_FLAGS	(CPC_OVF_NOTIFY_EMT | CPC_COUNT_USER | \
624df55fdeSJanie Lu 		CPC_COUNT_SYSTEM | CPC_COUNT_HV | CPC_COUNT_SAMPLE_MODE)
637c478bd9Sstevel@tonic-gate #define	KCPC_REQ_VALID_FLAGS(flags) \
647c478bd9Sstevel@tonic-gate 		(((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS)
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
677c478bd9Sstevel@tonic-gate  * CPC Capabilities
687c478bd9Sstevel@tonic-gate  */
697c478bd9Sstevel@tonic-gate #define	CPC_CAP_OVERFLOW_INTERRUPT	0x1
707c478bd9Sstevel@tonic-gate #define	CPC_CAP_OVERFLOW_PRECISE	0x2
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate /*
737c478bd9Sstevel@tonic-gate  * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in
747c478bd9Sstevel@tonic-gate  * cpc_event.h for backwards compatibility.
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate #define	CPC_SET_ALL_FLAGS	0x1
777c478bd9Sstevel@tonic-gate #define	CPC_SET_VALID_FLAGS(flags) \
787c478bd9Sstevel@tonic-gate 		(((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS)
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate  * These system call subcodes and ioctls allow the implementation of the
827c478bd9Sstevel@tonic-gate  * libcpc library to store and retrieve performance counter data.  Subject
837c478bd9Sstevel@tonic-gate  * to arbitrary change without notice at any time.  Do not invoke them
847c478bd9Sstevel@tonic-gate  * directly!
857c478bd9Sstevel@tonic-gate  */
867c478bd9Sstevel@tonic-gate #define	CPC_BIND		0
877c478bd9Sstevel@tonic-gate #define	CPC_SAMPLE		1
887c478bd9Sstevel@tonic-gate #define	CPC_INVALIDATE		2
897c478bd9Sstevel@tonic-gate #define	CPC_RELE		3
907c478bd9Sstevel@tonic-gate #define	CPC_EVLIST_SIZE		4
917c478bd9Sstevel@tonic-gate #define	CPC_LIST_EVENTS		5
927c478bd9Sstevel@tonic-gate #define	CPC_ATTRLIST_SIZE	6
937c478bd9Sstevel@tonic-gate #define	CPC_LIST_ATTRS		7
947c478bd9Sstevel@tonic-gate #define	CPC_IMPL_NAME		8
957c478bd9Sstevel@tonic-gate #define	CPC_CPUREF		9
967c478bd9Sstevel@tonic-gate #define	CPC_USR_EVENTS		10
977c478bd9Sstevel@tonic-gate #define	CPC_SYS_EVENTS		11
987c478bd9Sstevel@tonic-gate #define	CPC_NPIC		12
997c478bd9Sstevel@tonic-gate #define	CPC_CAPS		13
1007c478bd9Sstevel@tonic-gate #define	CPC_ENABLE		14
1017c478bd9Sstevel@tonic-gate #define	CPC_DISABLE		15
1027c478bd9Sstevel@tonic-gate #define	CPC_PRESET		16
1037c478bd9Sstevel@tonic-gate #define	CPC_RESTART		17
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate #define	_CPCIO_IOC	((((('c'<<8)|'p')<<8)|'c')<<8)
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate #define	CPCIO_BIND			(_CPCIO_IOC | 0x1)
1087c478bd9Sstevel@tonic-gate #define	CPCIO_SAMPLE			(_CPCIO_IOC | 0x2)
1097c478bd9Sstevel@tonic-gate #define	CPCIO_RELE			(_CPCIO_IOC | 0x3)
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate /*
1127c478bd9Sstevel@tonic-gate  * Forward declarations.
1137c478bd9Sstevel@tonic-gate  */
1147c478bd9Sstevel@tonic-gate struct _kthread;
1157c478bd9Sstevel@tonic-gate struct _kcpc_set;
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate #define	CPC_MAX_EVENT_LEN	512
1187c478bd9Sstevel@tonic-gate #define	CPC_MAX_ATTR_LEN	32
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate typedef struct _kcpc_attr {
1217c478bd9Sstevel@tonic-gate 	char		ka_name[CPC_MAX_ATTR_LEN];
1227c478bd9Sstevel@tonic-gate 	uint64_t	ka_val;
1237c478bd9Sstevel@tonic-gate } kcpc_attr_t;
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate typedef struct _kcpc_pic {
1267c478bd9Sstevel@tonic-gate 	uint_t			kp_flags;
1277c478bd9Sstevel@tonic-gate 	struct _kcpc_request	*kp_req;   /* request this PIC counts for */
1287c478bd9Sstevel@tonic-gate } kcpc_pic_t;
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate typedef struct _kcpc_ctx kcpc_ctx_t;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate struct _kcpc_ctx {
1337c478bd9Sstevel@tonic-gate 	struct _kcpc_set *kc_set;	/* linked list of all bound sets */
134b885580bSAlexander Kolbasov 	volatile uint_t	kc_flags;
1357c478bd9Sstevel@tonic-gate 	kcpc_pic_t	*kc_pics;	/* pointer to array of per-pic data */
1367c478bd9Sstevel@tonic-gate 	hrtime_t	kc_hrtime;	/* gethrtime() at last sample */
1377c478bd9Sstevel@tonic-gate 	uint64_t	kc_vtick;	/* virtualized %tick */
1387c478bd9Sstevel@tonic-gate 	uint64_t	kc_rawtick;	/* last snapshot of tick/tsc */
1397c478bd9Sstevel@tonic-gate 	struct _kthread	*kc_thread;	/* thread this context is measuring */
1407c478bd9Sstevel@tonic-gate 	int		kc_cpuid;	/* CPU this context is measuring */
1417c478bd9Sstevel@tonic-gate 	kcpc_ctx_t	*kc_next;	/* Global list of all contexts */
1424568bee7Strevtom 	kmutex_t	kc_lock;	/* protects kc_flags */
1434568bee7Strevtom 	kcondvar_t	kc_condv;	/* wait for kcpc_restore completion */
1447c478bd9Sstevel@tonic-gate };
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate typedef struct __cpc_args {
1477c478bd9Sstevel@tonic-gate 	void *udata1;
1487c478bd9Sstevel@tonic-gate 	void *udata2;
1497c478bd9Sstevel@tonic-gate 	void *udata3;
1507c478bd9Sstevel@tonic-gate } __cpc_args_t;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate #ifdef _KERNEL
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate #ifdef _MULTI_DATAMODEL
1557c478bd9Sstevel@tonic-gate typedef struct __cpc_args32 {
1567c478bd9Sstevel@tonic-gate 	caddr32_t udata1;
1577c478bd9Sstevel@tonic-gate 	caddr32_t udata2;
1587c478bd9Sstevel@tonic-gate 	caddr32_t udata3;
1597c478bd9Sstevel@tonic-gate } __cpc_args32_t;
1607c478bd9Sstevel@tonic-gate #endif /* _MULTI_DATAMODEL */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate #define	KCPC_LOG2_HASH_BUCKETS	6	/* => 64 buckets for now */
1637c478bd9Sstevel@tonic-gate #define	CPC_HASH_BUCKETS		(1l << KCPC_LOG2_HASH_BUCKETS)
1647c478bd9Sstevel@tonic-gate #define	CPC_HASH_CTX(ctx)		((((long)(ctx)) >> 7) &		       \
1657c478bd9Sstevel@tonic-gate 						(CPC_HASH_BUCKETS - 1))
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate /*
1687c478bd9Sstevel@tonic-gate  * Context flags.
1697c478bd9Sstevel@tonic-gate  */
1707c478bd9Sstevel@tonic-gate #define	KCPC_CTX_FREEZE		0x1	/* => no sampling */
1717c478bd9Sstevel@tonic-gate #define	KCPC_CTX_SIGOVF		0x2	/* => send signal on overflow */
1727c478bd9Sstevel@tonic-gate #define	KCPC_CTX_NONPRIV	0x4	/* => non-priv access to counters */
1737c478bd9Sstevel@tonic-gate #define	KCPC_CTX_LWPINHERIT	0x8	/* => lwp_create inherits ctx */
1747c478bd9Sstevel@tonic-gate #define	KCPC_CTX_INVALID	0x100	/* => context stolen; discard */
1757c478bd9Sstevel@tonic-gate #define	KCPC_CTX_INVALID_STOPPED 0x200	/* => invalid ctx has been stopped */
1764568bee7Strevtom #define	KCPC_CTX_RESTORE	0x400	/* => kcpc_restore in progress */
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate /*
1797c478bd9Sstevel@tonic-gate  * PIC flags.
1807c478bd9Sstevel@tonic-gate  */
1817c478bd9Sstevel@tonic-gate #define	KCPC_PIC_OVERFLOWED	0x1	/* pic overflowed & requested notify */
1827c478bd9Sstevel@tonic-gate 
183b9e93c10SJonathan Haslam /*
184b9e93c10SJonathan Haslam  * The following flags are used by the DTrace CPU performance counter provider
185b9e93c10SJonathan Haslam  * and the overflow handler. The 'DCPC_INTR_*' flags are used to synchronize
186b9e93c10SJonathan Haslam  * performance counter configuration events performed by the cpc provider and
187b9e93c10SJonathan Haslam  * interrupt processing carried out by the overflow handler.  The 'DCPC_?MASK'
188b9e93c10SJonathan Haslam  * flags are used by the dcpc provider to indicate which type of mask attribute
189b9e93c10SJonathan Haslam  * a platform supports.
190b9e93c10SJonathan Haslam  */
191b9e93c10SJonathan Haslam 
192*af4595edSJonathan Haslam enum dcpc_intr_state {
193*af4595edSJonathan Haslam 	DCPC_INTR_INACTIVE,	/* The dcpc provider is currently not in use */
194*af4595edSJonathan Haslam 	DCPC_INTR_FREE,		/* No config events or ovf ints in progress */
195*af4595edSJonathan Haslam 	DCPC_INTR_PROCESSING,	/* An overflow interrupt is being processed */
196*af4595edSJonathan Haslam 	DCPC_INTR_CONFIG	/* cpc subsystem being configured by dcpc */
197*af4595edSJonathan Haslam };
198b9e93c10SJonathan Haslam 
199*af4595edSJonathan Haslam enum dcpc_mask_attr {
200*af4595edSJonathan Haslam 	DCPC_UMASK = 0x1,	/* The platform supports a "umask" attribute */
201*af4595edSJonathan Haslam 	DCPC_EMASK = 0x2	/* The platform supports an "emask" attribute */
202*af4595edSJonathan Haslam };
203b9e93c10SJonathan Haslam 
2047c478bd9Sstevel@tonic-gate #ifdef __sparc
2057c478bd9Sstevel@tonic-gate extern uint64_t ultra_gettick(void);
2067c478bd9Sstevel@tonic-gate #define	KCPC_GET_TICK ultra_gettick
2077c478bd9Sstevel@tonic-gate #else
2087c478bd9Sstevel@tonic-gate extern hrtime_t tsc_read(void);
2097c478bd9Sstevel@tonic-gate #define	KCPC_GET_TICK tsc_read
2107c478bd9Sstevel@tonic-gate #endif /* __sparc */
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate #define	PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate struct cpu;
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate extern uint_t cpc_ncounters;
2177c478bd9Sstevel@tonic-gate extern krwlock_t kcpc_cpuctx_lock;	/* lock for 'kcpc_cpuctx' below */
2187c478bd9Sstevel@tonic-gate extern int	kcpc_cpuctx;		/* number of cpu-specific contexts */
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate extern void kcpc_invalidate_all(void);
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate extern void kcpc_passivate(void);
223b885580bSAlexander Kolbasov extern void kcpc_cpu_stop(struct cpu *, boolean_t);
2247c478bd9Sstevel@tonic-gate extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t);
225b885580bSAlexander Kolbasov extern void kcpc_cpu_program(struct cpu *, kcpc_ctx_t *);
226b9e93c10SJonathan Haslam extern void kcpc_register_dcpc(void (*func)(uint64_t));
227b9e93c10SJonathan Haslam extern void kcpc_unregister_dcpc(void);
228b885580bSAlexander Kolbasov extern kcpc_ctx_t *kcpc_ctx_alloc(int);
229b9e93c10SJonathan Haslam extern int kcpc_assign_reqs(struct _kcpc_set *, kcpc_ctx_t *);
230b9e93c10SJonathan Haslam extern void kcpc_ctx_free(kcpc_ctx_t *);
231b9e93c10SJonathan Haslam extern int kcpc_configure_reqs(kcpc_ctx_t *, struct _kcpc_set *, int *);
232b9e93c10SJonathan Haslam extern void kcpc_free_configs(struct _kcpc_set *);
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate /*
2377c478bd9Sstevel@tonic-gate  * Error subcodes.
2387c478bd9Sstevel@tonic-gate  */
2397c478bd9Sstevel@tonic-gate #define	CPC_INVALID_EVENT		1	/* Unknown event */
2407c478bd9Sstevel@tonic-gate #define	CPC_INVALID_PICNUM		2	/* Requested PIC out of range */
2417c478bd9Sstevel@tonic-gate #define	CPC_INVALID_ATTRIBUTE		3	/* Unknown attribute */
2427c478bd9Sstevel@tonic-gate #define	CPC_ATTRIBUTE_OUT_OF_RANGE	4	/* Attribute val out of range */
2437c478bd9Sstevel@tonic-gate #define	CPC_RESOURCE_UNAVAIL		5	/* Can't get needed resource */
2447c478bd9Sstevel@tonic-gate #define	CPC_PIC_NOT_CAPABLE		6	/* PIC can't count this event */
2457c478bd9Sstevel@tonic-gate #define	CPC_REQ_INVALID_FLAGS		7	/* Invalid flags in req(s) */
2467c478bd9Sstevel@tonic-gate #define	CPC_CONFLICTING_REQS		8	/* Reqs in the set conflict */
2477c478bd9Sstevel@tonic-gate #define	CPC_ATTR_REQUIRES_PRIVILEGE	9	/* Insufficient privs for atr */
2487c478bd9Sstevel@tonic-gate #define	CPC_PBIND_FAILED		10	/* Couldn't bind to processor */
2498d4e547dSae112802 #define	CPC_HV_NO_ACCESS		11	/* No perm for HV events */
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate #endif
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate #endif	/* _SYS_CPC_IMPL_H */
256