Messages in this thread Patch in this message | | | Subject | [PATCH] linux-2.4.23-pre2_proc-interrupts-fix_A1 | From | john stultz <> | Date | 30 Aug 2003 12:20:45 -0700 |
| |
Marcelo, All,
This patch converts /proc/interrupts to use the seq_file interface on i386 (thanks to Randy for adding the seq "single" code). This prevents memory corruption caused by /proc/interrupts overflowing its page sized buffer on systems with high cpu and interrupt counts.
Please consider for inclusion.
thanks -john
diff -Nru a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c --- a/arch/i386/kernel/irq.c Sat Aug 30 12:02:26 2003 +++ b/arch/i386/kernel/irq.c Sat Aug 30 12:02:26 2003 @@ -32,6 +32,7 @@ #include <linux/kernel_stat.h> #include <linux/irq.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/atomic.h> #include <asm/io.h> @@ -131,55 +132,55 @@ * Generic, controller-independent functions: */ -int get_irq_list(char *buf) +int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; - char *p = buf; - p += sprintf(p, " "); + seq_printf(p, " "); for (j=0; j<smp_num_cpus; j++) - p += sprintf(p, "CPU%d ",j); - *p++ = '\n'; + seq_printf(p, "CPU%d ",j); + seq_putc(p,'\n'); for (i = 0 ; i < NR_IRQS ; i++) { action = irq_desc[i].action; if (!action) continue; - p += sprintf(p, "%3d: ",i); + seq_printf(p, "%3d: ",i); #ifndef CONFIG_SMP - p += sprintf(p, "%10u ", kstat_irqs(i)); + seq_printf(p, "%10u ", kstat_irqs(i)); #else for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", kstat.irqs[cpu_logical_map(j)][i]); #endif - p += sprintf(p, " %14s", irq_desc[i].handler->typename); - p += sprintf(p, " %s", action->name); + seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) - p += sprintf(p, ", %s", action->name); - *p++ = '\n'; + seq_printf(p, ", %s", action->name); + seq_putc(p,'\n'); } - p += sprintf(p, "NMI: "); + seq_printf(p, "NMI: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", nmi_count(cpu_logical_map(j))); - p += sprintf(p, "\n"); + seq_printf(p, "\n"); #if CONFIG_X86_LOCAL_APIC - p += sprintf(p, "LOC: "); + seq_printf(p, "LOC: "); for (j = 0; j < smp_num_cpus; j++) - p += sprintf(p, "%10u ", + seq_printf(p, "%10u ", apic_timer_irqs[cpu_logical_map(j)]); - p += sprintf(p, "\n"); + seq_printf(p, "\n"); #endif - p += sprintf(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 - p += sprintf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); #endif #endif - return p - buf; + + return 0; } diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c --- a/fs/proc/proc_misc.c Sat Aug 30 12:02:26 2003 +++ b/fs/proc/proc_misc.c Sat Aug 30 12:02:26 2003 @@ -58,7 +58,9 @@ extern int get_device_list(char *); extern int get_filesystem_list(char *); extern int get_exec_domain_list(char *); +#ifndef CONFIG_X86 extern int get_irq_list(char *); +#endif extern int get_dma_list(char *); extern int get_locks_status (char *, char **, off_t, int); extern int get_swaparea_info (char *); @@ -389,6 +391,7 @@ return proc_calc_metrics(page, start, off, count, eof, len); } +#ifndef CONFIG_X86 #if !defined(CONFIG_ARCH_S390) static int interrupts_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) @@ -398,6 +401,35 @@ } #endif +#else /* !CONFIG_X86 */ + +extern int show_interrupts(struct seq_file *p, void *v); +static int interrupts_open(struct inode *inode, struct file *file) +{ + unsigned size = PAGE_SIZE * (1 + smp_num_cpus / 8); + char *buf = kmalloc(size, GFP_KERNEL); + struct seq_file *m; + int res; + + if (!buf) + return -ENOMEM; + res = single_open(file, show_interrupts, NULL); + if (!res) { + m = file->private_data; + m->buf = buf; + m->size = size; + } else + kfree(buf); + return res; +} +static struct file_operations proc_interrupts_operations = { + .open = interrupts_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; +#endif /* !CONFIG_X86 */ + static int filesystems_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -588,7 +620,7 @@ #endif {"stat", kstat_read_proc}, {"devices", devices_read_proc}, -#if !defined(CONFIG_ARCH_S390) +#if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_X86) {"interrupts", interrupts_read_proc}, #endif {"filesystems", filesystems_read_proc}, @@ -614,6 +646,9 @@ if (entry) entry->proc_fops = &proc_kmsg_operations; create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); +#if defined(CONFIG_X86) + create_seq_entry("interrupts", 0, &proc_interrupts_operations); +#endif create_seq_entry("partitions", 0, &proc_partitions_operations); create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); #ifdef CONFIG_MODULES
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |