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-unstable] x86 hvm: suspend platform timer emulation

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86 hvm: suspend platform timer emulation while its IRQ is masked
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Sep 2009 01:35:33 -0700
Delivery-date: Wed, 16 Sep 2009 01:37:18 -0700
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.fraser@xxxxxxxxxx>
# Date 1253089841 -3600
# Node ID 72d130772f36284b904da2369410de795237f712
# Parent  0c83979c1b56b297a5109f2c206630af28460337
x86 hvm: suspend platform timer emulation while its IRQ is masked

This patch gets rid of a timer which IRQ is masked from vcpu's timer
list. It reduces the overhead of VM EXIT and context switch of vm.

Also fixes a potential bug.
(1) VCPU#0: mask the IRQ of a timer. (ex. vioapic.redir[2].mask=1)
(2) VCPU#1: pt_timer_fn() is invoked by expiration of the timer.
(3) VCPU#1: pt_update_irq() is called but does nothing by
pt_irq_masked()==1.
(4) VCPU#1: sleep by halt.
(5) VCPU#0: unmask the IRQ of the timer.
After that, no one wakes up the VCPU#1.

IRQ of ISA is masked by:
 - PIC's IMR
 - IOAPIC's redir[0]
 - IOAPIC's redir[N].mask
 - LAPIC's LVT0
 - LAPIC enabled/disabled

IRQ of LAPIC timer is masked by:
 - LAPIC's LVTT
 - LAPIC disabled

When above stuffs are changed, the corresponding vcpu is kicked and
suspended timer emulation is resumed.

In addition, a small bug fix in pt_adjust_global_vcpu_target().

Signed-off-by: Kouya Shimura <kouya@xxxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/vioapic.c    |    6 +++
 xen/arch/x86/hvm/vlapic.c     |   10 ++++++
 xen/arch/x86/hvm/vpic.c       |    7 +++-
 xen/arch/x86/hvm/vpt.c        |   64 ++++++++++++++++++++++++++++++++++++------
 xen/include/asm-x86/hvm/vpt.h |    4 +-
 5 files changed, 80 insertions(+), 11 deletions(-)

diff -r 0c83979c1b56 -r 72d130772f36 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c        Wed Sep 16 09:29:17 2009 +0100
+++ b/xen/arch/x86/hvm/vioapic.c        Wed Sep 16 09:30:41 2009 +0100
@@ -125,6 +125,7 @@ static void vioapic_write_redirent(
     struct domain *d = vioapic_domain(vioapic);
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
     union vioapic_redir_entry *pent, ent;
+    int unmasked = 0;
 
     spin_lock(&d->arch.hvm_domain.irq_lock);
 
@@ -138,10 +139,12 @@ static void vioapic_write_redirent(
     }
     else
     {
+        unmasked = ent.fields.mask;
         /* Remote IRR and Delivery Status are read-only. */
         ent.bits = ((ent.bits >> 32) << 32) | val;
         ent.fields.delivery_status = 0;
         ent.fields.remote_irr = pent->fields.remote_irr;
+        unmasked = unmasked && !ent.fields.mask;
     }
 
     *pent = ent;
@@ -160,6 +163,9 @@ static void vioapic_write_redirent(
     }
 
     spin_unlock(&d->arch.hvm_domain.irq_lock);
+
+    if ( idx == 0 || unmasked )
+        pt_may_unmask_irq(d, NULL);
 }
 
 static void vioapic_write_indirect(
diff -r 0c83979c1b56 -r 72d130772f36 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Wed Sep 16 09:29:17 2009 +0100
+++ b/xen/arch/x86/hvm/vlapic.c Wed Sep 16 09:30:41 2009 +0100
@@ -624,7 +624,10 @@ static int vlapic_write(struct vcpu *v, 
             }
         }
         else
+        {
             vlapic->hw.disabled &= ~VLAPIC_SW_DISABLED;
+            pt_may_unmask_irq(vlapic_domain(vlapic), &vlapic->pt);
+        }
         break;
 
     case APIC_ESR:
@@ -654,7 +657,12 @@ static int vlapic_write(struct vcpu *v, 
         val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4];
         vlapic_set_reg(vlapic, offset, val);
         if ( offset == APIC_LVT0 )
+        {
             vlapic_adjust_i8259_target(v->domain);
+            pt_may_unmask_irq(v->domain, NULL);
+        }
+        if ( (offset == APIC_LVTT) && !(val & APIC_LVT_MASKED) )
+            pt_may_unmask_irq(NULL, &vlapic->pt);
         break;
 
     case APIC_TMICT:
@@ -719,10 +727,12 @@ void vlapic_msr_set(struct vlapic *vlapi
         {
             vlapic_reset(vlapic);
             vlapic->hw.disabled &= ~VLAPIC_HW_DISABLED;
+            pt_may_unmask_irq(vlapic_domain(vlapic), &vlapic->pt);
         }
         else
         {
             vlapic->hw.disabled |= VLAPIC_HW_DISABLED;
+            pt_may_unmask_irq(vlapic_domain(vlapic), NULL);
         }
     }
 
