xref: /illumos-gate/usr/src/uts/common/tnf/tnf_trace.c (revision 7c478bd9)
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
tnf_kernel_schedule(tnf_ops_t * ops,tnf_schedule_t * sched)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
tnf_opaque_array_1(tnf_ops_t * ops,tnf_opaque_t * opaques,tnf_record_p reference,tnf_tag_data_t * tag_data)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
tnf_opaque32_array_1(tnf_ops_t * ops,tnf_uint32_t * opaques,tnf_record_p reference,tnf_tag_data_t * tag_data)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
tnf_tag_trace_init(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