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 1994, 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/ddi.h> /* strchr */ 33 #include <sys/sunddi.h> /* strchr */ 34 #include <sys/tnf_com.h> 35 #include <sys/tnf_writer.h> 36 #include <sys/tnf_probe.h> 37 #include <sys/debug.h> 38 39 #include "tnf_buf.h" 40 #include "tnf_types.h" 41 #include "tnf_trace.h" 42 43 /* 44 * New derived types for probes 45 */ 46 47 TNF_STD_DERIVED_TAG(tnf_probe_event, tnf_tag, 48 tnf_derived_properties, TNF_OPAQUE); 49 50 TNF_STD_DERIVED_TAG(tnf_time_base, tnf_int64, 51 tnf_derived_properties, TNF_INT64); 52 53 TNF_STD_DERIVED_TAG(tnf_time_delta, tnf_uint32, 54 tnf_derived_properties, TNF_UINT32); 55 56 TNF_STD_DERIVED_TAG(tnf_pid, tnf_int32, 57 tnf_derived_properties, TNF_INT32); 58 59 TNF_STD_DERIVED_TAG(tnf_lwpid, tnf_uint32, 60 tnf_derived_properties, TNF_UINT32); 61 62 TNF_STD_DERIVED_TAG(tnf_kthread_id, tnf_opaque, 63 tnf_derived_properties, TNF_OPAQUE); 64 65 TNF_STD_DERIVED_TAG(tnf_cpuid, tnf_int32, 66 tnf_derived_properties, TNF_INT32); 67 68 TNF_STD_DERIVED_TAG(tnf_device, tnf_ulong, 69 tnf_derived_properties, TNF_ULONG); 70 71 TNF_STD_DERIVED_TAG(tnf_symbol, tnf_opaque, 72 tnf_derived_properties, TNF_OPAQUE); 73 74 TNF_STD_ARRAY_TAG(tnf_symbols, tnf_symbol, TNF_ARRAY); 75 76 TNF_STD_DERIVED_TAG(tnf_sysnum, tnf_int16, 77 tnf_derived_properties, TNF_INT32); 78 79 TNF_STD_DERIVED_TAG(tnf_microstate, tnf_int32, 80 tnf_derived_properties, TNF_INT32); 81 82 TNF_STD_DERIVED_TAG(tnf_offset, tnf_int64, 83 tnf_derived_properties, TNF_INT64); 84 85 TNF_STD_DERIVED_TAG(tnf_fault_type, tnf_int32, 86 tnf_derived_properties, TNF_INT32); 87 88 TNF_STD_DERIVED_TAG(tnf_seg_access, tnf_int32, 89 tnf_derived_properties, TNF_INT32); 90 91 TNF_STD_DERIVED_TAG(tnf_bioflags, tnf_int32, 92 tnf_derived_properties, TNF_INT32); 93 94 TNF_STD_DERIVED_TAG(tnf_diskaddr, tnf_int64, 95 tnf_derived_properties, TNF_INT64); 96 97 static char *kernel_schedule_slot_names[] = { 98 TNF_N_TAG, 99 TNF_N_TID, 100 TNF_N_LWPID, 101 TNF_N_PID, 102 TNF_N_TIME_BASE, 103 "cpuid", /* XXX */ 104 0}; 105 106 static tnf_tag_data_t **kernel_schedule_slots[] = { 107 &TAG_DATA(tnf_tag), 108 &TAG_DATA(tnf_kthread_id), 109 &TAG_DATA(tnf_lwpid), 110 &TAG_DATA(tnf_pid), 111 &TAG_DATA(tnf_time_base), 112 &TAG_DATA(tnf_cpuid), 113 0}; 114 115 TNF_STD_STRUCT_TAG(tnf_kernel_schedule, 116 kernel_schedule_slots, 117 kernel_schedule_slot_names, 118 sizeof (tnf_schedule_prototype_t)); 119 120 /* 121 * Probe type record (metatag) 122 */ 123 124 static tnf_tag_data_t **probe_type_slots[] = { 125 &TAG_DATA(tnf_tag), 126 &TAG_DATA(tnf_name), 127 &TAG_DATA(tnf_properties), 128 &TAG_DATA(tnf_slot_types), 129 &TAG_DATA(tnf_type_size), 130 &TAG_DATA(tnf_slot_names), 131 &TAG_DATA(tnf_string), /* detail */ 132 0}; 133 134 TNF_METATAG(tnf_probe_type, tnf_type_properties, 135 probe_type_slots, tnf_struct_tag_1); 136 137 /* 138 * Write a kernel schedule record 139 * Can only be written in reusable data space. 140 */ 141 142 tnf_record_p 143 tnf_kernel_schedule(tnf_ops_t *ops, tnf_schedule_t *sched) 144 { 145 tnf_tag_data_t *metatag_data; 146 tnf_record_p metatag_index; 147 tnf_schedule_prototype_t *buffer; 148 kthread_t *t; 149 150 t = curthread; 151 152 /* Cannot be called when writing into tag space */ 153 ASSERT(ops->mode == TNF_ALLOC_REUSABLE); 154 155 ALLOC(ops, sizeof (*buffer), buffer, sched->record_p, 156 TNF_ALLOC_REUSABLE); /* XXX see comment above */ 157 158 metatag_data = TAG_DATA(tnf_kernel_schedule); 159 metatag_index = metatag_data->tag_index ? 160 metatag_data->tag_index : 161 metatag_data->tag_desc(ops, metatag_data); 162 163 ASSIGN(buffer, tag, metatag_index); 164 ASSIGN2(buffer, tid, t, kthread_id); 165 ASSIGN(buffer, lwpid, t->t_tid); 166 ASSIGN(buffer, pid, ttoproc(t)->p_pid); 167 ASSIGN(buffer, time_base, sched->time_base); 168 ASSIGN(buffer, cpuid, sched->cpuid); 169 170 /* 171 * Remember schedule record generation number so the distance 172 * in virtual space can be calculated from an event record 173 */ 174 sched->record_gen = ((tnf_block_header_t *) 175 ((uintptr_t)buffer & TNF_BLOCK_MASK))->generation; 176 /* Cannot have been written into tag space */ 177 ASSERT(sched->record_gen != TNF_TAG_GENERATION_NUM); 178 179 return ((tnf_record_p)buffer); 180 } 181 182 /* 183 * Array of addresses and derivatives 184 */ 185 186 tnf_reference_t 187 tnf_opaque_array_1(tnf_ops_t *ops, tnf_opaque_t *opaques, 188 tnf_record_p reference, tnf_tag_data_t *tag_data) 189 { 190 tnf_record_p tag_index; 191 size_t record_size; 192 tnf_opaque_t *tmp; 193 tnf_opaque_t *ref_p; 194 tnf_array_header_t *bufhdr; 195 196 tag_index = tag_data->tag_index ? tag_data->tag_index : 197 tag_data->tag_desc(ops, tag_data); 198 199 if (!opaques) 200 return (TNF_NULL); 201 202 record_size = sizeof (*bufhdr); 203 tmp = opaques; 204 while (*tmp++) 205 record_size += sizeof (*ref_p); 206 207 ALLOC2(ops, record_size, bufhdr, ops->mode); 208 209 ASSIGN(bufhdr, tag, tag_index); 210 /* LINTED assignment of 64-bit integer to 32-bit integer */ 211 ASSIGN(bufhdr, self_size, record_size); 212 213 tmp = opaques; 214 /* LINTED pointer cast may result in improper alignment */ 215 ref_p = (tnf_opaque_t *)((char *)bufhdr + sizeof (*bufhdr)); 216 while (*tmp) { 217 *ref_p = tnf_opaque(ops, *tmp, (tnf_reference_t *)ref_p); 218 tmp++; 219 ref_p++; 220 } 221 222 return (tnf_ref32(ops, (tnf_record_p) bufhdr, reference)); 223 } 224 225 #ifdef __sparc 226 227 tnf_reference_t 228 tnf_opaque32_array_1(tnf_ops_t *ops, tnf_uint32_t *opaques, 229 tnf_record_p reference, tnf_tag_data_t *tag_data) 230 { 231 tnf_record_p tag_index; 232 size_t record_size; 233 tnf_uint32_t *tmp; 234 tnf_uint32_t *ref_p; 235 tnf_array_header_t *bufhdr; 236 237 tag_index = tag_data->tag_index ? tag_data->tag_index : 238 tag_data->tag_desc(ops, tag_data); 239 240 if (!opaques) 241 return (TNF_NULL); 242 243 record_size = sizeof (*bufhdr); 244 tmp = opaques; 245 while (*tmp++) 246 record_size += sizeof (*ref_p); 247 248 ALLOC2(ops, record_size, bufhdr, ops->mode); 249 250 ASSIGN(bufhdr, tag, tag_index); 251 /* LINTED assignment of 64-bit integer to 32-bit integer */ 252 ASSIGN(bufhdr, self_size, record_size); 253 254 tmp = opaques; 255 /* LINTED pointer cast may result in improper alignment */ 256 ref_p = (tnf_uint32_t *)((char *)bufhdr + sizeof (*bufhdr)); 257 while (*tmp) { 258 *ref_p = tnf_uint32(ops, *tmp, (tnf_reference_t *)ref_p); 259 tmp++; 260 ref_p++; 261 } 262 263 return (tnf_ref32(ops, (tnf_record_p) bufhdr, reference)); 264 } 265 266 #endif /* __sparc */ 267 268 /* 269 * Tag initializer 270 */ 271 272 void 273 tnf_tag_trace_init(void) 274 { 275 276 TAG_SNAP(tnf_probe_event); 277 TAG_SNAP(tnf_time_base); 278 TAG_SNAP(tnf_time_delta); 279 TAG_SNAP(tnf_pid); 280 TAG_SNAP(tnf_lwpid); 281 282 TAG_SNAP(tnf_kthread_id); 283 TAG_SNAP(tnf_cpuid); 284 TAG_SNAP(tnf_device); 285 TAG_SNAP(tnf_symbol); 286 TAG_SNAP(tnf_symbols); 287 TAG_SNAP(tnf_sysnum); 288 TAG_SNAP(tnf_microstate); 289 TAG_SNAP(tnf_offset); 290 TAG_SNAP(tnf_fault_type); 291 TAG_SNAP(tnf_seg_access); 292 TAG_SNAP(tnf_bioflags); 293 TAG_SNAP(tnf_diskaddr); 294 TAG_SNAP(tnf_kernel_schedule); 295 296 TAG_SNAP(tnf_probe_type); 297 298 } 299