Module: xenomai-jki
Branch: for-upstream
Commit: 8e6bc3b347c1282cdb717c72b31b5de3e9dbfb03
URL:    
http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=8e6bc3b347c1282cdb717c72b31b5de3e9dbfb03

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 603ae22..09ac71f 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;
 }
@@ -908,6 +906,16 @@ static bool xnintr_is_timer_irq(int irq)
 }
 
 #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;
@@ -933,19 +941,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))
@@ -958,8 +960,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);
@@ -982,10 +983,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

Reply via email to