Re: [Xenomai-core] I-pipe fasteoi interrupt handling issue

2007-10-24 Thread Philippe Gerum
Jeroen Van den Keybus wrote:
> On my Linux 2.6.23 with latest I-pipe patch (1.10-10), interrupts are
> dispatched twice if they are of the fasteoi type.
>  
> I have the impression that the I-pipe does the eoi() acknowledgement (in
> kernel/irq/chip.c: __ipipe_ack_fasteoi_irq) without first masking off
> the IRQ. As the interrupt line hasn't been cleared at this time, the
> interrupt is immediately reissued. Afterwards (in
> __ipipe_end_fasteoi_irq), unmasking is performed correctly nevertheless.
> If I add 'desc->chip->mask(irq);' before the 'desc->chip->eoi(irq);',
> Linux won't boot anymore; apparently the timer IRQs no longer make it to
> the APIC.

The reason this won't work is because ->mask() will also lock the
interrupt at I-pipe level, i.e. prevent the IRQ from flowing down the
pipeline (see ipipe_lock_irq). What we want here is only a physical
masking, not a physical+logical one, because we still want the incoming
IRQ to be dispatched to the kernel, albeit we ask the IO-APIC not to
send another one until we unmask the source (unmasking without masking
is ok, and simply leads to a no-op).

-- 
Philippe.

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


Re: [Xenomai-core] I-pipe fasteoi interrupt handling issue

2007-10-24 Thread Philippe Gerum
Jeroen Van den Keybus wrote:
> On my Linux 2.6.23 with latest I-pipe patch (1.10-10), interrupts are
> dispatched twice if they are of the fasteoi type.
>  
> I have the impression that the I-pipe does the eoi() acknowledgement (in
> kernel/irq/chip.c: __ipipe_ack_fasteoi_irq) without first masking off
> the IRQ. As the interrupt line hasn't been cleared at this time, the
> interrupt is immediately reissued.

Does this help?

--- arch/i386/kernel/io_apic.c~ 2007-10-22 16:43:21.0 +0200
+++ arch/i386/kernel/io_apic.c  2007-10-24 15:24:16.0 +0200
@@ -1985,6 +1985,17 @@
  * operation to prevent an edge-triggered interrupt escaping meanwhile.
  * The idea is from Manfred Spraul.  --macro
  */
+
+#ifdef CONFIG_IPIPE
+/*
+ * Prevent low priority IRQs grabbed by high priority domains from
+ * being delayed, waiting for a high priority interrupt handler
+ * running in a low priority domain to complete.
+ */
+   spin_lock(&ioapic_lock);
+   __mask_IO_APIC_irq(irq);
+   spin_unlock(&ioapic_lock);
+#endif
i = irq_vector[irq];

v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
@@ -1998,17 +2009,6 @@
__unmask_and_level_IO_APIC_irq(irq);
spin_unlock(&ioapic_lock);
}
-
-#ifdef CONFIG_IPIPE
-/*
- * Prevent low priority IRQs grabbed by high priority domains from
- * being delayed, waiting for a high priority interrupt handler
- * running in a low priority domain to complete.
- */
-   spin_lock(&ioapic_lock);
-   __mask_IO_APIC_irq(irq);
-   spin_unlock(&ioapic_lock);
-#endif
 }

-- 
Philippe.

___
Xenomai-core mailing list
Xenomai-core@gna.org
https://mail.gna.org/listinfo/xenomai-core


[Xenomai-core] I-pipe fasteoi interrupt handling issue

2007-10-24 Thread Jeroen Van den Keybus
On my Linux 2.6.23 with latest I-pipe patch (1.10-10), interrupts are
dispatched twice if they are of the fasteoi type.

I have the impression that the I-pipe does the eoi() acknowledgement (in
kernel/irq/chip.c: __ipipe_ack_fasteoi_irq) without first masking off the
IRQ. As the interrupt line hasn't been cleared at this time, the interrupt
is immediately reissued. Afterwards (in __ipipe_end_fasteoi_irq), unmasking
is performed correctly nevertheless. If I add 'desc->chip->mask(irq);'
before the 'desc->chip->eoi(irq);', Linux won't boot anymore; apparently the
timer IRQs no longer make it to the APIC.

I'm now going to try a level-irq, but if in the meantime anyone can explain
me if the above reasoning is totally off track or why the timer locks up
after adding the mask...

Thanks,

Jeroen.



A typical I-pipe trace shows:

 +func -290.079  try_to_wake_up+0x14
(wake_up_process+0x14)
 +func -290.084  task_rq_lock+0x14
(try_to_wake_up+0x24)
 +func -290.464  ipipe_check_context+0x14
(task_rq_lock+0x28)
 #func -280.094  _spin_lock+0x9 (task_rq_lock+0x63)
 #func -280.509  ipipe_check_context+0x14
