Commit a1bd0cc7 authored by Philippe Gerum's avatar Philippe Gerum

ipipe: work around: force all interrupts to unlazy disable mode

We don't cope well with lazy disabling simply because we neither track
nor update the descriptor state bits for reflecting the state of the
irqchip regarding interrupts channels. Which is definitely wrong for
multiple reasons.

Since proper lazy disabling relies on the masked/unmasked interrupt
state flag advertised by the descriptor, which is not updated by the
pipeline entry code when masking before event deferral, we may end up
with IRQ lines permanently masked.

Such bug is typically triggered by drivers which disable IRQs on the
fly directly from the interrupt handler as part of their PM logic,
e.g.:

<irq> (edge-triggered, lazy disable)
   __ipipe_ack_fasteoi_irq()
       irqchip.irq_hold()
          <irq masked in controller>
   ...
   handle_fasteoi_irq()
      handle_irq_event()
         driver: disable_irq(irq), schedule PM resume
	    <irq lazily disabled, not set as masked>
      cond_unmask_eoi_irq()
         <irq disabled, no unmask>
...
PM runtime resume
   enable_irq(irq)
     <irq seen as disabled but unmasked due to laziness, nop>

irq is now permantenly masked: BUG.

This change is a limited workaround, forcing all interrupts to unlazy
disable mode when the pipeline is built in. The only sane fix would be
to overhaul the pipelined interrupt flow handling entirely, in order
to fully integrate that logic into the regular flow handlers, sharing
the locking, descriptor state and status management with them.

This is basically what dovetail is aiming at:
http://lab.xenomai.org/linux-dovetail.git/
parent a40f54a7
......@@ -1040,6 +1040,13 @@ __fixup_irq_handler(struct irq_desc *desc, irq_flow_handler_t handle, int is_cha
}
}
/*
* We don't cope well with lazy disabling simply because we
* neither track nor update the descriptor state bits, which
* is badly wrong.
*/
irq_settings_clr_and_set(desc, 0, _IRQ_DISABLE_UNLAZY);
/* Suppress intermediate trampoline routine. */
ipipe_root_domain->irqs[desc->irq_data.irq].ackfn = desc->ipipe_ack;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment