Module: xenomai-forge Branch: master Commit: d1948fac8c299346fe8e3d9813921a3ce8629ed2 URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=d1948fac8c299346fe8e3d9813921a3ce8629ed2
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Wed Oct 17 12:49:51 2012 +0200 cobalt/kernel/intr: 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/cobalt/kernel/intr.h | 4 +++ kernel/cobalt/intr.c | 48 ++++++++++++++++++++--------------------- kernel/cobalt/sched.c | 25 +++++++++++++++++++++ 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/include/cobalt/kernel/intr.h b/include/cobalt/kernel/intr.h index 7c29b97..8f3c40d 100644 --- a/include/cobalt/kernel/intr.h +++ b/include/cobalt/kernel/intr.h @@ -133,6 +133,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/kernel/cobalt/intr.c b/kernel/cobalt/intr.c index b05aeff..638be6a 100644 --- a/kernel/cobalt/intr.c +++ b/kernel/cobalt/intr.c @@ -23,6 +23,8 @@ * @{ */ +#include <linux/mutex.h> + #include <cobalt/kernel/sched.h> #include <cobalt/kernel/intr.h> #include <cobalt/kernel/stat.h> @@ -31,7 +33,7 @@ #define XNINTR_MAX_UNHANDLED 1000 -DEFINE_PRIVATE_XNLOCK(intrlock); +static DEFINE_MUTEX(intrlock); #ifdef CONFIG_XENO_OPT_STATS xnintr_t nktimer; /* Only for statistics */ @@ -723,7 +725,6 @@ EXPORT_SYMBOL_GPL(xnintr_destroy); int xnintr_attach(xnintr_t *intr, void *cookie) { int ret; - spl_t s; secondary_mode_only(); @@ -737,7 +738,7 @@ int xnintr_attach(xnintr_t *intr, void *cookie) ipipe_set_irq_affinity(intr->irq, nkaffinity); #endif /* CONFIG_SMP */ - xnlock_get_irqsave(&intrlock, s); + mutex_lock(&intrlock); if (intr->flags & XN_ISR_ATTACHED) { ret = -EBUSY; @@ -751,7 +752,7 @@ int xnintr_attach(xnintr_t *intr, void *cookie) intr->flags |= XN_ISR_ATTACHED; stat_counter_inc(); out: - xnlock_put_irqrestore(&intrlock, s); + mutex_lock(&intrlock); return ret; } @@ -784,13 +785,11 @@ EXPORT_SYMBOL_GPL(xnintr_attach); */ void xnintr_detach(xnintr_t *intr) { - spl_t s; - secondary_mode_only(); trace_mark(xn_nucleus, irq_detach, "irq %u", intr->irq); - xnlock_get_irqsave(&intrlock, s); + mutex_lock(&intrlock); if (intr->flags & XN_ISR_ATTACHED) { intr->flags &= ~XN_ISR_ATTACHED; @@ -798,7 +797,7 @@ void xnintr_detach(xnintr_t *intr) stat_counter_dec(); } - xnlock_put_irqrestore(&intrlock, s); + mutex_unlock(&intrlock); } EXPORT_SYMBOL_GPL(xnintr_detach); @@ -901,6 +900,15 @@ static inline int xnintr_is_timer_irq(int irq) } #ifdef CONFIG_XENO_OPT_STATS +int xnintr_get_query_lock(void) +{ + return mutex_lock_interruptible(&intrlock) ? -ERESTARTSYS : 0; +} + +void xnintr_put_query_lock(void) +{ + mutex_unlock(&intrlock); +} int xnintr_query_init(xnintr_iterator_t *iterator) { @@ -926,9 +934,8 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) { struct xnirqstat *statp; xnticks_t last_switch; - int ret = 0, cpu; xnintr_t *intr; - spl_t s; + int cpu; for (cpu = iterator->cpu + 1; cpu < num_present_cpus(); ++cpu) { if (cpu_online(cpu)) @@ -938,12 +945,8 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) cpu = 0; iterator->cpu = cpu; - xnlock_get_irqsave(&intrlock, s); - - if (iterator->list_rev != xnintr_list_rev) { - ret = -EAGAIN; - goto unlock_and_exit; - } + if (iterator->list_rev != xnintr_list_rev) + return -EAGAIN; if (!iterator->prev) { if (xnintr_is_timer_irq(irq)) @@ -956,8 +959,7 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) if (intr == NULL) { cpu = -1; iterator->prev = NULL; - ret = -ENODEV; - goto unlock_and_exit; + return -ENODEV; } snprintf(name_buf, XNOBJECT_NAME_LEN, "IRQ%d: %s", irq, intr->name); @@ -979,10 +981,7 @@ int xnintr_query_next(int irq, xnintr_iterator_t *iterator, char *name_buf) if (cpu + 1 == num_present_cpus()) iterator->prev = intr; -unlock_and_exit: - xnlock_put_irqrestore(&intrlock, s); - - return ret; + return 0; } #endif /* CONFIG_XENO_OPT_STATS */ @@ -994,7 +993,6 @@ static inline int format_irq_proc(unsigned int irq, struct xnvfile_regular_iterator *it) { struct xnintr *intr; - spl_t s; int cpu; for_each_realtime_cpu(cpu) @@ -1022,7 +1020,7 @@ static inline int format_irq_proc(unsigned int irq, } } - xnlock_get_irqsave(&intrlock, s); + mutex_lock(&intrlock); intr = xnintr_shirq_first(irq); if (intr) { @@ -1035,7 +1033,7 @@ static inline int format_irq_proc(unsigned int irq, } while (intr); } - xnlock_put_irqrestore(&intrlock, s); + mutex_unlock(&intrlock); return 0; } diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c index aab6c02..e88dbbd 100644 --- a/kernel/cobalt/sched.c +++ b/kernel/cobalt/sched.c @@ -998,6 +998,30 @@ static struct xnvfile_snapshot_ops vfile_schedlist_ops = { #ifdef CONFIG_XENO_OPT_STATS +static spl_t vfile_schedstat_lock_s; + +static int vfile_schedstat_get_lock(struct xnvfile *vfile) +{ + int ret; + + ret = xnintr_get_query_lock(); + if (ret < 0) + return ret; + xnlock_get_irqsave(&nklock, vfile_schedstat_lock_s); + return 0; +} + +static void vfile_schedstat_put_lock(struct xnvfile *vfile) +{ + xnlock_put_irqrestore(&nklock, vfile_schedstat_lock_s); + xnintr_put_query_lock(); +} + +static struct xnvfile_lock_ops vfile_schedstat_lockops = { + .get = vfile_schedstat_get_lock, + .put = vfile_schedstat_put_lock, +}; + struct vfile_schedstat_priv { int irq; struct xnthread *curr; @@ -1028,6 +1052,7 @@ static struct xnvfile_snapshot schedstat_vfile = { .datasz = sizeof(struct vfile_schedstat_data), .tag = &nkthreadlist_tag, .ops = &vfile_schedstat_ops, + .entry = { .lockops = &vfile_schedstat_lockops }, }; static int vfile_schedstat_rewind(struct xnvfile_snapshot_iterator *it) _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git