(_spin_lock+0x15)
 #func -280.479  ipipe_check_context+0x14
(_spin_lock+0x3c)
<<< Here's where the IRQ happens >>>
 |   #func -270.169  __ipipe_handle_irq+0xe
(common_interrupt+0x21)
 |   #func -270.119  __ipipe_ack_irq+0x8
(__ipipe_handle_irq+0xc4)
<<< Here's where the APIC already receives its EOI >>>
 |   #func -270.104  __ipipe_ack_fasteoi_irq+0x8
(__ipipe_ack_irq+0x19)
 |   #func -270.209  ack_ioapic_quirk_irq+0xa
(__ipipe_ack_fasteoi_irq+0xe)
 |   #func -260.114  __mask_IO_APIC_irq+0x8
(ack_ioapic_quirk_irq+0xaa)
 |   #func -260.119  __modify_IO_APIC_irq+0xe
(__mask_IO_APIC_irq+0x14)
 |   #func -261.859  io_apic_base+0x8
(__modify_IO_APIC_irq+0x4d)
 |   #func -240.174  io_apic_base+0x8
(__modify_IO_APIC_irq+0x59)
 |   #func -240.164  __ipipe_dispatch_wired+0x14
(__ipipe_handle_irq+0x73)
 |  #*func -240.289  xnintr_irq_handler+0xe
(__ipipe_dispatch_wired+0xea)
<<< Here's where our driver gets a chance to process the interrupt and clear
the IRQ line >>>
 |  #*func -242.109  rt_driver_intr+0xc [rt_driver]
(xnintr_irq_handler+0x15e)
 |  #*func -220.129  xnarch_get_cpu_time+0x8
(rt_driver_intr+0x4b [rt_driver])
 |  #*func -220.139  xnarch_tsc_to_ns+0x12
(xnarch_get_cpu_time+0xf)
<<< Our driver signals a pending task and leaves. >>>
 |  #*func -210.199  rtdm_event_signal+0xe
(rt_driver_intr+0x2e [rt_driver])
 |  #*func -211.299  xnsynch_flush+0xe
(rtdm_event_signal+0x12f)
 |  #*func -200.159  xnpod_resume_thread+0xe
(xnsynch_flush+0x3a4)
 |  #*[ 2489] --   99   -200.294  xnpod_resume_thread+0x140
(xnsynch_flush+0x3a4)
 |  #*func -191.549  xntimer_stop_aperiodic+0xe
(xnpod_resume_thread+0xa0d)
 |  #*func -180.644  xntimer_next_local_shot+0x16
(xntimer_stop_aperiodic+0x4f4)
 |  #*func -170.419  xnpod_schedule+0x11
(rtdm_event_signal+0x2b4)
 |  #*func -170.129  rthal_irq_end+0x8
(xnintr_irq_handler+0x262)
 |  #*func -170.134  __ipipe_end_fasteoi_irq+0x8
(rthal_irq_end+0x24)
 |  #*func -170.109  unmask_IO_APIC_irq+0x12
(__ipipe_end_fasteoi_irq+0xe)
 |  #*func -160.134  __ipipe_spin_lock_irqsave+0x9
(unmask_IO_APIC_irq+0x1e)
 |  #*func -160.099  __unmask_IO_APIC_irq+0x8
(unmask_IO_APIC_irq+0x27)
 |  #*func -160.089  __modify_IO_APIC_irq+0xe
(__unmask_IO_APIC_irq+0x14)
 |  #*func -161.609  io_apic_base+0x8
(__modify_IO_APIC_irq+0x4d)
 |  #*func -150.159  io_apic_base+0x8
(__modify_IO_APIC_irq+0x59)
 |  #*func -140.124  __ipipe_unlock_irq+0xe
(unmask_IO_APIC_irq+0x3d)
 |  #*func -140.184  __ipipe_spin_unlock_irqrestore+0x9
(unmask_IO_APIC_irq+0x49)
 |  #*func -140.209  xnpod_schedule+0x11
(xnintr_irq_handler+0x28f)
 |  #*[  220] gatekee -1   -141.139  xnpod_schedule+0xec
(xnintr_irq_handler+0x28f)
 |  #*func -130.599  __switch_to+0xe
(xnpod_schedule+0x8b4)
 |  #*[ 2489] --   99   -121.019  xnpod_schedule+0x952
(xnpod_suspend_thread+0x72c)
 |  #*func -110.589  __ipipe_restore_pipeline_head+0x9
(rtdm_event_timedwait+0x181)
 |  +*func -100.169  __ipipe_handle_irq+0xe
(common_interrupt+0x21)
 |  +*func -100.109  __ipipe_ack_irq+0x8
(__ipipe_handle_irq+0xc4)
 |  +*func -100.109  __ipipe_ack_