Re: [Xenomai-core] I-pipe fasteoi interrupt handling issue
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
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
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_