diff -r 0c83979c1b56 -r 72d130772f36 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Wed Sep 16 09:29:17 2009 +0100
+++ b/xen/arch/x86/hvm/vpic.c   Wed Sep 16 09:30:41 2009 +0100
@@ -178,7 +178,7 @@ static void vpic_ioport_write(
     struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
 {
     int priority, cmd, irq;
-    uint8_t mask;
+    uint8_t mask, unmasked = 0;
 
     vpic_lock(vpic);
 
@@ -190,6 +190,7 @@ static void vpic_ioport_write(
             /* Clear edge-sensing logic. */
             vpic->irr &= vpic->elcr;
 
+            unmasked = vpic->imr;
             /* No interrupts masked or in service. */
             vpic->imr = vpic->isr = 0;
 
@@ -268,6 +269,7 @@ static void vpic_ioport_write(
         {
         case 0:
             /* OCW1 */
+            unmasked = vpic->imr & (~val);
             vpic->imr = val;
             break;
         case 1:
@@ -295,6 +297,9 @@ static void vpic_ioport_write(
     vpic_update_int_output(vpic);
 
     vpic_unlock(vpic);
+
+    if ( unmasked )
+        pt_may_unmask_irq(vpic_domain(vpic), NULL);
 }
 
 static uint32_t vpic_ioport_read(struct hvm_hw_vpic *vpic, uint32_t addr)
diff -r 0c83979c1b56 -r 72d130772f36 xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c    Wed Sep 16 09:29:17 2009 +0100
+++ b/xen/arch/x86/hvm/vpt.c    Wed Sep 16 09:30:41 2009 +0100
@@ -216,19 +216,30 @@ void pt_update_irq(struct vcpu *v)
 void pt_update_irq(struct vcpu *v)
 {
     struct list_head *head = &v->arch.hvm_vcpu.tm_list;
-    struct periodic_time *pt, *earliest_pt = NULL;
+    struct periodic_time *pt, *temp, *earliest_pt = NULL;
     uint64_t max_lag = -1ULL;
     int irq, is_lapic;
 
     spin_lock(&v->arch.hvm_vcpu.tm_lock);
 
-    list_for_each_entry ( pt, head, list )
-    {
-        if ( pt->pending_intr_nr && !pt_irq_masked(pt) &&
-             ((pt->last_plt_gtime + pt->period) < max_lag) )
-        {
-            max_lag = pt->last_plt_gtime + pt->period;
-            earliest_pt = pt;
+    list_for_each_entry_safe ( pt, temp, head, list )
+    {
+        if ( pt->pending_intr_nr )
+        {
+            if ( pt_irq_masked(pt) )
+            {
+                /* suspend timer emulation */
+                list_del(&pt->list);
+                pt->on_list = 0;
+            }
+            else
+            {
+                if ( (pt->last_plt_gtime + pt->period) < max_lag )
+                {
+                    max_lag = pt->last_plt_gtime + pt->period;
+                    earliest_pt = pt;
+                }
+            }
         }
     }
 
@@ -412,6 +423,7 @@ void destroy_periodic_time(struct period
     if ( pt->on_list )
         list_del(&pt->list);
     pt->on_list = 0;
+    pt->pending_intr_nr = 0;
     pt_unlock(pt);
 
     /*
@@ -451,11 +463,13 @@ static void pt_adjust_vcpu(struct period
 
 void pt_adjust_global_vcpu_target(struct vcpu *v)
 {
-    struct pl_time *pl_time = &v->domain->arch.hvm_domain.pl_time;
+    struct pl_time *pl_time;
     int i;
 
     if ( v == NULL )
         return;
+
+    pl_time = &v->domain->arch.hvm_domain.pl_time;
 
     spin_lock(&pl_time->vpit.lock);
     pt_adjust_vcpu(&pl_time->vpit.pt0, v);
@@ -470,3 +484,35 @@ void pt_adjust_global_vcpu_target(struct
         pt_adjust_vcpu(&pl_time->vhpet.pt[i], v);
     spin_unlock(&pl_time->vhpet.lock);
 }
+
+
+static void pt_resume(struct periodic_time *pt)
+{
+    if ( pt->vcpu == NULL )
+        return;
+
+    pt_lock(pt);
+    if ( pt->pending_intr_nr && !pt->on_list )
+    {
+        pt->on_list = 1;
+        list_add(&pt->list, &pt->vcpu->arch.hvm_vcpu.tm_list);
+        vcpu_kick(pt->vcpu);
+    }
+    pt_unlock(pt);
+}
+
+void pt_may_unmask_irq(struct domain *d, struct periodic_time *vlapic_pt)
+{
+    int i;
+
+    if ( d )
+    {
+        pt_resume(&d->arch.hvm_domain.pl_time.vpit.pt0);
+        pt_resume(&d->arch.hvm_domain.pl_time.vrtc.pt);
+        for ( i = 0; i < HPET_TIMER_NUM; i++ )
+            pt_resume(&d->arch.hvm_domain.pl_time.vhpet.pt[i]);
+    }
+
+    if ( vlapic_pt )
+        pt_resume(vlapic_pt);
+}
diff -r 0c83979c1b56 -r 72d130772f36 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Wed Sep 16 09:29:17 2009 +0100
+++ b/xen/include/asm-x86/hvm/vpt.h     Wed Sep 16 09:30:41 2009 +0100
@@ -144,8 +144,10 @@ void pt_adjust_global_vcpu_target(struct
 #define pt_global_vcpu_target(d) \
     ((d)->arch.hvm_domain.i8259_target ? : (d)->vcpu ? (d)->vcpu[0] : NULL)
 
+void pt_may_unmask_irq(struct domain *d, struct periodic_time *vlapic_pt);
+
 /* Is given periodic timer active? */
-#define pt_active(pt) ((pt)->on_list)
+#define pt_active(pt) ((pt)->on_list || (pt)->pending_intr_nr)
 
 /*
  * Create/destroy a periodic (or one-shot!) timer.

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86 hvm: suspend platform timer emulation while its IRQ is masked, Xen patchbot-unstable <=