Home | History | Annotate | Download | only in sys
      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 2007 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 #pragma ident	"@(#)cpc_impl.h	1.13	07/02/23 SMI"
     30 
     31 #include <sys/types.h>
     32 #include <sys/time.h>
     33 #include <sys/rwlock.h>
     34 
     35 #if defined(_KERNEL) && defined(_MULTI_DATAMODEL)
     36 #include <sys/types32.h>
     37 #endif
     38 
     39 #ifdef	__cplusplus
     40 extern "C" {
     41 #endif
     42 
     43 typedef struct {
     44 	char		*ca_name;
     45 	uint64_t	ca_val;
     46 } cpc_attr_t;
     47 
     48 /*
     49  * Flag arguments to cpc_bind_event and cpc_ctx_bind_event
     50  */
     51 #define	CPC_BIND_LWP_INHERIT	(0x1)
     52 #define	CPC_BIND_EMT_OVF	(0x2)
     53 
     54 #define	CPC_MAX_IMPL_NAME	512	/* Max len of PCBE's description str */
     55 #define	CPC_MAX_CPUREF		1024	/* Max len of PCBE's CPU ref string */
     56 
     57 #define	CPC_OVF_NOTIFY_EMT	0x1
     58 #define	CPC_COUNT_USER		0x2
     59 #define	CPC_COUNT_SYSTEM	0x4
     60 #define	CPC_COUNT_HV		0x8
     61 
     62 #define	KCPC_REQ_ALL_FLAGS	(CPC_OVF_NOTIFY_EMT | CPC_COUNT_USER | \
     63 		CPC_COUNT_SYSTEM | CPC_COUNT_HV)
     64 #define	KCPC_REQ_VALID_FLAGS(flags) \
     65 		(((flags) | KCPC_REQ_ALL_FLAGS) == KCPC_REQ_ALL_FLAGS)
     66 
     67 /*
     68  * CPC Capabilities
     69  */
     70 #define	CPC_CAP_OVERFLOW_INTERRUPT	0x1
     71 #define	CPC_CAP_OVERFLOW_PRECISE	0x2
     72 
     73 /*
     74  * The only valid per-set flag is CPC_BIND_LWP_INHERIT, which must remain in
     75  * cpc_event.h for backwards compatibility.
     76  */
     77 #define	CPC_SET_ALL_FLAGS	0x1
     78 #define	CPC_SET_VALID_FLAGS(flags) \
     79 		(((flags) | CPC_SET_ALL_FLAGS) == CPC_SET_ALL_FLAGS)
     80 
     81 /*
     82  * These system call subcodes and ioctls allow the implementation of the
     83  * libcpc library to store and retrieve performance counter data.  Subject
     84  * to arbitrary change without notice at any time.  Do not invoke them
     85  * directly!
     86  */
     87 #define	CPC_BIND		0
     88 #define	CPC_SAMPLE		1
     89 #define	CPC_INVALIDATE		2
     90 #define	CPC_RELE		3
     91 #define	CPC_EVLIST_SIZE		4
     92 #define	CPC_LIST_EVENTS		5
     93 #define	CPC_ATTRLIST_SIZE	6
     94 #define	CPC_LIST_ATTRS		7
     95 #define	CPC_IMPL_NAME		8
     96 #define	CPC_CPUREF		9
     97 #define	CPC_USR_EVENTS		10
     98 #define	CPC_SYS_EVENTS		11
     99 #define	CPC_NPIC		12
    100 #define	CPC_CAPS		13
    101 #define	CPC_ENABLE		14
    102 #define	CPC_DISABLE		15
    103 #define	CPC_PRESET		16
    104 #define	CPC_RESTART		17
    105 
    106 #define	_CPCIO_IOC	((((('c'<<8)|'p')<<8)|'c')<<8)
    107 
    108 #define	CPCIO_BIND			(_CPCIO_IOC | 0x1)
    109 #define	CPCIO_SAMPLE			(_CPCIO_IOC | 0x2)
    110 #define	CPCIO_RELE			(_CPCIO_IOC | 0x3)
    111 
    112 /*
    113  * Forward declarations.
    114  */
    115 struct _kthread;
    116 struct _kcpc_set;
    117 
    118 #define	CPC_MAX_EVENT_LEN	512
    119 #define	CPC_MAX_ATTR_LEN	32
    120 
    121 typedef struct _kcpc_attr {
    122 	char		ka_name[CPC_MAX_ATTR_LEN];
    123 	uint64_t	ka_val;
    124 } kcpc_attr_t;
    125 
    126 typedef struct _kcpc_pic {
    127 	uint_t			kp_flags;
    128 	struct _kcpc_request	*kp_req;   /* request this PIC counts for */
    129 } kcpc_pic_t;
    130 
    131 typedef struct _kcpc_ctx kcpc_ctx_t;
    132 
    133 struct _kcpc_ctx {
    134 	struct _kcpc_set *kc_set;	/* linked list of all bound sets */
    135 	uint32_t	kc_flags;
    136 	kcpc_pic_t	*kc_pics;	/* pointer to array of per-pic data */
    137 	hrtime_t	kc_hrtime;	/* gethrtime() at last sample */
    138 	uint64_t	kc_vtick;	/* virtualized %tick */
    139 	uint64_t	kc_rawtick;	/* last snapshot of tick/tsc */
    140 	struct _kthread	*kc_thread;	/* thread this context is measuring */
    141 	int		kc_cpuid;	/* CPU this context is measuring */
    142 	kcpc_ctx_t	*kc_next;	/* Global list of all contexts */
    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 
    176 /*
    177  * PIC flags.
    178  */
    179 #define	KCPC_PIC_OVERFLOWED	0x1	/* pic overflowed & requested notify */
    180 
    181 #ifdef __sparc
    182 extern uint64_t ultra_gettick(void);
    183 #define	KCPC_GET_TICK ultra_gettick
    184 #else
    185 extern hrtime_t tsc_read(void);
    186 #define	KCPC_GET_TICK tsc_read
    187 #endif /* __sparc */
    188 
    189 #define	PCBE_NAMELEN 30 /* Enough room for "pcbe." plus full PCBE name spec */
    190 
    191 struct cpu;
    192 
    193 extern uint_t cpc_ncounters;
    194 extern kmutex_t	kcpc_ctx_llock[];	/* protects ctx_list */
    195 extern kcpc_ctx_t *kcpc_ctx_list[];	/* head of list */
    196 extern krwlock_t kcpc_cpuctx_lock;	/* lock for 'kcpc_cpuctx' below */
    197 extern int	kcpc_cpuctx;		/* number of cpu-specific contexts */
    198 
    199 extern void kcpc_invalidate_all(void);
    200 
    201 extern void kcpc_passivate(void);
    202 extern void kcpc_remote_stop(struct cpu *cp);
    203 extern int kcpc_pcbe_tryload(const char *, uint_t, uint_t, uint_t);
    204 
    205 #endif /* _KERNEL */
    206 
    207 /*
    208  * Error subcodes.
    209  */
    210 #define	CPC_INVALID_EVENT		1	/* Unknown event */
    211 #define	CPC_INVALID_PICNUM		2	/* Requested PIC out of range */
    212 #define	CPC_INVALID_ATTRIBUTE		3	/* Unknown attribute */
    213 #define	CPC_ATTRIBUTE_OUT_OF_RANGE	4	/* Attribute val out of range */
    214 #define	CPC_RESOURCE_UNAVAIL		5	/* Can't get needed resource */
    215 #define	CPC_PIC_NOT_CAPABLE		6	/* PIC can't count this event */
    216 #define	CPC_REQ_INVALID_FLAGS		7	/* Invalid flags in req(s) */
    217 #define	CPC_CONFLICTING_REQS		8	/* Reqs in the set conflict */
    218 #define	CPC_ATTR_REQUIRES_PRIVILEGE	9	/* Insufficient privs for atr */
    219 #define	CPC_PBIND_FAILED		10	/* Couldn't bind to processor */
    220 #define	CPC_HV_NO_ACCESS		11	/* No perm for HV events */
    221 
    222 #ifdef	__cplusplus
    223 }
    224 #endif
    225 
    226 #endif	/* _SYS_CPC_IMPL_H */
    227