x86_64: make /proc/interrupts work with dyn irq_desc
authorYinghai Lu <yhlu.kernel@gmail.com>
Wed, 20 Aug 2008 03:50:20 +0000 (20:50 -0700)
committerIngo Molnar <mingo@elte.hu>
Thu, 16 Oct 2008 14:52:51 +0000 (16:52 +0200)
loop with irq_desc list

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/irq_64.c
fs/proc/proc_misc.c

index 5d5976e0311a92720a13f7228b77d2c9c4b2d7a8..7bd841a9c6404541a1a897f91644a6afc3483c2f 100644 (file)
@@ -70,9 +70,27 @@ static inline void stack_overflow_check(struct pt_regs *regs)
 
 int show_interrupts(struct seq_file *p, void *v)
 {
-       int i = *(loff_t *) v, j;
+       int i, j;
        struct irqaction * action;
        unsigned long flags;
+       unsigned int entries;
+       struct irq_desc *desc;
+       int tail = 0;
+
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+       desc = (struct irq_desc *)v;
+       entries = -1U;
+       i = desc->irq;
+       if (!desc->next)
+               tail = 1;
+#else
+       entries = nr_irqs - 1;
+       i = *(loff_t *) v;
+       if (i == nr_irqs)
+               tail = 1;
+       else
+               desc = irq_to_desc(i);
+#endif
 
        if (i == 0) {
                seq_printf(p, "           ");
@@ -81,12 +99,8 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_putc(p, '\n');
        }
 
-       if (i < nr_irqs) {
+       if (i <= entries) {
                unsigned any_count = 0;
-               struct irq_desc *desc = irq_to_desc(i);
-
-               if (!desc)
-                       return 0;
 
                spin_lock_irqsave(&desc->lock, flags);
 #ifndef CONFIG_SMP
@@ -116,7 +130,9 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_putc(p, '\n');
 skip:
                spin_unlock_irqrestore(&desc->lock, flags);
-       } else if (i == nr_irqs) {
+       }
+
+       if (tail) {
                seq_printf(p, "NMI: ");
                for_each_online_cpu(j)
                        seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
@@ -155,6 +171,7 @@ skip:
                seq_printf(p, "  Spurious interrupts\n");
                seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
        }
+
        return 0;
 }
 
index c3cbabe8b38e2a702cf1edbeed6daf7d19e15a4d..72dd739a7f8acdecf647d0df97a5c1aaca8eb7e0 100644 (file)
@@ -645,15 +645,36 @@ static const struct file_operations proc_stat_operations = {
  */
 static void *int_seq_start(struct seq_file *f, loff_t *pos)
 {
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+       struct irq_desc *desc;
+       int irq;
+       int count = *pos;
+
+       for_each_irq_desc(irq, desc) {
+               if (count-- == 0)
+                       return desc;
+       }
+
+       return NULL;
+#else
        return (*pos <= nr_irqs) ? pos : NULL;
+#endif
 }
 
+
 static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
 {
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+       struct irq_desc *desc;
+
+       desc = ((struct irq_desc *)v)->next;
        (*pos)++;
-       if (*pos > nr_irqs)
-               return NULL;
-       return pos;
+
+       return desc;
+#else
+       (*pos)++;
+       return (*pos <= nr_irqs) ? pos : NULL;
+#endif
 }
 
 static void int_seq_stop(struct seq_file *f, void *v)
@@ -661,7 +682,6 @@ static void int_seq_stop(struct seq_file *f, void *v)
        /* Nothing to do */
 }
 
-
 static const struct seq_operations int_seq_ops = {
        .start = int_seq_start,
        .next  = int_seq_next,