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
13DECLARE_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) \
30DEFINE_EVENT_FN(x86_irq_vector, name##_entry, \
31 TP_PROTO(int vector), \
32 TP_ARGS(vector), NULL, NULL); \
33DEFINE_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 */
41DEFINE_IRQ_VECTOR_EVENT(local_timer);
42
43/*
44 * spurious_apic - called when entering/exiting a spurious apic vector handler
45 */
46DEFINE_IRQ_VECTOR_EVENT(spurious_apic);
47
48/*
49 * error_apic - called when entering/exiting an error apic vector handler
50 */
51DEFINE_IRQ_VECTOR_EVENT(error_apic);
52
53/*
54 * x86_platform_ipi - called when entering/exiting a x86 platform ipi interrupt
55 * vector handler
56 */
57DEFINE_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 */
64DEFINE_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 */
75TRACE_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 */
87DEFINE_IRQ_VECTOR_EVENT(reschedule);
88
89/*
90 * call_function - called when entering/exiting a call function interrupt
91 * vector handler
92 */
93DEFINE_IRQ_VECTOR_EVENT(call_function);
94
95/*
96 * call_function_single - called when entering/exiting a call function
97 * single interrupt vector handler
98 */
99DEFINE_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 */
107DEFINE_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 */
115DEFINE_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 */
123DEFINE_IRQ_VECTOR_EVENT(thermal_apic);
124#endif
125
126TRACE_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
152DECLARE_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) \
183DEFINE_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
189DEFINE_IRQ_VECTOR_MOD_EVENT(vector_update);
190DEFINE_IRQ_VECTOR_MOD_EVENT(vector_clear);
191
192DECLARE_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) \
212DEFINE_EVENT_FN(vector_reserve, name, \
213 TP_PROTO(unsigned int irq, int ret), \
214 TP_ARGS(irq, ret), NULL, NULL); \
215
216DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve_managed);
217DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve);
218
219TRACE_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
245TRACE_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
268DECLARE_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) \
295DEFINE_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
300DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_activate);
301DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_deactivate);
302
303TRACE_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
325TRACE_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
347TRACE_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

source code of linux/arch/x86/include/asm/trace/irq_vectors.h