Home | History | Annotate | Download | only in tnf
      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	"@(#)tnf_trace.c	1.25	05/06/08 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