From: corbet@lwn.net (Jonathan Corbet) Here, anyway, is a better version of the patch. It's less intrusive, forgoes some "cleanups" I indulged in the first time, and makes it easier to update other architectures. I did x86-64, ia_64 and ppc64 just for the heck of it, but I can't test them. 25-akpm/arch/i386/kernel/irq.c | 46 +++++++++++++++++++--------------- 25-akpm/arch/ia64/kernel/irq.c | 43 +++++++++++++++++--------------- 25-akpm/arch/ppc64/kernel/irq.c | 20 ++++++++------- 25-akpm/arch/x86_64/kernel/irq.c | 43 +++++++++++++++++--------------- 25-akpm/fs/proc/proc_misc.c | 52 +++++++++++++++++++++++++-------------- 5 files changed, 117 insertions(+), 87 deletions(-) diff -puN arch/i386/kernel/irq.c~proc-interrupts-use-seq-file arch/i386/kernel/irq.c --- 25/arch/i386/kernel/irq.c~proc-interrupts-use-seq-file Thu Nov 13 13:48:43 2003 +++ 25-akpm/arch/i386/kernel/irq.c Thu Nov 13 13:48:43 2003 @@ -139,17 +139,19 @@ atomic_t irq_mis_count; int show_interrupts(struct seq_file *p, void *v) { - int i, j; + int i = *(int *) v, j; struct irqaction * action; unsigned long flags; - seq_printf(p, " "); - for (j=0; jlock, flags); action = idesc->action; @@ -194,25 +196,26 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&idesc->lock, flags); - } - seq_puts(p, "NMI: "); - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - seq_printf(p, "%10u ", nmi_count(j)); - seq_putc(p, '\n'); + } else if (i == NR_IRQS) { + seq_puts(p, "NMI: "); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", nmi_count(j)); + seq_putc(p, '\n'); #ifdef CONFIG_X86_LOCAL_APIC - seq_puts(p, "LOC: "); - for (j = 0; j < NR_CPUS; j++) - if (cpu_online(j)) - seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs); - seq_putc(p, '\n'); + seq_puts(p, "LOC: "); + for (j = 0; j < NR_CPUS; j++) + if (cpu_online(j)) + seq_printf(p, "%10u ", irq_stat[j].apic_timer_irqs); + seq_putc(p, '\n'); #endif - seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); + seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); #ifdef CONFIG_X86_IO_APIC #ifdef APIC_MISMATCH_DEBUG - seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif #endif + } return 0; } diff -puN arch/ppc64/kernel/irq.c~proc-interrupts-use-seq-file arch/ppc64/kernel/irq.c --- 25/arch/ppc64/kernel/irq.c~proc-interrupts-use-seq-file Thu Nov 13 13:48:43 2003 +++ 25-akpm/arch/ppc64/kernel/irq.c Thu Nov 13 13:48:43 2003 @@ -323,18 +323,20 @@ EXPORT_SYMBOL(enable_irq); int show_interrupts(struct seq_file *p, void *v) { - int i, j; + int i = *(int *) v, j; struct irqaction * action; unsigned long flags; - seq_printf(p, " "); - for (j=0; jhandler) @@ -359,8 +361,8 @@ int show_interrupts(struct seq_file *p, seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } - seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); + } else if (i == NR_IRQS) + seq_printf(p, "BAD: %10u\n", ppc_spurious_interrupts); return 0; } diff -puN arch/x86_64/kernel/irq.c~proc-interrupts-use-seq-file arch/x86_64/kernel/irq.c --- 25/arch/x86_64/kernel/irq.c~proc-interrupts-use-seq-file Thu Nov 13 13:48:43 2003 +++ 25-akpm/arch/x86_64/kernel/irq.c Thu Nov 13 13:48:43 2003 @@ -138,17 +138,19 @@ atomic_t irq_mis_count; int show_interrupts(struct seq_file *p, void *v) { - int i, j; + int i = *(int *) v, j; struct irqaction * action; unsigned long flags; - seq_printf(p, " "); - for (j=0; jprivate_data; - m->buf = buf; - m->size = size; - } else - kfree(buf); - return res; + return (*pos <= NR_IRQS) ? pos : NULL; } + +static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos) +{ + (*pos)++; + if (*pos > NR_IRQS) + return NULL; + return pos; +} + +static void int_seq_stop(struct seq_file *f, void *v) +{ + /* Nothing to do */ +} + + +extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */ +static struct seq_operations int_seq_ops = { + .start = int_seq_start, + .next = int_seq_next, + .stop = int_seq_stop, + .show = show_interrupts +}; + +int interrupts_open(struct inode *inode, struct file *filp) +{ + return seq_open(filp, &int_seq_ops); +} + static struct file_operations proc_interrupts_operations = { .open = interrupts_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; static int filesystems_read_proc(char *page, char **start, off_t off, _