Module: xenomai-jki Branch: queues/proc Commit: 874570fd2240b2f49c10602e8d3e22d6964bb5a0 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=874570fd2240b2f49c10602e8d3e22d6964bb5a0
Author: Wolfgang Mauerer <wolfgang.maue...@siemens.com> Date: Fri Apr 16 18:07:31 2010 +0200 nucleus: Convert irq proc entry to seqfile On a system with many CPUs, the size of the data can exceed a single page. Signed-off-by: Wolfgang Mauerer <wolfgang.maue...@siemens.com> Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- ksrc/nucleus/intr.c | 149 +++++++++++++++++++++++++++++++-------------------- 1 files changed, 90 insertions(+), 59 deletions(-) diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c index a6de4ea..79fa3e4 100644 --- a/ksrc/nucleus/intr.c +++ b/ksrc/nucleus/intr.c @@ -984,27 +984,27 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) #ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/ctype.h> -static int format_irq_proc(unsigned int irq, char *str) +static void format_irq_proc(unsigned int irq, struct seq_file *f) { xnintr_t *intr; - char *p = str; spl_t s; if (rthal_virtual_irq_p(irq)) { - p += sprintf(p, " [virtual]"); - return p - str; + seq_puts(f, " [virtual]"); + return; } else if (irq == XNARCH_TIMER_IRQ) { - p += sprintf(p, " [timer]"); - return p - str; + seq_puts(f, " [timer]"); + return ; #ifdef CONFIG_SMP } else if (irq == RTHAL_SERVICE_IPI0) { - p += sprintf(p, " [IPI]"); - return p - str; + seq_puts(f, " [IPI]"); + return; } else if (irq == RTHAL_CRITICAL_IPI) { - p += sprintf(p, " [critical sync]"); - return p - str; + seq_puts(f, " [critical sync]"); + return; #endif /* CONFIG_SMP */ } @@ -1012,61 +1012,17 @@ static int format_irq_proc(unsigned int irq, char *str) intr = xnintr_shirq_first(irq); if (intr) { - strcpy(p, " "); p += 8; + seq_puts(f, " "); do { - *p = ' '; p += 1; - strcpy(p, intr->name); p += strlen(intr->name); + seq_putc(f, ' '); + seq_printf(f, "%s", intr->name); intr = xnintr_shirq_next(intr); } while (intr); } xnlock_put_irqrestore(&intrlock, s); - - return p - str; -} - -static int irq_read_proc(char *page, - char **start, - off_t off, int count, int *eof, void *data) -{ - int len = 0, cpu, irq; - char *p = page; - - p += sprintf(p, "IRQ "); - - for_each_online_cpu(cpu) { - p += sprintf(p, " CPU%d", cpu); - } - - for (irq = 0; irq < XNARCH_NR_IRQS; irq++) { - if (rthal_irq_handler(&rthal_domain, irq) == NULL) - continue; - - p += sprintf(p, "\n%3d:", irq); - - for_each_online_cpu(cpu) { - p += sprintf(p, "%12lu", - rthal_cpudata_irq_hits(&rthal_domain, cpu, - irq)); - } - - p += format_irq_proc(irq, p); - } - - p += sprintf(p, "\n"); - - len = p - page - off; - if (len <= off + count) - *eof = 1; - *start = page + off; - if (len > count) - len = count; - if (len < 0) - len = 0; - - return len; } #ifdef CONFIG_SMP @@ -1094,6 +1050,75 @@ static int affinity_read_proc(char *page, return len; } +static void *irq_seq_start(struct seq_file *seq, loff_t *pos) +{ + /* + * Note: Position 0 is the header, so we need to + * use <= instead of < + */ + return (*pos <= XNARCH_NR_IRQS) ? pos : NULL; +} + +static void irq_seq_stop(struct seq_file *f, void *v) +{ + /* Nothing to do */ +} + +static void *irq_seq_next(struct seq_file *f, void *v, loff_t *pos) +{ + (*pos)++; + + if (*pos > XNARCH_NR_IRQS) + return NULL; + + return pos; +} + +static int irq_seq_show(struct seq_file *f, void *v) +{ + unsigned int i = *(loff_t *) v; + unsigned int irq, cpu; + + if (i == 0) { + seq_puts(f, "IRQ "); + for_each_online_cpu(cpu) { + seq_printf(f, " CPU%u", cpu); + } + seq_putc(f, '\n'); + + return 0; + } + + irq = i - 1; + if (rthal_irq_handler(&rthal_domain, irq) == NULL) + return 0; + + seq_printf(f, "%3d:", irq); + + for_each_online_cpu(cpu) { + seq_printf(f, "%12lu", + rthal_cpudata_irq_hits(&rthal_domain, cpu, + irq)); + } + + format_irq_proc(irq, f); + seq_putc(f, '\n'); + + return 0; +} + +static struct seq_operations irq_seq_ops = { + .start = irq_seq_start, + .next = irq_seq_next, + .stop = irq_seq_stop, + .show = irq_seq_show, +}; + +static int irq_open(struct inode *inode, struct file *filp) +{ + return seq_open(filp, &irq_seq_ops); +} + static int affinity_write_proc(struct file *file, const char __user * buffer, unsigned long count, void *data) @@ -1124,10 +1149,16 @@ static int affinity_write_proc(struct file *file, } #endif /* CONFIG_SMP */ +static struct file_operations irq_seq_operations = { + .open = irq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + void xnintr_init_proc(void) { - rthal_add_proc_leaf("irq", &irq_read_proc, NULL, NULL, - rthal_proc_root); + rthal_add_proc_seq("irq", &irq_seq_operations, 0, rthal_proc_root); #ifdef CONFIG_SMP rthal_add_proc_leaf("affinity", &affinity_read_proc, &affinity_write_proc, NULL, rthal_proc_root); _______________________________________________ Xenomai-git mailing list Xenomai-git@gna.org https://mail.gna.org/listinfo/xenomai-git