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
13extern int trace_resched_ipi_reg(void);
14extern void trace_resched_ipi_unreg(void);
15
16DECLARE_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) \
33DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \
34 TP_PROTO(int vector), \
35 TP_ARGS(vector), NULL, NULL); \
36DEFINE_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) \
41DEFINE_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); \
46DEFINE_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 */
56DEFINE_IRQ_VECTOR_EVENT(local_timer);
57
58/*
59 * spurious_apic - called when entering/exiting a spurious apic vector handler
60 */
61DEFINE_IRQ_VECTOR_EVENT(spurious_apic);
62
63/*
64 * error_apic - called when entering/exiting an error apic vector handler
65 */
66DEFINE_IRQ_VECTOR_EVENT(error_apic);
67
68/*
69 * x86_platform_ipi - called when entering/exiting a x86 platform ipi interrupt
70 * vector handler
71 */
72DEFINE_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 */
79DEFINE_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 */
90TRACE_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 */
102DEFINE_RESCHED_IPI_EVENT(reschedule);
103
104/*
105 * call_function - called when entering/exiting a call function interrupt
106 * vector handler
107 */
108DEFINE_IRQ_VECTOR_EVENT(call_function);
109
110/*
111 * call_function_single - called when entering/exiting a call function
112 * single interrupt vector handler
113 */
114DEFINE_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 */
122DEFINE_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 */
130DEFINE_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 */
138DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
139#endif
140
141TRACE_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
167DECLARE_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) \
198DEFINE_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
204DEFINE_IRQ_VECTOR_MOD_EVENT(vector_update);
205DEFINE_IRQ_VECTOR_MOD_EVENT(vector_clear);
206
207DECLARE_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) \
227DEFINE_EVENT_FN(vector_reserve, name, \
228 TP_PROTO(unsigned int irq, int ret), \
229 TP_ARGS(irq, ret), NULL, NULL); \
230
231DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve_managed);
232DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve);
233
234TRACE_EVENT(vector_alloc,
235
236 TP_PROTO(unsigned int irq, unsigned int vector, bool reserved,
237 int ret),
238
239 TP_ARGS(irq, vector, reserved, ret),
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
260TRACE_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
283DECLARE_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) \
310DEFINE_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
315DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_activate);
316DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_deactivate);
317
318TRACE_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
340TRACE_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
362TRACE_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#undef TRACE_INCLUDE_FILE
393#define TRACE_INCLUDE_PATH .
394#define TRACE_INCLUDE_FILE irq_vectors
395#endif /* _TRACE_IRQ_VECTORS_H */
396
397/* This part must be outside protection */
398#include <trace/define_trace.h>
399