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