[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;
}
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Xenomai-help mailing list [email protected] https://mail.gna.org/listinfo/xenomai-help
