1 /* SPDX-License-Identifier: GPL-2.0 */
2 #undef TRACE_SYSTEM
3 #define TRACE_SYSTEM irq_vectors
4 
5 #if !defined(_TRACE_IRQ_VECTORS_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define _TRACE_IRQ_VECTORS_H
7 
8 #include <linux/tracepoint.h>
9 #include <asm/trace/common.h>
10 
11 #ifdef CONFIG_X86_LOCAL_APIC
12 
13 DECLARE_EVENT_CLASS(x86_irq_vector,
14 
15 	TP_PROTO(int vector),
16 
17 	TP_ARGS(vector),
18 
19 	TP_STRUCT__entry(
20 		__field(		int,	vector	)
21 	),
22 
23 	TP_fast_assign(
24 		__entry->vector = vector;
25 	),
26 
27 	TP_printk("vector=%d", __entry->vector) );
28 
29 #define DEFINE_IRQ_VECTOR_EVENT(name)		\
30 DEFINE_EVENT_FN(x86_irq_vector, name##_entry,	\
31 	TP_PROTO(int vector),			\
32 	TP_ARGS(vector), NULL, NULL);		\
33 DEFINE_EVENT_FN(x86_irq_vector, name##_exit,	\
34 	TP_PROTO(int vector),			\
35 	TP_ARGS(vector), NULL, NULL);
36 
37 /*
38  * local_timer - called when entering/exiting a local timer interrupt
39  * vector handler
40  */
41 DEFINE_IRQ_VECTOR_EVENT(local_timer);
42 
43 /*
44  * spurious_apic - called when entering/exiting a spurious apic vector handler
45  */
46 DEFINE_IRQ_VECTOR_EVENT(spurious_apic);
47 
48 /*
49  * error_apic - called when entering/exiting an error apic vector handler
50  */
51 DEFINE_IRQ_VECTOR_EVENT(error_apic);
52 
53 /*
54  * x86_platform_ipi - called when entering/exiting a x86 platform ipi interrupt
55  * vector handler
56  */
57 DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi);
58 
59 #ifdef CONFIG_IRQ_WORK
60 /*
61  * irq_work - called when entering/exiting a irq work interrupt
62  * vector handler
63  */
64 DEFINE_IRQ_VECTOR_EVENT(irq_work);
65 
66 /*
67  * We must dis-allow sampling irq_work_exit() because perf event sampling
68  * itself can cause irq_work, which would lead to an infinite loop;
69  *
70  *  1) irq_work_exit happens
71  *  2) generates perf sample
72  *  3) generates irq_work
73  *  4) goto 1
74  */
75 TRACE_EVENT_PERF_PERM(irq_work_exit, is_sampling_event(p_event) ? -EPERM : 0);
76 #endif
77 
78 /*
79  * The ifdef is required because that tracepoint macro hell emits tracepoint
80  * code in files which include this header even if the tracepoint is not
81  * enabled. Brilliant stuff that.
82  */
83 #ifdef CONFIG_SMP
84 /*
85  * reschedule - called when entering/exiting a reschedule vector handler
86  */
87 DEFINE_IRQ_VECTOR_EVENT(reschedule);
88 
89 /*
90  * call_function - called when entering/exiting a call function interrupt
91  * vector handler
92  */
93 DEFINE_IRQ_VECTOR_EVENT(call_function);
94 
95 /*
96  * call_function_single - called when entering/exiting a call function
97  * single interrupt vector handler
98  */
99 DEFINE_IRQ_VECTOR_EVENT(call_function_single);
100 #endif
101 
102 #ifdef CONFIG_X86_MCE_THRESHOLD
103 /*
104  * threshold_apic - called when entering/exiting a threshold apic interrupt
105  * vector handler
106  */
107 DEFINE_IRQ_VECTOR_EVENT(threshold_apic);
108 #endif
109 
110 #ifdef CONFIG_X86_MCE_AMD
111 /*
112  * deferred_error_apic - called when entering/exiting a deferred apic interrupt
113  * vector handler
114  */
115 DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);
116 #endif
117 
118 #ifdef CONFIG_X86_THERMAL_VECTOR
119 /*
120  * thermal_apic - called when entering/exiting a thermal apic interrupt
121  * vector handler
122  */
123 DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
124 #endif
125 
126 TRACE_EVENT(vector_config,
127 
128 	TP_PROTO(unsigned int irq, unsigned int vector,
129 		 unsigned int cpu, unsigned int apicdest),
130 
131 	TP_ARGS(irq, vector, cpu, apicdest),
132 
133 	TP_STRUCT__entry(
134 		__field(	unsigned int,	irq		)
135 		__field(	unsigned int,	vector		)
136 		__field(	unsigned int,	cpu		)
137 		__field(	unsigned int,	apicdest	)
138 	),
139 
140 	TP_fast_assign(
141 		__entry->irq		= irq;
142 		__entry->vector		= vector;
143 		__entry->cpu		= cpu;
144 		__entry->apicdest	= apicdest;
145 	),
146 
147 	TP_printk("irq=%u vector=%u cpu=%u apicdest=0x%08x",
148 		  __entry->irq, __entry->vector, __entry->cpu,
149 		  __entry->apicdest)
150 );
151 
152 DECLARE_EVENT_CLASS(vector_mod,
153 
154 	TP_PROTO(unsigned int irq, unsigned int vector,
155 		 unsigned int cpu, unsigned int prev_vector,
156 		 unsigned int prev_cpu),
157 
158 	TP_ARGS(irq, vector, cpu, prev_vector, prev_cpu),
159 
160 	TP_STRUCT__entry(
161 		__field(	unsigned int,	irq		)
162 		__field(	unsigned int,	vector		)
163 		__field(	unsigned int,	cpu		)
164 		__field(	unsigned int,	prev_vector	)
165 		__field(	unsigned int,	prev_cpu	)
166 	),
167 
168 	TP_fast_assign(
169 		__entry->irq		= irq;
170 		__entry->vector		= vector;
171 		__entry->cpu		= cpu;
172 		__entry->prev_vector	= prev_vector;
173 		__entry->prev_cpu	= prev_cpu;
174 
175 	),
176 
177 	TP_printk("irq=%u vector=%u cpu=%u prev_vector=%u prev_cpu=%u",
178 		  __entry->irq, __entry->vector, __entry->cpu,
179 		  __entry->prev_vector, __entry->prev_cpu)
180 );
181 
182 #define DEFINE_IRQ_VECTOR_MOD_EVENT(name)				\
183 DEFINE_EVENT_FN(vector_mod, name,					\
184 	TP_PROTO(unsigned int irq, unsigned int vector,			\
185 		 unsigned int cpu, unsigned int prev_vector,		\
186 		 unsigned int prev_cpu),				\
187 	TP_ARGS(irq, vector, cpu, prev_vector, prev_cpu), NULL, NULL);	\
188 
189 DEFINE_IRQ_VECTOR_MOD_EVENT(vector_update);
190 DEFINE_IRQ_VECTOR_MOD_EVENT(vector_clear);
191 
192 DECLARE_EVENT_CLASS(vector_reserve,
193 
194 	TP_PROTO(unsigned int irq, int ret),
195 
196 	TP_ARGS(irq, ret),
197 
198 	TP_STRUCT__entry(
199 		__field(	unsigned int,	irq	)
200 		__field(	int,		ret	)
201 	),
202 
203 	TP_fast_assign(
204 		__entry->irq = irq;
205 		__entry->ret = ret;
206 	),
207 
208 	TP_printk("irq=%u ret=%d", __entry->irq, __entry->ret)
209 );
210 
211 #define DEFINE_IRQ_VECTOR_RESERVE_EVENT(name)	\
212 DEFINE_EVENT_FN(vector_reserve, name,	\
213 	TP_PROTO(unsigned int irq, int ret),	\
214 	TP_ARGS(irq, ret), NULL, NULL);		\
215 
216 DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve_managed);
217 DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve);
218 
219 TRACE_EVENT(vector_alloc,
220 
221 	TP_PROTO(unsigned int irq, unsigned int vector, bool reserved,
222 		 int ret),
223 
224 	TP_ARGS(irq, vector, reserved, ret),
225 
226 	TP_STRUCT__entry(
227 		__field(	unsigned int,	irq		)
228 		__field(	unsigned int,	vector		)
229 		__field(	bool,		reserved	)
230 		__field(	int,		ret		)
231 	),
232 
233 	TP_fast_assign(
234 		__entry->irq		= irq;
235 		__entry->vector		= ret < 0 ? 0 : vector;
236 		__entry->reserved	= reserved;
237 		__entry->ret		= ret > 0 ? 0 : ret;
238 	),
239 
240 	TP_printk("irq=%u vector=%u reserved=%d ret=%d",
241 		  __entry->irq, __entry->vector,
242 		  __entry->reserved, __entry->ret)
243 );
244 
245 TRACE_EVENT(vector_alloc_managed,
246 
247 	TP_PROTO(unsigned int irq, unsigned int vector,
248 		 int ret),
249 
250 	TP_ARGS(irq, vector, ret),
251 
252 	TP_STRUCT__entry(
253 		__field(	unsigned int,	irq		)
254 		__field(	unsigned int,	vector		)
255 		__field(	int,		ret		)
256 	),
257 
258 	TP_fast_assign(
259 		__entry->irq		= irq;
260 		__entry->vector		= ret < 0 ? 0 : vector;
261 		__entry->ret		= ret > 0 ? 0 : ret;
262 	),
263 
264 	TP_printk("irq=%u vector=%u ret=%d",
265 		  __entry->irq, __entry->vector, __entry->ret)
266 );
267 
268 DECLARE_EVENT_CLASS(vector_activate,
269 
270 	TP_PROTO(unsigned int irq, bool is_managed, bool can_reserve,
271 		 bool reserve),
272 
273 	TP_ARGS(irq, is_managed, can_reserve, reserve),
274 
275 	TP_STRUCT__entry(
276 		__field(	unsigned int,	irq		)
277 		__field(	bool,		is_managed	)
278 		__field(	bool,		can_reserve	)
279 		__field(	bool,		reserve		)
280 	),
281 
282 	TP_fast_assign(
283 		__entry->irq		= irq;
284 		__entry->is_managed	= is_managed;
285 		__entry->can_reserve	= can_reserve;
286 		__entry->reserve	= reserve;
287 	),
288 
289 	TP_printk("irq=%u is_managed=%d can_reserve=%d reserve=%d",
290 		  __entry->irq, __entry->is_managed, __entry->can_reserve,
291 		  __entry->reserve)
292 );
293 
294 #define DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(name)				\
295 DEFINE_EVENT_FN(vector_activate, name,					\
296 	TP_PROTO(unsigned int irq, bool is_managed,			\
297 		 bool can_reserve, bool reserve),			\
298 	TP_ARGS(irq, is_managed, can_reserve, reserve), NULL, NULL);	\
299 
300 DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_activate);
301 DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_deactivate);
302 
303 TRACE_EVENT(vector_teardown,
304 
305 	TP_PROTO(unsigned int irq, bool is_managed, bool has_reserved),
306 
307 	TP_ARGS(irq, is_managed, has_reserved),
308 
309 	TP_STRUCT__entry(
310 		__field(	unsigned int,	irq		)
311 		__field(	bool,		is_managed	)
312 		__field(	bool,		has_reserved	)
313 	),
314 
315 	TP_fast_assign(
316 		__entry->irq		= irq;
317 		__entry->is_managed	= is_managed;
318 		__entry->has_reserved	= has_reserved;
319 	),
320 
321 	TP_printk("irq=%u is_managed=%d has_reserved=%d",
322 		  __entry->irq, __entry->is_managed, __entry->has_reserved)
323 );
324 
325 TRACE_EVENT(vector_setup,
326 
327 	TP_PROTO(unsigned int irq, bool is_legacy, int ret),
328 
329 	TP_ARGS(irq, is_legacy, ret),
330 
331 	TP_STRUCT__entry(
332 		__field(	unsigned int,	irq		)
333 		__field(	bool,		is_legacy	)
334 		__field(	int,		ret		)
335 	),
336 
337 	TP_fast_assign(
338 		__entry->irq		= irq;
339 		__entry->is_legacy	= is_legacy;
340 		__entry->ret		= ret;
341 	),
342 
343 	TP_printk("irq=%u is_legacy=%d ret=%d",
344 		  __entry->irq, __entry->is_legacy, __entry->ret)
345 );
346 
347 TRACE_EVENT(vector_free_moved,
348 
349 	TP_PROTO(unsigned int irq, unsigned int cpu, unsigned int vector,
350 		 bool is_managed),
351 
352 	TP_ARGS(irq, cpu, vector, is_managed),
353 
354 	TP_STRUCT__entry(
355 		__field(	unsigned int,	irq		)
356 		__field(	unsigned int,	cpu		)
357 		__field(	unsigned int,	vector		)
358 		__field(	bool,		is_managed	)
359 	),
360 
361 	TP_fast_assign(
362 		__entry->irq		= irq;
363 		__entry->cpu		= cpu;
364 		__entry->vector		= vector;
365 		__entry->is_managed	= is_managed;
366 	),
367 
368 	TP_printk("irq=%u cpu=%u vector=%u is_managed=%d",
369 		  __entry->irq, __entry->cpu, __entry->vector,
370 		  __entry->is_managed)
371 );
372 
373 
374 #endif /* CONFIG_X86_LOCAL_APIC */
375 
376 #undef TRACE_INCLUDE_PATH
377 #undef TRACE_INCLUDE_FILE
378 #define TRACE_INCLUDE_PATH .
379 #define TRACE_INCLUDE_FILE irq_vectors
380 #endif /*  _TRACE_IRQ_VECTORS_H */
381 
382 /* This part must be outside protection */
383 #include <trace/define_trace.h>
384