1 /* SPDX-License-Identifier: GPL-2.0 */
3 #define TRACE_SYSTEM irq_vectors
5 #if !defined(_TRACE_IRQ_VECTORS_H) || defined(TRACE_HEADER_MULTI_READ)
6 #define _TRACE_IRQ_VECTORS_H
8 #include <linux/tracepoint.h>
9 #include <asm/trace/common.h>
11 #ifdef CONFIG_X86_LOCAL_APIC
13 DECLARE_EVENT_CLASS(x86_irq_vector
,
20 __field( int, vector
)
24 __entry
->vector
= vector
;
27 TP_printk("vector=%d", __entry
->vector
) );
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);
38 * local_timer - called when entering/exiting a local timer interrupt
41 DEFINE_IRQ_VECTOR_EVENT(local_timer
);
44 * spurious_apic - called when entering/exiting a spurious apic vector handler
46 DEFINE_IRQ_VECTOR_EVENT(spurious_apic
);
49 * error_apic - called when entering/exiting an error apic vector handler
51 DEFINE_IRQ_VECTOR_EVENT(error_apic
);
54 * x86_platform_ipi - called when entering/exiting a x86 platform ipi interrupt
57 DEFINE_IRQ_VECTOR_EVENT(x86_platform_ipi
);
59 #ifdef CONFIG_IRQ_WORK
61 * irq_work - called when entering/exiting a irq work interrupt
64 DEFINE_IRQ_VECTOR_EVENT(irq_work
);
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;
70 * 1) irq_work_exit happens
71 * 2) generates perf sample
72 * 3) generates irq_work
75 TRACE_EVENT_PERF_PERM(irq_work_exit
, is_sampling_event(p_event
) ? -EPERM
: 0);
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.
85 * reschedule - called when entering/exiting a reschedule vector handler
87 DEFINE_IRQ_VECTOR_EVENT(reschedule
);
90 * call_function - called when entering/exiting a call function interrupt
93 DEFINE_IRQ_VECTOR_EVENT(call_function
);
96 * call_function_single - called when entering/exiting a call function
97 * single interrupt vector handler
99 DEFINE_IRQ_VECTOR_EVENT(call_function_single
);
102 #ifdef CONFIG_X86_MCE_THRESHOLD
104 * threshold_apic - called when entering/exiting a threshold apic interrupt
107 DEFINE_IRQ_VECTOR_EVENT(threshold_apic
);
110 #ifdef CONFIG_X86_MCE_AMD
112 * deferred_error_apic - called when entering/exiting a deferred apic interrupt
115 DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic
);
118 #ifdef CONFIG_X86_THERMAL_VECTOR
120 * thermal_apic - called when entering/exiting a thermal apic interrupt
123 DEFINE_IRQ_VECTOR_EVENT(thermal_apic
);
126 TRACE_EVENT(vector_config
,
128 TP_PROTO(unsigned int irq
, unsigned int vector
,
129 unsigned int cpu
, unsigned int apicdest
),
131 TP_ARGS(irq
, vector
, cpu
, apicdest
),
134 __field( unsigned int, irq
)
135 __field( unsigned int, vector
)
136 __field( unsigned int, cpu
)
137 __field( unsigned int, apicdest
)
142 __entry
->vector
= vector
;
144 __entry
->apicdest
= apicdest
;
147 TP_printk("irq=%u vector=%u cpu=%u apicdest=0x%08x",
148 __entry
->irq
, __entry
->vector
, __entry
->cpu
,
152 DECLARE_EVENT_CLASS(vector_mod
,
154 TP_PROTO(unsigned int irq
, unsigned int vector
,
155 unsigned int cpu
, unsigned int prev_vector
,
156 unsigned int prev_cpu
),
158 TP_ARGS(irq
, vector
, cpu
, prev_vector
, prev_cpu
),
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
)
170 __entry
->vector
= vector
;
172 __entry
->prev_vector
= prev_vector
;
173 __entry
->prev_cpu
= prev_cpu
;
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
)
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); \
189 DEFINE_IRQ_VECTOR_MOD_EVENT(vector_update);
190 DEFINE_IRQ_VECTOR_MOD_EVENT(vector_clear
);
192 DECLARE_EVENT_CLASS(vector_reserve
,
194 TP_PROTO(unsigned int irq
, int ret
),
199 __field( unsigned int, irq
)
208 TP_printk("irq=%u ret=%d", __entry
->irq
, __entry
->ret
)
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); \
216 DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve_managed);
217 DEFINE_IRQ_VECTOR_RESERVE_EVENT(vector_reserve
);
219 TRACE_EVENT(vector_alloc
,
221 TP_PROTO(unsigned int irq
, unsigned int vector
, bool reserved
,
224 TP_ARGS(irq
, vector
, reserved
, ret
),
227 __field( unsigned int, irq
)
228 __field( unsigned int, vector
)
229 __field( bool, reserved
)
235 __entry
->vector
= ret
< 0 ? 0 : vector
;
236 __entry
->reserved
= reserved
;
237 __entry
->ret
= ret
> 0 ? 0 : ret
;
240 TP_printk("irq=%u vector=%u reserved=%d ret=%d",
241 __entry
->irq
, __entry
->vector
,
242 __entry
->reserved
, __entry
->ret
)
245 TRACE_EVENT(vector_alloc_managed
,
247 TP_PROTO(unsigned int irq
, unsigned int vector
,
250 TP_ARGS(irq
, vector
, ret
),
253 __field( unsigned int, irq
)
254 __field( unsigned int, vector
)
260 __entry
->vector
= ret
< 0 ? 0 : vector
;
261 __entry
->ret
= ret
> 0 ? 0 : ret
;
264 TP_printk("irq=%u vector=%u ret=%d",
265 __entry
->irq
, __entry
->vector
, __entry
->ret
)
268 DECLARE_EVENT_CLASS(vector_activate
,
270 TP_PROTO(unsigned int irq
, bool is_managed
, bool can_reserve
,
273 TP_ARGS(irq
, is_managed
, can_reserve
, reserve
),
276 __field( unsigned int, irq
)
277 __field( bool, is_managed
)
278 __field( bool, can_reserve
)
279 __field( bool, reserve
)
284 __entry
->is_managed
= is_managed
;
285 __entry
->can_reserve
= can_reserve
;
286 __entry
->reserve
= reserve
;
289 TP_printk("irq=%u is_managed=%d can_reserve=%d reserve=%d",
290 __entry
->irq
, __entry
->is_managed
, __entry
->can_reserve
,
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); \
300 DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_activate);
301 DEFINE_IRQ_VECTOR_ACTIVATE_EVENT(vector_deactivate
);
303 TRACE_EVENT(vector_teardown
,
305 TP_PROTO(unsigned int irq
, bool is_managed
, bool has_reserved
),
307 TP_ARGS(irq
, is_managed
, has_reserved
),
310 __field( unsigned int, irq
)
311 __field( bool, is_managed
)
312 __field( bool, has_reserved
)
317 __entry
->is_managed
= is_managed
;
318 __entry
->has_reserved
= has_reserved
;
321 TP_printk("irq=%u is_managed=%d has_reserved=%d",
322 __entry
->irq
, __entry
->is_managed
, __entry
->has_reserved
)
325 TRACE_EVENT(vector_setup
,
327 TP_PROTO(unsigned int irq
, bool is_legacy
, int ret
),
329 TP_ARGS(irq
, is_legacy
, ret
),
332 __field( unsigned int, irq
)
333 __field( bool, is_legacy
)
339 __entry
->is_legacy
= is_legacy
;
343 TP_printk("irq=%u is_legacy=%d ret=%d",
344 __entry
->irq
, __entry
->is_legacy
, __entry
->ret
)
347 TRACE_EVENT(vector_free_moved
,
349 TP_PROTO(unsigned int irq
, unsigned int cpu
, unsigned int vector
,
352 TP_ARGS(irq
, cpu
, vector
, is_managed
),
355 __field( unsigned int, irq
)
356 __field( unsigned int, cpu
)
357 __field( unsigned int, vector
)
358 __field( bool, is_managed
)
364 __entry
->vector
= vector
;
365 __entry
->is_managed
= is_managed
;
368 TP_printk("irq=%u cpu=%u vector=%u is_managed=%d",
369 __entry
->irq
, __entry
->cpu
, __entry
->vector
,
374 #endif /* CONFIG_X86_LOCAL_APIC */
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 */
382 /* This part must be outside protection */
383 #include <trace/define_trace.h>