[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] xen/arm: irq: Don't use _IRQ_PENDING when handling host interrupt



commit f83a02eb819375c2ece4747ce1b90b7245723c6e
Author:     Julien Grall <julien.grall@xxxxxxx>
AuthorDate: Sun Jun 2 11:26:14 2019 +0100
Commit:     Stefano Stabellini <sstabellini@xxxxxxxxxx>
CommitDate: Mon Jul 29 13:50:44 2019 -0700

    xen/arm: irq: Don't use _IRQ_PENDING when handling host interrupt
    
    While SPIs are shared between CPU, it is not possible to receive the
    same interrupts on a different CPU while the interrupt is in active
    state.
    
    For host interrupt (i.e routed to Xen), the deactivation of the
    interrupt is done at the end of the handling. This can alternatively be
    done outside of the handler by calling gic_set_active_state().
    
    At the moment, gic_set_active_state() is only called by the vGIC for
    interrupt routed to the guest. It is hard to find a reason for Xen to
    directly play with the active state for interrupt routed to Xen.
    
    To simplify the handling of host interrupt, gic_set_activate_state() is
    now restricted to interrupts routed to guest.
    
    This means the _IRQ_PENDING logic is now unecessary on Arm as a same
    interrupt can never come up while in the loop and nobody should play
    with the flag behind our back.
    
    [Stefano: improve in-code comment]
    
    Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
    Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx>
    Reviewed-by: Andrii Anisov <andrii_anisov@xxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
---
 xen/arch/arm/irq.c        | 32 ++++++++++----------------------
 xen/include/asm-arm/gic.h |  5 +++++
 2 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
index c51cf333ce..3877657a52 100644
--- a/xen/arch/arm/irq.c
+++ b/xen/arch/arm/irq.c
@@ -199,6 +199,7 @@ int request_irq(unsigned int irq, unsigned int irqflags,
 void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
 {
     struct irq_desc *desc = irq_to_desc(irq);
+    struct irqaction *action;
 
     perfc_incr(irqs);
 
@@ -242,35 +243,22 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, 
int is_fiq)
         goto out_no_end;
     }
 
-    set_bit(_IRQ_PENDING, &desc->status);
-
-    /*
-     * Since we set PENDING, if another processor is handling a different
-     * instance of this same irq, the other processor will take care of it.
-     */
-    if ( test_bit(_IRQ_DISABLED, &desc->status) ||
-         test_bit(_IRQ_INPROGRESS, &desc->status) )
+    if ( test_bit(_IRQ_DISABLED, &desc->status) )
         goto out;
 
     set_bit(_IRQ_INPROGRESS, &desc->status);
 
-    while ( test_bit(_IRQ_PENDING, &desc->status) )
-    {
-        struct irqaction *action;
+    action = desc->action;
 
-        clear_bit(_IRQ_PENDING, &desc->status);
-        action = desc->action;
+    spin_unlock_irq(&desc->lock);
 
-        spin_unlock_irq(&desc->lock);
-
-        do
-        {
-            action->handler(irq, action->dev_id, regs);
-            action = action->next;
-        } while ( action );
+    do
+    {
+        action->handler(irq, action->dev_id, regs);
+        action = action->next;
+    } while ( action );
 
-        spin_lock_irq(&desc->lock);
-    }
+    spin_lock_irq(&desc->lock);
 
     clear_bit(_IRQ_INPROGRESS, &desc->status);
 
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index fab02f19f7..793d324b33 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -400,9 +400,14 @@ static inline unsigned int gic_get_nr_lrs(void)
  * Set the active state of an IRQ. This should be used with care, as this
  * directly forces the active bit, without considering the GIC state machine.
  * For private IRQs this only works for those of the current CPU.
+ *
+ * This function should only be called for interrupts routed to the
+ * guest. The flow of interrupts routed to Xen is not able cope with
+ * software changes to the active state.
  */
 static inline void gic_set_active_state(struct irq_desc *irqd, bool state)
 {
+    ASSERT(test_bit(_IRQ_GUEST, &irqd->status));
     gic_hw_ops->set_active_state(irqd, state);
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.