All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] x86 hvm: freeze PIT/LAPIC timer emulation while its IRQ is masked
@ 2009-09-10  5:47 Kouya Shimura
  2009-09-10  6:49 ` Keir Fraser
  2009-09-11 12:07 ` Konrad Rzeszutek Wilk
  0 siblings, 2 replies; 18+ messages in thread
From: Kouya Shimura @ 2009-09-10  5:47 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: message body text --]
[-- Type: text/plain, Size: 328 bytes --]

Hi,

I've found that modern windows OS never use the PIT timer,
and neither cpu#0's LAPIC timer after boot.
Despite that, xen emulates them busily. It's inefficient.

Note: this patch ignores the IRQ mask of legacy i8259 since
rombios frequently modifies it.

Thanks,
Kouya

Signed-off-by: Kouya Shimura <kouya@jp.fujitsu.com>


[-- Attachment #2: freeze_vpt.patch --]
[-- Type: text/x-patch, Size: 5928 bytes --]

diff -r d2a32e24fe50 xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c	Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/hvm/i8254.c	Thu Sep 10 09:55:29 2009 +0900
@@ -421,6 +421,8 @@ static int pit_load(struct domain *d, hv
 
     spin_unlock(&pit->lock);
 
+    pt_freeze_pit_timer_if_irqmasked(d);
+
     return 0;
 }
 
diff -r d2a32e24fe50 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c	Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/hvm/vioapic.c	Thu Sep 10 09:55:29 2009 +0900
@@ -158,6 +158,9 @@ static void vioapic_write_redirent(
         pent->fields.remote_irr = 1;
         vioapic_deliver(vioapic, idx);
     }
+
+    if ( idx == hvm_isa_irq_to_gsi(0) && !top_word )
+        pt_freeze_pit_timer_if_irqmasked(d);
 
     spin_unlock(&d->arch.hvm_domain.irq_lock);
 }
diff -r d2a32e24fe50 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c	Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/hvm/vlapic.c	Thu Sep 10 09:55:29 2009 +0900
@@ -655,6 +655,8 @@ static int vlapic_write(struct vcpu *v, 
         vlapic_set_reg(vlapic, offset, val);
         if ( offset == APIC_LVT0 )
             vlapic_adjust_i8259_target(v->domain);
+        if ( offset == APIC_LVTT )
+            pt_freeze_lapic_timer_if_irqmasked(&vlapic->pt);
         break;
 
     case APIC_TMICT:
@@ -770,10 +772,13 @@ void vlapic_adjust_i8259_target(struct d
     v = d->vcpu ? d->vcpu[0] : NULL;
 
  found:
-    if ( d->arch.hvm_domain.i8259_target == v )
-        return;
-    d->arch.hvm_domain.i8259_target = v;
-    pt_adjust_global_vcpu_target(v);
+    if ( d->arch.hvm_domain.i8259_target != v )
+    {
+        d->arch.hvm_domain.i8259_target = v;
+        pt_adjust_global_vcpu_target(v);
+    }
+
+    pt_freeze_pit_timer_if_irqmasked(d);
 }
 
 int vlapic_has_pending_irq(struct vcpu *v)
@@ -934,6 +939,7 @@ static int lapic_load_regs(struct domain
 
     vlapic_adjust_i8259_target(d);
     lapic_rearm(s);
+    pt_freeze_lapic_timer_if_irqmasked(&s->pt);
     return 0;
 }
 
diff -r d2a32e24fe50 xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c	Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/arch/x86/hvm/vpt.c	Thu Sep 10 09:55:29 2009 +0900
@@ -211,6 +211,10 @@ static void pt_timer_fn(void *data)
         pt_process_missed_ticks(pt);
         set_timer(&pt->timer, pt->scheduled);
     }
+    else
+    {
+        pt->frozen_by_irqmask = 0;
+    }
 
     if ( !pt_irq_masked(pt) )
         vcpu_kick(pt->vcpu);
