WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-4.0-testing] x86: Automatically EOI guest-bound int

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-4.0-testing] x86: Automatically EOI guest-bound interrupts if guest takes too long.
From: "Xen patchbot-4.0-testing" <patchbot-4.0-testing@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 16 Nov 2010 10:55:10 -0800
Delivery-date: Tue, 16 Nov 2010 10:55:21 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1289908413 0
# Node ID 9507fac4e8924075e920b034f59ee9567f66b7e4
# Parent  ec0c3f773c3e2e3f125bc99582c5db1032be3ae7
x86: Automatically EOI guest-bound interrupts if guest takes too long.

Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
xen-unstable changeset:   22051:59ff5820534f
xen-unstable date:        Sun Aug 22 09:37:08 2010 +0100
---
 xen/arch/x86/irq.c |   83 ++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 64 insertions(+), 19 deletions(-)

diff -r ec0c3f773c3e -r 9507fac4e892 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Nov 10 14:16:45 2010 +0000
+++ b/xen/arch/x86/irq.c        Tue Nov 16 11:53:33 2010 +0000
@@ -46,8 +46,6 @@ static DECLARE_BITMAP(used_vectors, NR_V
 
 struct irq_cfg __read_mostly *irq_cfg = NULL;
 
-static struct timer *__read_mostly irq_guest_eoi_timer;
-
 static DEFINE_SPINLOCK(vector_lock);
 
 DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
@@ -274,18 +272,15 @@ int init_irq_data(void)
     irq_desc = xmalloc_array(struct irq_desc, nr_irqs);
     irq_cfg = xmalloc_array(struct irq_cfg, nr_irqs);
     irq_status = xmalloc_array(int, nr_irqs);
-    irq_guest_eoi_timer = xmalloc_array(struct timer, nr_irqs);
     irq_vector = xmalloc_array(u8, nr_irqs_gsi);
     
-    if (!irq_desc || !irq_cfg || !irq_status ||! irq_vector ||
-        !irq_guest_eoi_timer)
+    if ( !irq_desc || !irq_cfg || !irq_status ||! irq_vector )
         return -ENOMEM;
 
     memset(irq_desc, 0,  nr_irqs * sizeof(*irq_desc));
     memset(irq_cfg, 0,  nr_irqs * sizeof(*irq_cfg));
     memset(irq_status, 0,  nr_irqs * sizeof(*irq_status));
     memset(irq_vector, 0, nr_irqs_gsi * sizeof(*irq_vector));
-    memset(irq_guest_eoi_timer, 0, nr_irqs * sizeof(*irq_guest_eoi_timer));
     
     for (irq = 0; irq < nr_irqs; irq++) {
         desc = irq_to_desc(irq);
@@ -735,6 +730,7 @@ typedef struct {
 #define ACKTYPE_UNMASK 1     /* Unmask PIC hardware (from any CPU)   */
 #define ACKTYPE_EOI    2     /* EOI on the CPU that was interrupted  */
     cpumask_t cpu_eoi_map;   /* CPUs that need to EOI this interrupt */
+    struct timer eoi_timer;
     struct domain *guest[IRQ_MAX_GUESTS];
 } irq_guest_action_t;
 
@@ -784,13 +780,55 @@ static void _irq_guest_eoi(struct irq_de
     desc->handler->enable(irq);
 }
 
+static void set_eoi_ready(void *data);
+
 static void irq_guest_eoi_timer_fn(void *data)
 {
     struct irq_desc *desc = data;
+    unsigned int irq = desc - irq_desc;
+    irq_guest_action_t *action;
+    cpumask_t cpu_eoi_map;
     unsigned long flags;
 
     spin_lock_irqsave(&desc->lock, flags);
-    _irq_guest_eoi(desc);
+    
+    if ( !(desc->status & IRQ_GUEST) )
+        goto out;
+
+    action = (irq_guest_action_t *)desc->action;
+
+    if ( action->ack_type != ACKTYPE_NONE )
+    {
+        unsigned int i;
+        for ( i = 0; i < action->nr_guests; i++ )
+        {
+            struct domain *d = action->guest[i];
+            unsigned int pirq = domain_irq_to_pirq(d, irq);
+            if ( test_and_clear_bit(pirq, d->pirq_mask) )
+                action->in_flight--;
+        }
+    }
+
+    if ( action->in_flight != 0 )
+        goto out;
+
+    switch ( action->ack_type )
+    {
+    case ACKTYPE_UNMASK:
+        desc->handler->end(irq);
+        break;
+    case ACKTYPE_EOI:
+        cpu_eoi_map = action->cpu_eoi_map;
+        spin_unlock_irq(&desc->lock);
+        on_selected_cpus(&cpu_eoi_map, set_eoi_ready, desc, 0);
+        spin_lock_irq(&desc->lock);
+        break;
+    case ACKTYPE_NONE:
+        _irq_guest_eoi(desc);
+        break;
+    }
+
+ out:
     spin_unlock_irqrestore(&desc->lock, flags);
 }
 
@@ -847,9 +885,11 @@ static void __do_IRQ_guest(int irq)
         }
     }
 
