irq.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Common interrupt code for 32 and 64 bit
  3. */
  4. #include <linux/cpu.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/kernel_stat.h>
  7. #include <linux/seq_file.h>
  8. #include <asm/apic.h>
  9. #include <asm/io_apic.h>
  10. #include <asm/smp.h>
  11. atomic_t irq_err_count;
  12. #ifdef CONFIG_X86_32
  13. # define irq_stats(x) (&per_cpu(irq_stat,x))
  14. #else
  15. # define irq_stats(x) cpu_pda(x)
  16. #endif
  17. /*
  18. * /proc/interrupts printing:
  19. */
  20. static int show_other_interrupts(struct seq_file *p)
  21. {
  22. int j;
  23. seq_printf(p, "NMI: ");
  24. for_each_online_cpu(j)
  25. seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
  26. seq_printf(p, " Non-maskable interrupts\n");
  27. #ifdef CONFIG_X86_LOCAL_APIC
  28. seq_printf(p, "LOC: ");
  29. for_each_online_cpu(j)
  30. seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
  31. seq_printf(p, " Local timer interrupts\n");
  32. #endif
  33. #ifdef CONFIG_SMP
  34. seq_printf(p, "RES: ");
  35. for_each_online_cpu(j)
  36. seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
  37. seq_printf(p, " Rescheduling interrupts\n");
  38. seq_printf(p, "CAL: ");
  39. for_each_online_cpu(j)
  40. seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
  41. seq_printf(p, " Function call interrupts\n");
  42. seq_printf(p, "TLB: ");
  43. for_each_online_cpu(j)
  44. seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
  45. seq_printf(p, " TLB shootdowns\n");
  46. #endif
  47. #ifdef CONFIG_X86_MCE
  48. seq_printf(p, "TRM: ");
  49. for_each_online_cpu(j)
  50. seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
  51. seq_printf(p, " Thermal event interrupts\n");
  52. # ifdef CONFIG_X86_64
  53. seq_printf(p, "THR: ");
  54. for_each_online_cpu(j)
  55. seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
  56. seq_printf(p, " Threshold APIC interrupts\n");
  57. # endif
  58. #endif
  59. #ifdef CONFIG_X86_LOCAL_APIC
  60. seq_printf(p, "SPU: ");
  61. for_each_online_cpu(j)
  62. seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
  63. seq_printf(p, " Spurious interrupts\n");
  64. #endif
  65. seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
  66. #if defined(CONFIG_X86_IO_APIC)
  67. seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
  68. #endif
  69. return 0;
  70. }
  71. int show_interrupts(struct seq_file *p, void *v)
  72. {
  73. unsigned long flags, any_count = 0;
  74. int i = *(loff_t *) v, j;
  75. struct irqaction *action;
  76. struct irq_desc *desc;
  77. if (i > nr_irqs)
  78. return 0;
  79. if (i == nr_irqs)
  80. return show_other_interrupts(p);
  81. /* print header */
  82. if (i == 0) {
  83. seq_printf(p, " ");
  84. for_each_online_cpu(j)
  85. seq_printf(p, "CPU%-8d",j);
  86. seq_putc(p, '\n');
  87. }
  88. desc = irq_to_desc(i);
  89. spin_lock_irqsave(&desc->lock, flags);
  90. #ifndef CONFIG_SMP
  91. any_count = kstat_irqs(i);
  92. #else
  93. for_each_online_cpu(j)
  94. any_count |= kstat_irqs_cpu(i, j);
  95. #endif
  96. action = desc->action;
  97. if (!action && !any_count)
  98. goto out;
  99. seq_printf(p, "%3d: ", i);
  100. #ifndef CONFIG_SMP
  101. seq_printf(p, "%10u ", kstat_irqs(i));
  102. #else
  103. for_each_online_cpu(j)
  104. seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
  105. #endif
  106. seq_printf(p, " %8s", desc->chip->name);
  107. seq_printf(p, "-%-8s", desc->name);
  108. if (action) {
  109. seq_printf(p, " %s", action->name);
  110. while ((action = action->next) != NULL)
  111. seq_printf(p, ", %s", action->name);
  112. }
  113. seq_putc(p, '\n');
  114. out:
  115. spin_unlock_irqrestore(&desc->lock, flags);
  116. return 0;
  117. }
  118. /*
  119. * /proc/stat helpers
  120. */
  121. u64 arch_irq_stat_cpu(unsigned int cpu)
  122. {
  123. u64 sum = irq_stats(cpu)->__nmi_count;
  124. #ifdef CONFIG_X86_LOCAL_APIC
  125. sum += irq_stats(cpu)->apic_timer_irqs;
  126. #endif
  127. #ifdef CONFIG_SMP
  128. sum += irq_stats(cpu)->irq_resched_count;
  129. sum += irq_stats(cpu)->irq_call_count;
  130. sum += irq_stats(cpu)->irq_tlb_count;
  131. #endif
  132. #ifdef CONFIG_X86_MCE
  133. sum += irq_stats(cpu)->irq_thermal_count;
  134. # ifdef CONFIG_X86_64
  135. sum += irq_stats(cpu)->irq_threshold_count;
  136. #endif
  137. #endif
  138. #ifdef CONFIG_X86_LOCAL_APIC
  139. sum += irq_stats(cpu)->irq_spurious_count;
  140. #endif
  141. return sum;
  142. }
  143. u64 arch_irq_stat(void)
  144. {
  145. u64 sum = atomic_read(&irq_err_count);
  146. #ifdef CONFIG_X86_IO_APIC
  147. sum += atomic_read(&irq_mis_count);
  148. #endif
  149. return sum;
  150. }