On Fri, 2010-10-08 at 09:01 +0200, Pavel Machek wrote:
> Hi!
[snip]
> Now... I'm aware that lock_get/put around irq_free should be
> unneccessary, as should be irq_disable and my ->ready flag. Those were
> my attempts to work around the problem. I'll attach the full source at
> the end.
>
> > > Unfortunately, when the userspace app is ran and killed repeatedly (so
> > > that interrupt is registered/unregistered all the time), I get
> > > oopses in __ipipe_dispatch_wired() -- it seems to call into the NULL
> > > pointer.
> > >
> > > I decided that "wired" interrupt when the source is shared between
> > > Linux and Xenomai, is wrong thing, so I disable "wired" interrupts
> > > altogether, but that only moved oops to __virq_end.
> >
> > This is wrong. The only way to get a determistically shared IRQs across
> > domains is via the wired path, either using the pattern Gilles cited or,
> > in a slight variation, signaling down via a separate rtdm_nrtsig.
>
> For now, I'm trying to get it not to oops; deterministic latencies are
> the next topic :-(.
Could you try the patches below? Absolutely untested as required by the
breaktiquette, but might help. Hopefully.
This series is on top of I-pipe 2.6.27-x86:
diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
index a12f431..b0e59e6 100644
--- a/include/linux/ipipe.h
+++ b/include/linux/ipipe.h
@@ -353,6 +353,15 @@ int ipipe_register_domain(struct ipipe_domain *ipd,
int ipipe_unregister_domain(struct ipipe_domain *ipd);
+#ifdef CONFIG_SMP
+void ipipe_drain_interrupt(struct ipipe_domain *ipd,
+ unsigned int irq);
+#else
+static inline void ipipe_drain_interrupt(struct ipipe_domain *ipd,
+ unsigned int irq)
+{}
+#endif
+
void ipipe_suspend_domain(void);
int ipipe_virtualize_irq(struct ipipe_domain *ipd,
diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
index 97e6aae..ac4addc 100644
--- a/kernel/ipipe/core.c
+++ b/kernel/ipipe/core.c
@@ -1250,6 +1250,32 @@ int ipipe_unregister_domain(struct ipipe_domain
*ipd)
return 0;
}
+void ipipe_drain_interrupt(struct ipipe_domain *ipd, unsigned int irq)
+{
+ struct ipipe_percpu_domain_data *p;
+ unsigned long flags;
+ int cpu;
+
+ flags = ipipe_critical_enter(NULL);
+ clear_bit(IPIPE_HANDLE_FLAG, &ipd->irqs[irq].control);
+ clear_bit(IPIPE_STICKY_FLAG, &ipd->irqs[irq].control);
+ set_bit(IPIPE_PASS_FLAG, &ipd->irqs[irq].control);
+ ipipe_critical_exit(flags);
+
+ for_each_online_cpu(cpu) {
+ local_irq_save_hw(flags);
+ p = ipipe_percpudom_ptr(ipd, cpu);
+ do {
+ local_irq_restore_hw(flags);
+ cpu_relax();
+ local_irq_save_hw(flags);
+ } while (test_bit(irq, p->irqpend_lomask) ||
+ test_bit(IPIPE_STALL_FLAG, &p->status));
+ local_irq_restore_hw(flags);
+ }
+}
+EXPORT_SYMBOL_GPL(ipipe_drain_interrupt);
+
This series goes on top of Xenomai 2.5.x:
/*
* ipipe_propagate_irq() -- Force a given IRQ propagation on behalf of
* a running interrupt handler to the next domain down the pipeline.
diff --git a/include/asm-generic/bits/intr.h
b/include/asm-generic/bits/intr.h
index 19b35d6..9452932 100644
--- a/include/asm-generic/bits/intr.h
+++ b/include/asm-generic/bits/intr.h
@@ -57,6 +57,11 @@ static inline void xnarch_chain_irq (unsigned irq)
rthal_irq_host_pend(irq);
}
+static inline void xnarch_drain_irq(unsigned irq)
+{
+ rthal_irq_drain(irq);
+}
+
static inline xnarch_cpumask_t xnarch_set_irq_affinity (unsigned irq,
xnarch_cpumask_t
affinity)
{
diff --git a/include/asm-generic/hal.h b/include/asm-generic/hal.h
index 34f8ea1..81aef5e 100644
--- a/include/asm-generic/hal.h
+++ b/include/asm-generic/hal.h
@@ -504,6 +504,11 @@ int rthal_irq_disable(unsigned irq);
int rthal_irq_end(unsigned irq);
+static inline void rthal_irq_drain(unsigned int irq)
+{
+ ipipe_drain_interrupt(&rthal_domain, irq);
+}
+
int rthal_irq_host_request(unsigned irq,
rthal_irq_host_handler_t handler,
char *name,
diff --git a/ksrc/nucleus/intr.c b/ksrc/nucleus/intr.c
index a6de4ea..1b79874 100644
--- a/ksrc/nucleus/intr.c
+++ b/ksrc/nucleus/intr.c
@@ -792,6 +792,8 @@ int xnintr_detach(xnintr_t *intr)
goto out;
}
+ xnarch_drain_irq(intr->irq);
+
__clrbits(intr->flags, XN_ISR_ATTACHED);
ret = xnintr_irq_detach(intr);
--
Philippe.
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help