[EMAIL PROTECTED] wrote:
> Hi,
> running a simple test application which spawns a periodic task writing on a
> serial interface
> the system hangs performing the rt_dev_close.
> The test program ran fine with xeno 2.2.6 with "Shared Interrupts" enabled,
> so as with
> xeno 2.3.1 with "Shared Interrupts" disabled. It fails with xeno 2.3.1 with
> "Shared Interrupts" enabled, so the problem seems to be in the shared
> interrupts handling area.
> kernel is 2.6.20 adeos patched
> 
> Any suggestion?

OK, the commission came to the conclusion that we may have a solution:

Could you please test this patch

    https://mail.gna.org/public/xenomai-core/2007-06/msg00091.html

and report the result to us? Oh... wait... you are on 2.3.1. Then use the
patch below. Applies against 2.3.x-SVN, but should work with the release
as well.

Thanks,
Jan


---
 ksrc/nucleus/intr.c |   68 ++++++++++++++++------------------------------------
 1 file changed, 21 insertions(+), 47 deletions(-)

Index: xenomai-2.3.x/ksrc/nucleus/intr.c
===================================================================
--- xenomai-2.3.x.orig/ksrc/nucleus/intr.c
+++ xenomai-2.3.x/ksrc/nucleus/intr.c
@@ -145,39 +145,13 @@ typedef struct xnintr_shirq {
        xnintr_t *handlers;
        int unhandled;
 #ifdef CONFIG_SMP
-       atomic_counter_t active;
+       xnlock_t lock;
 #endif
 
 } xnintr_shirq_t;
 
 static xnintr_shirq_t xnshirqs[RTHAL_NR_IRQS];
 
-static inline void xnintr_shirq_lock(xnintr_shirq_t *shirq)
-{
-#ifdef CONFIG_SMP
-       xnarch_atomic_inc(&shirq->active);
-       xnarch_memory_barrier();
-#endif
-}
-
-static inline void xnintr_shirq_unlock(xnintr_shirq_t *shirq)
-{
-#ifdef CONFIG_SMP
-       xnarch_memory_barrier();
-       xnarch_atomic_dec(&shirq->active);
-#endif
-}
-
-void xnintr_synchronize(xnintr_t *intr)
-{
-#ifdef CONFIG_SMP
-       xnintr_shirq_t *shirq = &xnshirqs[intr->irq];
-
-       while (xnarch_atomic_get(&shirq->active))
-               cpu_relax();
-#endif
-}
-
 #if defined(CONFIG_XENO_OPT_SHIRQ_LEVEL)
 /*
  * Low-level interrupt handler dispatching the user-defined ISRs for
@@ -201,7 +175,7 @@ static void xnintr_shirq_handler(unsigne
 
        ++sched->inesting;
 
-       xnintr_shirq_lock(shirq);
+       xnlock_get(&shirq->lock);
        intr = shirq->handlers;
 
        while (intr) {
@@ -222,7 +196,7 @@ static void xnintr_shirq_handler(unsigne
                intr = intr->next;
        }
 
-       xnintr_shirq_unlock(shirq);
+       xnlock_put(&shirq->lock);
 
        if (unlikely(s == XN_ISR_NONE)) {
                if (++shirq->unhandled == XNINTR_MAX_UNHANDLED) {
@@ -272,7 +246,7 @@ static void xnintr_edge_shirq_handler(un
 
        ++sched->inesting;
 
-       xnintr_shirq_lock(shirq);
+       xnlock_get(&shirq->lock);
        intr = shirq->handlers;
 
        while (intr != end) {
@@ -303,7 +277,7 @@ static void xnintr_edge_shirq_handler(un
                        intr = shirq->handlers;
        }
 
-       xnintr_shirq_unlock(shirq);
+       xnlock_put(&shirq->lock);
 
        if (counter > MAX_EDGEIRQ_COUNTER)
                xnlogerr
@@ -386,9 +360,12 @@ static inline int xnintr_irq_attach(xnin
 
        __setbits(intr->flags, XN_ISR_ATTACHED);
 
-       /* Add a given interrupt object. */
        intr->next = NULL;
+
+       /* Add a given interrupt object. */
+       xnlock_get(&shirq->lock);
        *p = intr;
+       xnlock_put(&shirq->lock);
 
        return 0;
 }
@@ -409,8 +386,10 @@ static inline int xnintr_irq_detach(xnin
 
        while ((e = *p) != NULL) {
                if (e == intr) {
-                       /* Remove a given interrupt object from the list. */
+                       /* Remove the given interrupt object from the list. */
+                       xnlock_get(&shirq->lock);
                        *p = e->next;
+                       xnlock_put(&shirq->lock);
 
                        /* Release the IRQ line if this was the last user */
                        if (shirq->handlers == NULL)
@@ -429,12 +408,8 @@ static inline int xnintr_irq_detach(xnin
 int xnintr_mount(void)
 {
        int i;
-       for (i = 0; i < RTHAL_NR_IRQS; ++i) {
-               xnshirqs[i].handlers = NULL;
-#ifdef CONFIG_SMP
-               xnarch_atomic_set(&xnshirqs[i].active, 0);
-#endif
-       }
+       for (i = 0; i < RTHAL_NR_IRQS; ++i)
+               xnlock_init(&xnshirqs[i].lock);
        return 0;
 }
 
@@ -450,7 +425,6 @@ static inline int xnintr_irq_detach(xnin
        return xnarch_release_irq(intr->irq);
 }
 
-void xnintr_synchronize(xnintr_t *intr) {}
 int xnintr_mount(void) { return 0; }
 
 #endif /* CONFIG_XENO_OPT_SHIRQ_LEVEL || CONFIG_XENO_OPT_SHIRQ_EDGE */
@@ -626,6 +600,9 @@ int xnintr_destroy(xnintr_t *intr)
  * a low-level error occurred while attaching the interrupt. -EBUSY is
  * specifically returned if the interrupt object was already attached.
  *
+ * @note The caller <b>must not</b> hold nklock when invoking this service,
+ * this would cause deadlocks.
+ *
  * Environments:
  *
  * This service can be called from:
@@ -654,7 +631,7 @@ int xnintr_attach(xnintr_t *intr, void *
 
        if (!err)
                xnintr_stat_counter_inc();
-       
+
        xnlock_put_irqrestore(&intrlock, s);
 
        return err;
@@ -678,6 +655,9 @@ int xnintr_attach(xnintr_t *intr, void *
  * a non-attached interrupt object leads to a null-effect and returns
  * 0.
  *
+ * @note The caller <b>must not</b> hold nklock when invoking this service,
+ * this would cause deadlocks.
+ *
  * Environments:
  *
  * This service can be called from:
@@ -703,12 +683,6 @@ int xnintr_detach(xnintr_t *intr)
 
        xnlock_put_irqrestore(&intrlock, s);
 
-       /* The idea here is to keep a detached interrupt object valid as long
-          as the corresponding irq handler is running. This is one of the
-          requirements to iterate over the xnintr_shirq_t::handlers list in
-          xnintr_irq_handler() in a lockless way. */
-       xnintr_synchronize(intr);
-
        return err;
 }
 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help

Reply via email to