# define NR_IRQS NR_IRQS_LEGACY
#endif
+#define irq_vector_name(sirq) { sirq, #sirq }
+#define invalidate_tlb_vector_name(i) { INVALIDATE_TLB_VECTOR_END-31+i, \
+ "INVALIDATE_TLB_VECTOR" }
+
+#define irq_vector_name_table \
+ irq_vector_name(NMI_VECTOR), \
+ irq_vector_name(LOCAL_TIMER_VECTOR), \
+ irq_vector_name(ERROR_APIC_VECTOR), \
+ irq_vector_name(RESCHEDULE_VECTOR), \
+ irq_vector_name(CALL_FUNCTION_VECTOR), \
+ irq_vector_name(CALL_FUNCTION_SINGLE_VECTOR), \
+ irq_vector_name(THERMAL_APIC_VECTOR), \
+ irq_vector_name(THRESHOLD_APIC_VECTOR), \
+ irq_vector_name(REBOOT_VECTOR), \
+ irq_vector_name(SPURIOUS_APIC_VECTOR), \
+ irq_vector_name(IRQ_WORK_VECTOR), \
+ irq_vector_name(X86_PLATFORM_IPI_VECTOR), \
+ invalidate_tlb_vector_name(0), \
+ invalidate_tlb_vector_name(1), \
+ invalidate_tlb_vector_name(2), \
+ invalidate_tlb_vector_name(3), \
+ invalidate_tlb_vector_name(4), \
+ invalidate_tlb_vector_name(5), \
+ invalidate_tlb_vector_name(6), \
+ invalidate_tlb_vector_name(7), \
+ invalidate_tlb_vector_name(8), \
+ invalidate_tlb_vector_name(9), \
+ invalidate_tlb_vector_name(10), \
+ invalidate_tlb_vector_name(11), \
+ invalidate_tlb_vector_name(12), \
+ invalidate_tlb_vector_name(13), \
+ invalidate_tlb_vector_name(14), \
+ invalidate_tlb_vector_name(15), \
+ invalidate_tlb_vector_name(16), \
+ invalidate_tlb_vector_name(17), \
+ invalidate_tlb_vector_name(18), \
+ invalidate_tlb_vector_name(19), \
+ invalidate_tlb_vector_name(20), \
+ invalidate_tlb_vector_name(21), \
+ invalidate_tlb_vector_name(22), \
+ invalidate_tlb_vector_name(23), \
+ invalidate_tlb_vector_name(24), \
+ invalidate_tlb_vector_name(25), \
+ invalidate_tlb_vector_name(26), \
+ invalidate_tlb_vector_name(27), \
+ invalidate_tlb_vector_name(28), \
+ invalidate_tlb_vector_name(29), \
+ invalidate_tlb_vector_name(30), \
+ invalidate_tlb_vector_name(31)
+
#endif /* _ASM_X86_IRQ_VECTORS_H */
#include <linux/dmi.h>
#include <linux/smp.h>
#include <linux/mm.h>
+#include <trace/events/irq_vectors.h>
#include <asm/perf_event.h>
#include <asm/x86_init.h>
*/
exit_idle();
irq_enter();
+ trace_irq_vector_entry(LOCAL_TIMER_VECTOR);
local_apic_timer_interrupt();
+ trace_irq_vector_exit(LOCAL_TIMER_VECTOR);
irq_exit();
set_irq_regs(old_regs);
exit_idle();
irq_enter();
+ trace_irq_vector_entry(SPURIOUS_APIC_VECTOR);
/*
* Check if this really is a spurious interrupt and ACK it
* if it is a vectored one. Just in case...
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
pr_info("spurious APIC interrupt on CPU#%d, "
"should never happen.\n", smp_processor_id());
+ trace_irq_vector_exit(SPURIOUS_APIC_VECTOR);
irq_exit();
}
exit_idle();
irq_enter();
+ trace_irq_vector_entry(ERROR_APIC_VECTOR);
/* First tickle the hardware, only then report what went on. -- REW */
v0 = apic_read(APIC_ESR);
apic_write(APIC_ESR, 0);
apic_printk(APIC_DEBUG, KERN_CONT "\n");
+ trace_irq_vector_exit(ERROR_APIC_VECTOR);
irq_exit();
}
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/cpu.h>
+#include <trace/events/irq_vectors.h>
#include <asm/processor.h>
#include <asm/system.h>
{
exit_idle();
irq_enter();
+ trace_irq_vector_entry(THERMAL_APIC_VECTOR);
inc_irq_stat(irq_thermal_count);
smp_thermal_vector();
+ trace_irq_vector_exit(THERMAL_APIC_VECTOR);
irq_exit();
/* Ack only at the end to avoid potential reentry */
ack_APIC_irq();
*/
#include <linux/interrupt.h>
#include <linux/kernel.h>
+#include <trace/events/irq_vectors.h>
#include <asm/irq_vectors.h>
#include <asm/apic.h>
{
exit_idle();
irq_enter();
+ trace_irq_vector_entry(THRESHOLD_APIC_VECTOR);
inc_irq_stat(irq_threshold_count);
mce_threshold_vector();
+ trace_irq_vector_exit(THRESHOLD_APIC_VECTOR);
irq_exit();
/* Ack only at the end to avoid potential reentry */
ack_APIC_irq();
#include <asm/mce.h>
#include <asm/hw_irq.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/irq_vectors.h>
+
atomic_t irq_err_count;
/* Function pointer for generic interrupt vector handling */
exit_idle();
irq_enter();
-
+ trace_irq_vector_entry(X86_PLATFORM_IPI_VECTOR);
inc_irq_stat(x86_platform_ipis);
if (x86_platform_ipi_callback)
x86_platform_ipi_callback();
+ trace_irq_vector_exit(X86_PLATFORM_IPI_VECTOR);
irq_exit();
set_irq_regs(old_regs);
#include <linux/irq_work.h>
#include <linux/hardirq.h>
#include <asm/apic.h>
+#include <trace/events/irq_vectors.h>
void smp_irq_work_interrupt(struct pt_regs *regs)
{
irq_enter();
ack_APIC_irq();
+ trace_irq_vector_entry(IRQ_WORK_VECTOR);
inc_irq_stat(apic_irq_work_irqs);
irq_work_run();
+ trace_irq_vector_exit(IRQ_WORK_VECTOR);
irq_exit();
}
#include <linux/interrupt.h>
#include <linux/cpu.h>
#include <linux/gfp.h>
+#include <trace/events/irq_vectors.h>
#include <asm/mtrr.h>
#include <asm/tlbflush.h>
void smp_reschedule_interrupt(struct pt_regs *regs)
{
ack_APIC_irq();
+ trace_irq_vector_entry(RESCHEDULE_VECTOR);
inc_irq_stat(irq_resched_count);
scheduler_ipi();
+ trace_irq_vector_exit(RESCHEDULE_VECTOR);
/*
* KVM uses this interrupt to force a cpu out of guest mode
*/
{
ack_APIC_irq();
irq_enter();
+ trace_irq_vector_entry(CALL_FUNCTION_VECTOR);
generic_smp_call_function_interrupt();
inc_irq_stat(irq_call_count);
+ trace_irq_vector_exit(CALL_FUNCTION_VECTOR);
irq_exit();
}
{
ack_APIC_irq();
irq_enter();
+ trace_irq_vector_entry(CALL_FUNCTION_SINGLE_VECTOR);
generic_smp_call_function_single_interrupt();
inc_irq_stat(irq_call_count);
+ trace_irq_vector_exit(CALL_FUNCTION_SINGLE_VECTOR);
irq_exit();
}
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/io.h>
+#include <trace/events/irq_vectors.h>
#ifdef CONFIG_EISA
#include <linux/ioport.h>
do_nmi(struct pt_regs *regs, long error_code)
{
nmi_enter();
+ trace_irq_vector_entry(NMI_VECTOR);
inc_irq_stat(__nmi_count);
if (!ignore_nmis)
default_do_nmi(regs);
+ trace_irq_vector_exit(NMI_VECTOR);
nmi_exit();
}
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <trace/events/irq_vectors.h>
#include <linux/cpu.h>
#include <asm/tlbflush.h>
sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
f = &flush_state[sender];
+ trace_irq_vector_entry(INVALIDATE_TLB_VECTOR_START + sender);
if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask)))
goto out;
/*
cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask));
smp_mb__after_clear_bit();
inc_irq_stat(irq_tlb_count);
+ trace_irq_vector_exit(INVALIDATE_TLB_VECTOR_START + sender);
}
static void flush_tlb_others_ipi(const struct cpumask *cpumask,
--- /dev/null
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM irq_vectors
+
+#if !defined(_TRACE_IRQ_VECTORS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_IRQ_VECTORS_H
+
+#include <linux/tracepoint.h>
+#include <asm/irq.h>
+
+#ifndef irq_vector_name_table
+#define irq_vector_name_table { -1, NULL }
+#endif
+
+DECLARE_EVENT_CLASS(irq_vector,
+
+ TP_PROTO(int irq),
+
+ TP_ARGS(irq),
+
+ TP_STRUCT__entry(
+ __field( int, irq )
+ ),
+
+ TP_fast_assign(
+ __entry->irq = irq;
+ ),
+
+ TP_printk("irq=%d name=%s", __entry->irq,
+ __print_symbolic(__entry->irq, irq_vector_name_table))
+);
+
+/*
+ * irq_vector_entry - called before enterring a interrupt vector handler
+ */
+DEFINE_EVENT(irq_vector, irq_vector_entry,
+
+ TP_PROTO(int irq),
+
+ TP_ARGS(irq)
+);
+
+/*
+ * irq_vector_exit - called immediately after the interrupt vector
+ * handler returns
+ */
+DEFINE_EVENT(irq_vector, irq_vector_exit,
+
+ TP_PROTO(int irq),
+
+ TP_ARGS(irq)
+);
+
+#endif /* _TRACE_IRQ_VECTORS_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>