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