Module: xenomai-jki Branch: for-upstream Commit: fbb21a59b6a3f145263487a4be16ae789d06a968 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=fbb21a59b6a3f145263487a4be16ae789d06a968
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Wed Oct 17 12:49:51 2012 +0200 nucleus: Convert intrlock to a sleeping Linux lock Conceptually, all users of this lock are supposed to run over Linux context already. Moreover, latest I-pipe patches complain that ipipe_virtualize_irq is called with the Xenomai domain stalled which invalidates that useful internal bug check. So rework the locking for dumping scheduling statistics and convert intrlock to a sleeping Linux variant to avoid the alarm. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- include/nucleus/intr.h | 4 ++++ ksrc/nucleus/intr.c | 45 +++++++++++++++++++++------------------------ ksrc/nucleus/sched.c | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 24 deletions(-) diff --git a/include/nucleus/intr.h b/include/nucleus/intr.h index 20a625d..8f84f2d 100644 --- a/include/nucleus/intr.h +++ b/include/nucleus/intr.h @@ -131,6 +131,10 @@ void xnintr_affinity(xnintr_t *intr, int xnintr_query_init(xnintr_iterator_t *iterator); +int xnintr_get_query_lock(void); + +void xnintr_put_query_lock(void); + int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf); diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c index b63b3cd..d10d281 100644 --- a/ksrc/nucleus/intr.c +++ b/ksrc/nucleus/intr.c @@ -39,7 +39,7 @@ #define XNINTR_MAX_UNHANDLED 1000 -DEFINE_PRIVATE_XNLOCK(intrlock); +static DEFINE_BINARY_SEMAPHORE(intrlock); #ifdef CONFIG_XENO_OPT_STATS xnintr_t nkclock; /* Only for statistics */ @@ -709,7 +709,6 @@ EXPORT_SYMBOL_GPL(xnintr_destroy); int xnintr_attach(xnintr_t *intr, void *cookie) { int ret; - spl_t s; trace_mark(xn_nucleus, irq_attach, "irq %u name %s", intr->irq, intr->name); @@ -721,7 +720,7 @@ int xnintr_attach(xnintr_t *intr, void *cookie) xnarch_set_irq_affinity(intr->irq, nkaffinity); #endif /* CONFIG_SMP */ - xnlock_get_irqsave(&intrlock, s); + down(&intrlock); if (__testbits(intr->flags, XN_ISR_ATTACHED)) { ret = -EBUSY; @@ -735,7 +734,7 @@ int xnintr_attach(xnintr_t *intr, void *cookie) __setbits(intr->flags, XN_ISR_ATTACHED); xnintr_stat_counter_inc(); out: - xnlock_put_irqrestore(&intrlock, s); + up(&intrlock); return ret; } @@ -775,11 +774,10 @@ EXPORT_SYMBOL_GPL(xnintr_attach); int xnintr_detach(xnintr_t *intr) { int ret; - spl_t s; trace_mark(xn_nucleus, irq_detach, "irq %u", intr->irq); - xnlock_get_irqsave(&intrlock, s); + down(&intrlock); if (!__testbits(intr->flags, XN_ISR_ATTACHED)) { ret = -EINVAL; @@ -794,7 +792,7 @@ int xnintr_detach(xnintr_t *intr) xnintr_stat_counter_dec(); out: - xnlock_put_irqrestore(&intrlock, s); + up(&intrlock); return ret; } @@ -894,6 +892,16 @@ void xnintr_affinity(xnintr_t *intr, xnarch_cpumask_t cpumask) EXPORT_SYMBOL_GPL(xnintr_affinity); #ifdef CONFIG_XENO_OPT_STATS +int xnintr_get_query_lock(void) +{ + return down_interruptible(&intrlock) ? -ERESTARTSYS : 0; +} + +void xnintr_put_query_lock(void) +{ + up(&intrlock); +} + int xnintr_query_init(xnintr_iterator_t *iterator) { iterator->cpu = -1; @@ -929,19 +937,13 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) xnintr_t *intr; xnticks_t last_switch; int cpu_no = iterator->cpu + 1; - int err = 0; - spl_t s; if (cpu_no == xnarch_num_online_cpus()) cpu_no = 0; iterator->cpu = cpu_no; - xnlock_get_irqsave(&intrlock, s); - - if (iterator->list_rev != xnintr_list_rev) { - err = -EAGAIN; - goto unlock_and_exit; - } + if (iterator->list_rev != xnintr_list_rev) + return -EAGAIN; if (!iterator->prev) { if (xnintr_is_timer_irq(irq)) @@ -954,8 +956,7 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) if (!intr) { cpu_no = -1; iterator->prev = NULL; - err = -ENODEV; - goto unlock_and_exit; + return -ENODEV; } snprintf(name_buf, XNOBJECT_NAME_LEN, "IRQ%d: %s", irq, intr->name); @@ -978,10 +979,7 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) if (cpu_no + 1 == xnarch_num_online_cpus()) iterator->prev = intr; - unlock_and_exit: - xnlock_put_irqrestore(&intrlock, s); - - return err; + return 0; } #endif /* CONFIG_XENO_OPT_STATS */ @@ -993,7 +991,6 @@ static inline int format_irq_proc(unsigned int irq, struct xnvfile_regular_iterator *it) { struct xnintr *intr; - spl_t s; if (xnintr_is_timer_irq(irq)) { xnvfile_puts(it, " [timer]"); @@ -1019,7 +1016,7 @@ static inline int format_irq_proc(unsigned int irq, return 0; } - xnlock_get_irqsave(&intrlock, s); + down(&intrlock); intr = xnintr_shirq_first(irq); if (intr) { @@ -1032,7 +1029,7 @@ static inline int format_irq_proc(unsigned int irq, } while (intr); } - xnlock_put_irqrestore(&intrlock, s); + up(&intrlock); return 0; } diff --git a/ksrc/nucleus/sched.c b/ksrc/nucleus/sched.c index 5d2f074..194497e 100644 --- a/ksrc/nucleus/sched.c +++ b/ksrc/nucleus/sched.c @@ -839,11 +839,36 @@ struct vfile_stat_data { static struct xnvfile_snapshot_ops vfile_stat_ops; +static spl_t vfile_stat_lock_s; + +static int vfile_stat_get_lock(struct xnvfile *vfile) +{ + int ret; + + ret = xnintr_get_query_lock(); + if (ret < 0) + return ret; + xnlock_get_irqsave(&nklock, vfile_stat_lock_s); + return 0; +} + +static void vfile_stat_put_lock(struct xnvfile *vfile) +{ + xnlock_put_irqrestore(&nklock, vfile_stat_lock_s); + xnintr_put_query_lock(); +} + +static struct xnvfile_lock_ops vfile_stat_lockops = { + .get = vfile_stat_get_lock, + .put = vfile_stat_put_lock, +}; + static struct xnvfile_snapshot stat_vfile = { .privsz = sizeof(struct vfile_stat_priv), .datasz = sizeof(struct vfile_stat_data), .tag = &nkpod_struct.threadlist_tag, .ops = &vfile_stat_ops, + .entry = { .lockops = &vfile_stat_lockops }, }; static int vfile_stat_rewind(struct xnvfile_snapshot_iterator *it) _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git