-    if ( already_pending == action->nr_guests )
-    {
-        stop_timer(&irq_guest_eoi_timer[irq]);
+    stop_timer(&action->eoi_timer);
+
+    if ( (action->ack_type == ACKTYPE_NONE) &&
+         (already_pending == action->nr_guests) )
+    {
         desc->handler->disable(irq);
         desc->status |= IRQ_GUEST_EOI_PENDING;
         for ( i = 0; i < already_pending; ++i )
@@ -865,10 +905,10 @@ static void __do_IRQ_guest(int irq)
              * - skip the timer setup below.
              */
         }
-        init_timer(&irq_guest_eoi_timer[irq],
-                   irq_guest_eoi_timer_fn, desc, smp_processor_id());
-        set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1));
-    }
+    }
+
+    migrate_timer(&action->eoi_timer, smp_processor_id());
+    set_timer(&action->eoi_timer, NOW() + MILLISECS(1));
 }
 
 /*
@@ -978,7 +1018,7 @@ static void __pirq_guest_eoi(struct doma
     if ( action->ack_type == ACKTYPE_NONE )
     {
         ASSERT(!test_bit(pirq, d->pirq_mask));
-        stop_timer(&irq_guest_eoi_timer[irq]);
+        stop_timer(&action->eoi_timer);
         _irq_guest_eoi(desc);
     }
 
@@ -1162,6 +1202,7 @@ int pirq_guest_bind(struct vcpu *v, int 
         action->shareable   = will_share;
         action->ack_type    = pirq_acktype(v->domain, pirq);
         cpus_clear(action->cpu_eoi_map);
+        init_timer(&action->eoi_timer, irq_guest_eoi_timer_fn, desc, 0);
 
         desc->depth = 0;
         desc->status |= IRQ_GUEST;
@@ -1266,7 +1307,7 @@ static irq_guest_action_t *__pirq_guest_
         }
         break;
     case ACKTYPE_NONE:
-        stop_timer(&irq_guest_eoi_timer[irq]);
+        stop_timer(&action->eoi_timer);
         _irq_guest_eoi(desc);
         break;
     }
@@ -1306,9 +1347,7 @@ static irq_guest_action_t *__pirq_guest_
     BUG_ON(!cpus_empty(action->cpu_eoi_map));
 
     desc->action = NULL;
-    desc->status &= ~IRQ_GUEST;
-    desc->status &= ~IRQ_INPROGRESS;
-    kill_timer(&irq_guest_eoi_timer[irq]);
+    desc->status &= ~(IRQ_GUEST|IRQ_GUEST_EOI_PENDING|IRQ_INPROGRESS);
     desc->handler->shutdown(irq);
 
     /* Caller frees the old guest descriptor block. */
@@ -1342,7 +1381,10 @@ void pirq_guest_unbind(struct domain *d,
     spin_unlock_irq(&desc->lock);
 
     if ( oldaction != NULL )
+    {
+        kill_timer(&oldaction->eoi_timer);
         xfree(oldaction);
+    }
 }
 
 static int pirq_guest_force_unbind(struct domain *d, int irq)
@@ -1380,7 +1422,10 @@ static int pirq_guest_force_unbind(struc
     spin_unlock_irq(&desc->lock);
 
     if ( oldaction != NULL )
+    {
+        kill_timer(&oldaction->eoi_timer);
         xfree(oldaction);
+    }
 
     return bound;
 }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-4.0-testing] x86: Automatically EOI guest-bound interrupts if guest takes too long., Xen patchbot-4.0-testing <=