]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/x86/kernel/apic/apic.c
Merge branch 'x86-tracing-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[karo-tx-linux.git] / arch / x86 / kernel / apic / apic.c
index 1600b1ca4f04615958e2ebb94dbd5f9df873bcbc..99663b59123a0066fe42a427bb2a2cb51b8b8a55 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/smp.h>
 #include <linux/mm.h>
 
+#include <asm/trace/irq_vectors.h>
 #include <asm/irq_remapping.h>
 #include <asm/perf_event.h>
 #include <asm/x86_init.h>
@@ -919,17 +920,35 @@ void __irq_entry smp_apic_timer_interrupt(struct pt_regs *regs)
        /*
         * NOTE! We'd better ACK the irq immediately,
         * because timer handling can be slow.
+        *
+        * update_process_times() expects us to have done irq_enter().
+        * Besides, if we don't timer interrupts ignore the global
+        * interrupt lock, which is the WrongThing (tm) to do.
         */
-       ack_APIC_irq();
+       entering_ack_irq();
+       local_apic_timer_interrupt();
+       exiting_irq();
+
+       set_irq_regs(old_regs);
+}
+
+void __irq_entry smp_trace_apic_timer_interrupt(struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+
        /*
+        * NOTE! We'd better ACK the irq immediately,
+        * because timer handling can be slow.
+        *
         * update_process_times() expects us to have done irq_enter().
         * Besides, if we don't timer interrupts ignore the global
         * interrupt lock, which is the WrongThing (tm) to do.
         */
-       irq_enter();
-       exit_idle();
+       entering_ack_irq();
+       trace_local_timer_entry(LOCAL_TIMER_VECTOR);
        local_apic_timer_interrupt();
-       irq_exit();
+       trace_local_timer_exit(LOCAL_TIMER_VECTOR);
+       exiting_irq();
 
        set_irq_regs(old_regs);
 }
@@ -1907,12 +1926,10 @@ int __init APIC_init_uniprocessor(void)
 /*
  * This interrupt should _never_ happen with our APIC/SMP architecture
  */
-void smp_spurious_interrupt(struct pt_regs *regs)
+static inline void __smp_spurious_interrupt(void)
 {
        u32 v;
 
-       irq_enter();
-       exit_idle();
        /*
         * Check if this really is a spurious interrupt and ACK it
         * if it is a vectored one.  Just in case...
@@ -1927,13 +1944,28 @@ void smp_spurious_interrupt(struct pt_regs *regs)
        /* 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());
-       irq_exit();
+}
+
+void smp_spurious_interrupt(struct pt_regs *regs)
+{
+       entering_irq();
+       __smp_spurious_interrupt();
+       exiting_irq();
+}
+
+void smp_trace_spurious_interrupt(struct pt_regs *regs)
+{
+       entering_irq();
+       trace_spurious_apic_entry(SPURIOUS_APIC_VECTOR);
+       __smp_spurious_interrupt();
+       trace_spurious_apic_exit(SPURIOUS_APIC_VECTOR);
+       exiting_irq();
 }
 
 /*
  * This interrupt should never happen with our APIC/SMP architecture
  */
-void smp_error_interrupt(struct pt_regs *regs)
+static inline void __smp_error_interrupt(struct pt_regs *regs)
 {
        u32 v0, v1;
        u32 i = 0;
@@ -1948,8 +1980,6 @@ void smp_error_interrupt(struct pt_regs *regs)
                "Illegal register address",     /* APIC Error Bit 7 */
        };
 
-       irq_enter();
-       exit_idle();
        /* First tickle the hardware, only then report what went on. -- REW */
        v0 = apic_read(APIC_ESR);
        apic_write(APIC_ESR, 0);
@@ -1970,7 +2000,22 @@ void smp_error_interrupt(struct pt_regs *regs)
 
        apic_printk(APIC_DEBUG, KERN_CONT "\n");
 
-       irq_exit();
+}
+
+void smp_error_interrupt(struct pt_regs *regs)
+{
+       entering_irq();
+       __smp_error_interrupt(regs);
+       exiting_irq();
+}
+
+void smp_trace_error_interrupt(struct pt_regs *regs)
+{
+       entering_irq();
+       trace_error_apic_entry(ERROR_APIC_VECTOR);
+       __smp_error_interrupt(regs);
+       trace_error_apic_exit(ERROR_APIC_VECTOR);
+       exiting_irq();
 }
 
 /**