* [Xenomai-core] I-pipe fasteoi interrupt handling issue
@ 2007-10-24 13:11 Jeroen Van den Keybus
2007-10-24 13:25 ` Philippe Gerum
2007-10-24 13:30 ` Philippe Gerum
0 siblings, 2 replies; 3+ messages in thread
From: Jeroen Van den Keybus @ 2007-10-24 13:11 UTC (permalink / raw)
To: xenomai-core
[-- Attachment #1: Type: text/plain, Size: 8072 bytes --]
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 -29 0.079 try_to_wake_up+0x14
(wake_up_process+0x14)
+func -29 0.084 task_rq_lock+0x14
(try_to_wake_up+0x24)
+func -29 0.464 ipipe_check_context+0x14
(task_rq_lock+0x28)
#func -28 0.094 _spin_lock+0x9 (task_rq_lock+0x63)
#func -28 0.509 ipipe_check_context+0x14
(_spin_lock+0x15)
#func -28 0.479 ipipe_check_context+0x14
(_spin_lock+0x3c)
<<< Here's where the IRQ happens >>>
| #func -27 0.169 __ipipe_handle_irq+0xe
(common_interrupt+0x21)
| #func -27 0.119 __ipipe_ack_irq+0x8
(__ipipe_handle_irq+0xc4)
<<< Here's where the APIC already receives its EOI >>>
| #func -27 0.104 __ipipe_ack_fasteoi_irq+0x8
(__ipipe_ack_irq+0x19)
| #func -27 0.209 ack_ioapic_quirk_irq+0xa
(__ipipe_ack_fasteoi_irq+0xe)
| #func -26 0.114 __mask_IO_APIC_irq+0x8
(ack_ioapic_quirk_irq+0xaa)
| #func -26 0.119 __modify_IO_APIC_irq+0xe
(__mask_IO_APIC_irq+0x14)
| #func -26 1.859 io_apic_base+0x8
(__modify_IO_APIC_irq+0x4d)
| #func -24 0.174 io_apic_base+0x8
(__modify_IO_APIC_irq+0x59)
| #func -24 0.164 __ipipe_dispatch_wired+0x14
(__ipipe_handle_irq+0x73)
| #*func -24 0.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 -24 2.109 rt_driver_intr+0xc [rt_driver]
(xnintr_irq_handler+0x15e)
| #*func -22 0.129 xnarch_get_cpu_time+0x8
(rt_driver_intr+0x4b [rt_driver])
| #*func -22 0.139 xnarch_tsc_to_ns+0x12
(xnarch_get_cpu_time+0xf)
<<< Our driver signals a pending task and leaves. >>>
| #*func -21 0.199 rtdm_event_signal+0xe
(rt_driver_intr+0x2e [rt_driver])
| #*func -21 1.299 xnsynch_flush+0xe
(rtdm_event_signal+0x12f)
| #*func -20 0.159 xnpod_resume_thread+0xe
(xnsynch_flush+0x3a4)
| #*[ 2489] -<?>- 99 -20 0.294 xnpod_resume_thread+0x140
(xnsynch_flush+0x3a4)
| #*func -19 1.549 xntimer_stop_aperiodic+0xe
(xnpod_resume_thread+0xa0d)
| #*func -18 0.644 xntimer_next_local_shot+0x16
(xntimer_stop_aperiodic+0x4f4)
| #*func -17 0.419 xnpod_schedule+0x11
(rtdm_event_signal+0x2b4)
| #*func -17 0.129 rthal_irq_end+0x8
(xnintr_irq_handler+0x262)
| #*func -17 0.134 __ipipe_end_fasteoi_irq+0x8
(rthal_irq_end+0x24)
| #*func -17 0.109 unmask_IO_APIC_irq+0x12
(__ipipe_end_fasteoi_irq+0xe)
| #*func -16 0.134 __ipipe_spin_lock_irqsave+0x9
(unmask_IO_APIC_irq+0x1e)
| #*func -16 0.099 __unmask_IO_APIC_irq+0x8
(unmask_IO_APIC_irq+0x27)
| #*func -16 0.089 __modify_IO_APIC_irq+0xe
(__unmask_IO_APIC_irq+0x14)
| #*func -16 1.609 io_apic_base+0x8
(__modify_IO_APIC_irq+0x4d)
| #*func -15 0.159 io_apic_base+0x8
(__modify_IO_APIC_irq+0x59)
| #*func -14 0.124 __ipipe_unlock_irq+0xe
(unmask_IO_APIC_irq+0x3d)
| #*func -14 0.184 __ipipe_spin_unlock_irqrestore+0x9
(unmask_IO_APIC_irq+0x49)
| #*func -14 0.209 xnpod_schedule+0x11
(xnintr_irq_handler+0x28f)
| #*[ 220] gatekee -1 -14 1.139 xnpod_schedule+0xec
(xnintr_irq_handler+0x28f)
| #*func -13 0.599 __switch_to+0xe
(xnpod_schedule+0x8b4)
| #*[ 2489] -<?>- 99 -12 1.019 xnpod_schedule+0x952
(xnpod_suspend_thread+0x72c)
| #*func -11 0.589 __ipipe_restore_pipeline_head+0x9
(rtdm_event_timedwait+0x181)
| +*func -10 0.169 __ipipe_handle_irq+0xe
(common_interrupt+0x21)
| +*func -10 0.109 __ipipe_ack_irq+0x8
(__ipipe_handle_irq+0xc4)
| +*func -10 0.109 __ipipe_ack_fasteoi_irq+0x8
(__ipipe_ack_irq+0x19)
| +*func -10 0.194 ack_ioapic_quirk_irq+0xa
(__ipipe_ack_fasteoi_irq+0xe)
| +*func -10 0.109 __mask_IO_APIC_irq+0x8
(ack_ioapic_quirk_irq+0xaa)
| +*func -10 0.109 __modify_IO_APIC_irq+0xe
(__mask_IO_APIC_irq+0x14)
| +*func -10 1.594 io_apic_base+0x8
(__modify_IO_APIC_irq+0x4d)
| +*func -8 0.174 io_apic_base+0x8
(__modify_IO_APIC_irq+0x59)
| +*func -8 0.124 __ipipe_dispatch_wired+0x14
(__ipipe_handle_irq+0x73)
| #*func -8 0.214 xnintr_irq_handler+0xe
(__ipipe_dispatch_wired+0xea)
<<< Here's where our driver is called again >>>
| #*func -8 2.024 rt_driver_intr+0xc [rt_driver]
(xnintr_irq_handler+0x15e)
| #*func -6 0.139 printk+0x14 (rt_driver_intr+0x78
[rt_driver])
| #*func -5 0.144 __ipipe_spin_lock_irqsave+0x9
(printk+0xbf)
| #*func -5 0.109 vscnprintf+0xc (printk+0xe7)
| #*func -5 0.309 vsnprintf+0xe (vscnprintf+0x1b)
| #*func -5 0.379 number+0xe (vsnprintf+0x2f9)
| #*func -4 0.164 __ipipe_spin_unlock_irqrestore+0x9
(printk+0xfd)
| #*func -4 0.139 ipipe_trigger_irq+0xc
(printk+0x10b)
| #*func -4 0.194 __ipipe_handle_irq+0xe
(ipipe_trigger_irq+0xa7)
| #*func -4 0.174 __ipipe_set_irq_pending+0x14
(__ipipe_handle_irq+0x1a4)
| #*func -4 0.259 __ipipe_walk_pipeline+0xe
(__ipipe_handle_irq+0x95)
| #*func -4 0.114 rthal_irq_end+0x8
(xnintr_irq_handler+0x262)
| #*func -3 0.104 __ipipe_end_fasteoi_irq+0x8
(rthal_irq_end+0x24)
| #*func -3 0.104 unmask_IO_APIC_irq+0x12
(__ipipe_end_fasteoi_irq+0xe)
| #*func -3 0.129 __ipipe_spin_lock_irqsave+0x9
(unmask_IO_APIC_irq+0x1e)
| #*func -3 0.104 __unmask_IO_APIC_irq+0x8
(unmask_IO_APIC_irq+0x27)
| #*func -3 0.094 __modify_IO_APIC_irq+0xe
(__unmask_IO_APIC_irq+0x14)
| #*func -3 1.604 io_apic_base+0x8
(__modify_IO_APIC_irq+0x4d)
| #*func -1 0.139 io_apic_base+0x8
(__modify_IO_APIC_irq+0x59)
| #*func -1 0.129 __ipipe_unlock_irq+0xe
(unmask_IO_APIC_irq+0x3d)
| #*func -1 0.314 __ipipe_spin_unlock_irqrestore+0x9
(unmask_IO_APIC_irq+0x49)
| +*func -1 0.479 __ipipe_walk_pipeline+0xe
(__ipipe_handle_irq+0x95)
+*func 0 0.704 receiveCurrentBuffer+0x11
[rt_driver] (rt_driver_read+0xc1 [rt_driver])
> +*begin 0x00000000 0+ 1.659 rt_driver_read+0x181 [rt_driver]
(__rt_dev_read+0x55)
: +*func 1 0.149 __ipipe_syscall_root+0x9
(sysenter_past_esp+0x46)
: +*func 1 0.154 __ipipe_dispatch_event+0xe
(__ipipe_syscall_root+0x50)
:
[-- Attachment #2: Type: text/html, Size: 17236 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Xenomai-core] I-pipe fasteoi interrupt handling issue
2007-10-24 13:11 [Xenomai-core] I-pipe fasteoi interrupt handling issue Jeroen Van den Keybus
@ 2007-10-24 13:25 ` Philippe Gerum
2007-10-24 13:30 ` Philippe Gerum
1 sibling, 0 replies; 3+ messages in thread
From: Philippe Gerum @ 2007-10-24 13:25 UTC (permalink / raw)
To: Jeroen Van den Keybus; +Cc: xenomai-core
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.000000000 +0200
+++ arch/i386/kernel/io_apic.c 2007-10-24 15:24:16.000000000 +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.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Xenomai-core] I-pipe fasteoi interrupt handling issue
2007-10-24 13:11 [Xenomai-core] I-pipe fasteoi interrupt handling issue Jeroen Van den Keybus
2007-10-24 13:25 ` Philippe Gerum
@ 2007-10-24 13:30 ` Philippe Gerum
1 sibling, 0 replies; 3+ messages in thread
From: Philippe Gerum @ 2007-10-24 13:30 UTC (permalink / raw)
To: Jeroen Van den Keybus; +Cc: xenomai-core
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.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-10-24 13:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-24 13:11 [Xenomai-core] I-pipe fasteoi interrupt handling issue Jeroen Van den Keybus
2007-10-24 13:25 ` Philippe Gerum
2007-10-24 13:30 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.