1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1996 Berkeley Software Design, Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Berkeley Software Design Inc's name may not be used to endorse or
15 *    promote products derived from this software without specific prior
16 *    written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN INC ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN INC BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 *	from BSDI $Id: ktr.h,v 1.10.2.7 2000/03/16 21:44:42 cp Exp $
31 * $FreeBSD$
32 */
33
34/*
35 *	Wraparound kernel trace buffer support.
36 */
37
38#ifndef _SYS_KTR_H_
39#define _SYS_KTR_H_
40
41#include <sys/ktr_class.h>
42
43/*
44 * Version number for ktr_entry struct.  Increment this when you break binary
45 * compatibility.
46 */
47#define	KTR_VERSION	2
48
49#define	KTR_PARMS	6
50
51#ifndef LOCORE
52
53#include <sys/param.h>
54#include <sys/_cpuset.h>
55
56struct ktr_entry {
57	u_int64_t ktr_timestamp;
58	int	ktr_cpu;
59	int	ktr_line;
60	const	char *ktr_file;
61	const	char *ktr_desc;
62	struct	thread *ktr_thread;
63	u_long	ktr_parms[KTR_PARMS];
64};
65
66extern cpuset_t ktr_cpumask;
67extern uint64_t ktr_mask;
68extern int ktr_entries;
69extern int ktr_verbose;
70
71extern volatile int ktr_idx;
72extern struct ktr_entry *ktr_buf;
73
74#ifdef KTR
75
76void	ktr_tracepoint(uint64_t mask, const char *file, int line,
77	    const char *format, u_long arg1, u_long arg2, u_long arg3,
78	    u_long arg4, u_long arg5, u_long arg6);
79
80#define CTR6(m, format, p1, p2, p3, p4, p5, p6) do {			\
81	if (KTR_COMPILE & (m))						\
82		ktr_tracepoint((m), __FILE__, __LINE__, format,		\
83		    (u_long)(p1), (u_long)(p2), (u_long)(p3),		\
84		    (u_long)(p4), (u_long)(p5), (u_long)(p6));		\
85	} while(0)
86#define CTR0(m, format)			CTR6(m, format, 0, 0, 0, 0, 0, 0)
87#define CTR1(m, format, p1)		CTR6(m, format, p1, 0, 0, 0, 0, 0)
88#define	CTR2(m, format, p1, p2)		CTR6(m, format, p1, p2, 0, 0, 0, 0)
89#define	CTR3(m, format, p1, p2, p3)	CTR6(m, format, p1, p2, p3, 0, 0, 0)
90#define	CTR4(m, format, p1, p2, p3, p4)	CTR6(m, format, p1, p2, p3, p4, 0, 0)
91#define	CTR5(m, format, p1, p2, p3, p4, p5)	CTR6(m, format, p1, p2, p3, p4, p5, 0)
92#else	/* KTR */
93#define	CTR0(m, d)			(void)0
94#define	CTR1(m, d, p1)			(void)0
95#define	CTR2(m, d, p1, p2)		(void)0
96#define	CTR3(m, d, p1, p2, p3)		(void)0
97#define	CTR4(m, d, p1, p2, p3, p4)	(void)0
98#define	CTR5(m, d, p1, p2, p3, p4, p5)	(void)0
99#define	CTR6(m, d, p1, p2, p3, p4, p5, p6)	(void)0
100#endif	/* KTR */
101
102#define	TR0(d)				CTR0(KTR_GEN, d)
103#define	TR1(d, p1)			CTR1(KTR_GEN, d, p1)
104#define	TR2(d, p1, p2)			CTR2(KTR_GEN, d, p1, p2)
105#define	TR3(d, p1, p2, p3)		CTR3(KTR_GEN, d, p1, p2, p3)
106#define	TR4(d, p1, p2, p3, p4)		CTR4(KTR_GEN, d, p1, p2, p3, p4)
107#define	TR5(d, p1, p2, p3, p4, p5)	CTR5(KTR_GEN, d, p1, p2, p3, p4, p5)
108#define	TR6(d, p1, p2, p3, p4, p5, p6)	CTR6(KTR_GEN, d, p1, p2, p3, p4, p5, p6)
109
110/*
111 * The event macros implement KTR graphic plotting facilities provided
112 * by src/tools/sched/schedgraph.py.  Three generic types of events are
113 * supported: states, counters, and points.
114 *
115 * m is the ktr class for ktr_mask.
116 * ident is the string identifier that owns the event (ie: "thread 10001")
117 * etype is the type of event to plot (state, counter, point)
118 * edat is the event specific data (state name, counter value, point name)
119 * up to four attributes may be supplied as a name, value pair of arguments.
120 *
121 * etype and attribute names must be string constants.  This minimizes the
122 * number of ktr slots required by construction the final format strings
123 * at compile time.  Both must also include a colon and format specifier
124 * (ie. "prio:%d", prio).  It is recommended that string arguments be
125 * contained within escaped quotes if they may contain ',' or ':' characters.
126 *
127 * The special attribute (KTR_ATTR_LINKED, ident) creates a reference to another
128 * id on the graph for easy traversal of related graph elements.
129 */
130
131#define	KTR_ATTR_LINKED	"linkedto:\"%s\""
132#define	KTR_EFMT(egroup, ident, etype)					\
133	    "KTRGRAPH group:\"" egroup "\", id:\"%s\", " etype ", attributes: "
134
135#define	KTR_EVENT0(m, egroup, ident, etype, edat)			\
136	CTR2(m,	KTR_EFMT(egroup, ident, etype) "none", ident, edat)
137#define	KTR_EVENT1(m, egroup, ident, etype, edat, a0, v0)		\
138	CTR3(m, KTR_EFMT(egroup, ident, etype) a0, ident, edat, (v0))
139#define	KTR_EVENT2(m, egroup, ident, etype, edat, a0, v0, a1, v1)	\
140	CTR4(m, KTR_EFMT(egroup, ident, etype) a0 ", " a1,		\
141	    ident, edat, (v0), (v1))
142#define	KTR_EVENT3(m, egroup, ident, etype, edat, a0, v0, a1, v1, a2, v2)\
143	CTR5(m,KTR_EFMT(egroup, ident, etype) a0 ", " a1 ", " a2,	\
144	    ident, edat, (v0), (v1), (v2))
145#define	KTR_EVENT4(m, egroup, ident, etype, edat,			\
146	    a0, v0, a1, v1, a2, v2, a3, v3)				\
147	CTR6(m,KTR_EFMT(egroup, ident, etype) a0 ", " a1 ", " a2 ", " a3,\
148	     ident, edat, (v0), (v1), (v2), (v3))
149
150/*
151 * State functions graph state changes on an ident.
152 */
153#define KTR_STATE0(m, egroup, ident, state)				\
154	KTR_EVENT0(m, egroup, ident, "state:\"%s\"", state)
155#define KTR_STATE1(m, egroup, ident, state, a0, v0)			\
156	KTR_EVENT1(m, egroup, ident, "state:\"%s\"", state, a0, (v0))
157#define KTR_STATE2(m, egroup, ident, state, a0, v0, a1, v1)		\
158	KTR_EVENT2(m, egroup, ident, "state:\"%s\"", state, a0, (v0), a1, (v1))
159#define KTR_STATE3(m, egroup, ident, state, a0, v0, a1, v1, a2, v2)	\
160	KTR_EVENT3(m, egroup, ident, "state:\"%s\"",			\
161	    state, a0, (v0), a1, (v1), a2, (v2))
162#define KTR_STATE4(m, egroup, ident, state, a0, v0, a1, v1, a2, v2, a3, v3)\
163	KTR_EVENT4(m, egroup, ident, "state:\"%s\"",			\
164	    state, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
165
166/*
167 * Counter functions graph counter values.  The counter id
168 * must not be intermixed with a state id.
169 */
170#define	KTR_COUNTER0(m, egroup, ident, counter)				\
171	KTR_EVENT0(m, egroup, ident, "counter:%d", counter)
172#define	KTR_COUNTER1(m, egroup, ident, edat, a0, v0)			\
173	KTR_EVENT1(m, egroup, ident, "counter:%d", counter, a0, (v0))
174#define	KTR_COUNTER2(m, egroup, ident, counter, a0, v0, a1, v1)		\
175	KTR_EVENT2(m, egroup, ident, "counter:%d", counter, a0, (v0), a1, (v1))
176#define	KTR_COUNTER3(m, egroup, ident, counter, a0, v0, a1, v1, a2, v2)	\
177	KTR_EVENT3(m, egroup, ident, "counter:%d",			\
178	    counter, a0, (v0), a1, (v1), a2, (v2))
179#define	KTR_COUNTER4(m, egroup, ident, counter, a0, v0, a1, v1, a2, v2, a3, v3)\
180	KTR_EVENT4(m, egroup, ident, "counter:%d",			\
181	    counter, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
182
183/*
184 * Point functions plot points of interest on counter or state graphs.
185 */
186#define	KTR_POINT0(m, egroup, ident, point)				\
187	KTR_EVENT0(m, egroup, ident, "point:\"%s\"", point)
188#define	KTR_POINT1(m, egroup, ident, point, a0, v0)			\
189	KTR_EVENT1(m, egroup, ident, "point:\"%s\"", point, a0, (v0))
190#define	KTR_POINT2(m, egroup, ident, point, a0, v0, a1, v1)		\
191	KTR_EVENT2(m, egroup, ident, "point:\"%s\"", point, a0, (v0), a1, (v1))
192#define	KTR_POINT3(m, egroup, ident, point, a0, v0, a1, v1, a2, v2)	\
193	KTR_EVENT3(m, egroup, ident, "point:\"%s\"", point,		\
194	    a0, (v0), a1, (v1), a2, (v2))
195#define	KTR_POINT4(m, egroup, ident, point, a0, v0, a1, v1, a2, v2, a3, v3)\
196	KTR_EVENT4(m, egroup, ident, "point:\"%s\"",			\
197	    point, a0, (v0), a1, (v1), a2, (v2), a3, (v3))
198
199/*
200 * Start functions denote the start of a region of code or operation
201 * and should be paired with stop functions for timing of nested
202 * sequences.
203 *
204 * Specifying extra attributes with the name "key" will result in
205 * multi-part keys.  For example a block device and offset pair
206 * might be used to describe a buf undergoing I/O.
207 */
208#define	KTR_START0(m, egroup, ident, key)				\
209	KTR_EVENT0(m, egroup, ident, "start:0x%jX", (uintmax_t)key)
210#define	KTR_START1(m, egroup, ident, key, a0, v0)			\
211	KTR_EVENT1(m, egroup, ident, "start:0x%jX", (uintmax_t)key, a0, (v0))
212#define	KTR_START2(m, egroup, ident, key, a0, v0, a1, v1)		\
213	KTR_EVENT2(m, egroup, ident, "start:0x%jX", (uintmax_t)key,	\
214	    a0, (v0), a1, (v1))
215#define	KTR_START3(m, egroup, ident, key, a0, v0, a1, v1, a2, v2)\
216	KTR_EVENT3(m, egroup, ident, "start:0x%jX", (uintmax_t)key,	\
217	    a0, (v0), a1, (v1), a2, (v2))
218#define	KTR_START4(m, egroup, ident, key,				\
219	    a0, v0, a1, v1, a2, v2, a3, v3)				\
220	KTR_EVENT4(m, egroup, ident, "start:0x%jX", (uintmax_t)key,	\
221	    a0, (v0), a1, (v1), a2, (v2), a3, (v3))
222
223/*
224 * Stop functions denote the end of a region of code or operation
225 * and should be paired with start functions for timing of nested
226 * sequences.
227 */
228#define	KTR_STOP0(m, egroup, ident, key)				\
229	KTR_EVENT0(m, egroup, ident, "stop:0x%jX", (uintmax_t)key)
230#define	KTR_STOP1(m, egroup, ident, key, a0, v0)			\
231	KTR_EVENT1(m, egroup, ident, "stop:0x%jX", (uintmax_t)key, a0, (v0))
232#define	KTR_STOP2(m, egroup, ident, key, a0, v0, a1, v1)		\
233	KTR_EVENT2(m, egroup, ident, "stop:0x%jX", (uintmax_t)key,	\
234	    a0, (v0), a1, (v1))
235#define	KTR_STOP3(m, egroup, ident, key, a0, v0, a1, v1, a2, v2)\
236	KTR_EVENT3(m, egroup, ident, "stop:0x%jX", (uintmax_t)key,	\
237	    a0, (v0), a1, (v1), a2, (v2))
238#define	KTR_STOP4(m, egroup, ident, 					\
239	    key, a0, v0, a1, v1, a2, v2, a3, v3)			\
240	KTR_EVENT4(m, egroup, ident, "stop:0x%jX", (uintmax_t)key,	\
241	    a0, (v0), a1, (v1), a2, (v2), a3, (v3))
242
243/*
244 * Trace initialization events, similar to CTR with KTR_INIT, but
245 * completely ifdef'ed out if KTR_INIT isn't in KTR_COMPILE (to
246 * save string space, the compiler doesn't optimize out strings
247 * for the conditional ones above).
248 */
249#if (KTR_COMPILE & KTR_INIT) != 0
250#define	ITR0(d)				CTR0(KTR_INIT, d)
251#define	ITR1(d, p1)			CTR1(KTR_INIT, d, p1)
252#define	ITR2(d, p1, p2)			CTR2(KTR_INIT, d, p1, p2)
253#define	ITR3(d, p1, p2, p3)		CTR3(KTR_INIT, d, p1, p2, p3)
254#define	ITR4(d, p1, p2, p3, p4)		CTR4(KTR_INIT, d, p1, p2, p3, p4)
255#define	ITR5(d, p1, p2, p3, p4, p5)	CTR5(KTR_INIT, d, p1, p2, p3, p4, p5)
256#define	ITR6(d, p1, p2, p3, p4, p5, p6)	CTR6(KTR_INIT, d, p1, p2, p3, p4, p5, p6)
257#else
258#define	ITR0(d)
259#define	ITR1(d, p1)
260#define	ITR2(d, p1, p2)
261#define	ITR3(d, p1, p2, p3)
262#define	ITR4(d, p1, p2, p3, p4)
263#define	ITR5(d, p1, p2, p3, p4, p5)
264#define	ITR6(d, p1, p2, p3, p4, p5, p6)
265#endif
266
267#endif /* !LOCORE */
268
269#endif /* !_SYS_KTR_H_ */
270