@@ -394,6 +398,7 @@ void create_periodic_time(
 
     pt->on_list = 1;
     list_add(&pt->list, &v->arch.hvm_vcpu.tm_list);
+    pt->frozen_by_irqmask = 0;
 
     init_timer(&pt->timer, pt_timer_fn, pt, v->processor);
     set_timer(&pt->timer, pt->scheduled);
@@ -411,6 +416,7 @@ void destroy_periodic_time(struct period
     if ( pt->on_list )
         list_del(&pt->list);
     pt->on_list = 0;
+    pt->frozen_by_irqmask = 0;
     pt_unlock(pt);
 
     /*
@@ -469,3 +475,75 @@ 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_freeze_timer(struct periodic_time *pt)
+{
+    struct vcpu *v = NULL;
+
+    pt_lock(pt);
+    if ( pt->on_list )
+    {
+        v = pt->vcpu;
+        pt->frozen_by_irqmask = 1;
+        pt->on_list = 0;
+        list_del(&pt->list);
+        stop_timer(&pt->timer);
+    }
+    pt_unlock(pt);
+
+    if ( v )
+        gdprintk(XENLOG_INFO, "vcpu%d freeze %s timer(irq=%d)\n", v->vcpu_id,
+                 pt->source == PTSRC_lapic ? "LAPIC" : "ISA", pt->irq);
+}
+
+static void pt_thaw_timer(struct periodic_time *pt)
+{
+    struct vcpu *v = NULL;
+
+    pt_lock(pt);
+    if ( !pt->on_list && pt->frozen_by_irqmask )
+    {
+        v = pt->vcpu;
+        pt->on_list = 1;
+        list_add(&pt->list, &v->arch.hvm_vcpu.tm_list);
+        migrate_timer(&pt->timer, v->processor);
+        /*
+         * It may set the past time, however, TIMER_SOFTIRQ is raised
+         * and pt_timer_fn() will reset the timer appropriately.
+         */
+        set_timer(&pt->timer, pt->scheduled);
+    }
+    pt->frozen_by_irqmask = 0;
+    pt_unlock(pt);
+
+    if ( v )
+        gdprintk(XENLOG_INFO, "vcpu%d thaw %s timer(irq=%d)\n", v->vcpu_id,
+                 pt->source == PTSRC_lapic ? "LAPIC" : "ISA", pt->irq);
+}
+
+void pt_freeze_pit_timer_if_irqmasked(struct domain *d)
+{
+    struct periodic_time *pt = &d->arch.hvm_domain.pl_time.vpit.pt0;
+    unsigned int gsi = hvm_isa_irq_to_gsi(pt->irq);
+
+    if ( pt->vcpu == NULL )
+        return;
+
+    if ( !vlapic_accept_pic_intr(pt->vcpu) &&
+         domain_vioapic(d)->redirtbl[gsi].fields.mask )
+        pt_freeze_timer(pt);
+    else
+        pt_thaw_timer(pt);
+}
+
+void pt_freeze_lapic_timer_if_irqmasked(struct periodic_time *pt)
+{
+    if ( pt->vcpu == NULL )
+        return;
+
+    if (vlapic_get_reg(vcpu_vlapic(pt->vcpu), APIC_LVTT) & APIC_LVT_MASKED)
+        pt_freeze_timer(pt);
+    else
+        pt_thaw_timer(pt);
+}
diff -r d2a32e24fe50 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h	Wed Sep 09 16:39:41 2009 +0100
+++ b/xen/include/asm-x86/hvm/vpt.h	Thu Sep 10 09:55:29 2009 +0900
@@ -44,6 +44,7 @@ struct periodic_time {
     bool_t do_not_freeze;
     bool_t irq_issued;
     bool_t warned_timeout_too_short;
+    bool_t frozen_by_irqmask;
 #define PTSRC_isa    1 /* ISA time source */
 #define PTSRC_lapic  2 /* LAPIC time source */
     u8 source;                  /* PTSRC_ */
@@ -145,7 +146,10 @@ void pt_adjust_global_vcpu_target(struct
     ((d)->arch.hvm_domain.i8259_target ? : (d)->vcpu ? (d)->vcpu[0] : NULL)
 
 /* Is given periodic timer active? */
-#define pt_active(pt) ((pt)->on_list)
+#define pt_active(pt) ((pt)->on_list || (pt)->frozen_by_irqmask)
+
+void pt_freeze_pit_timer_if_irqmasked(struct domain *d);
+void pt_freeze_lapic_timer_if_irqmasked(struct periodic_time *pt);
 
 /*
  * Create/destroy a periodic (or one-shot!) timer.

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2009-09-16  9:09 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-10  5:47 [PATCH] x86 hvm: freeze PIT/LAPIC timer emulation while its IRQ is masked Kouya Shimura
2009-09-10  6:49 ` Keir Fraser
2009-09-10  8:22   ` Kouya Shimura
2009-09-10  8:32     ` Keir Fraser
2009-09-10  9:54       ` Kouya Shimura
2009-09-10 12:32         ` Keir Fraser
2009-09-16  6:46           ` Kouya Shimura
2009-09-16  6:50             ` [PATCH 1/2] x86 hvm: don't set periodical timer again until its IRQ is delivered Kouya Shimura
2009-09-16  6:53               ` [PATCH 2/2] x86 hvm: suspend platform timer emulation while its IRQ is masked Kouya Shimura
2009-09-16  7:40             ` [PATCH] x86 hvm: freeze PIT/LAPIC " Keir Fraser
2009-09-16  8:00               ` Cui, Dexuan
2009-09-16  8:20                 ` Keir Fraser
2009-09-16  8:40                   ` Cui, Dexuan
2009-09-16  9:09                     ` Keir Fraser
2009-09-16  8:28                 ` Kouya Shimura
2009-09-16  8:36                   ` Keir Fraser
2009-09-11 12:07 ` Konrad Rzeszutek Wilk
2009-09-14  5:58   ` Kouya Shimura

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.