public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: "Yang, Sheng" <sheng.yang@intel.com>
To: kvm-devel@lists.sourceforge.net
Cc: Marcelo Tosatti <mtosatti@redhat.com>, Avi Kivity <avi@qumranet.com>
Subject: Re: [patch 1/2] KVM: hlt emulation should take in-kernel APIC/PIT timers into account
Date: Fri, 9 May 2008 15:49:20 +0800	[thread overview]
Message-ID: <200805091549.20620.sheng.yang@intel.com> (raw)
In-Reply-To: <4801D236.6000604@qumranet.com>

[-- Attachment #1: Type: text/plain, Size: 3958 bytes --]

On Sunday 13 April 2008 17:28:22 Avi Kivity wrote:
> Marcelo Tosatti wrote:
> > On Fri, Apr 11, 2008 at 03:12:41PM +0300, Avi Kivity wrote:
> >> This breaks ia64 (and shouldn't s390 use this too?)
> >>
> >>> 	 * We will block until either an interrupt or a signal wakes us up
> >>> 	 */
> >>> 	while (!kvm_cpu_has_interrupt(vcpu)
> >>> +	       && !kvm_cpu_has_pending_timer(vcpu)
> >>
> >> I guess the fix is to stub this out for the other archs.
> >
> > Agreed. How's this.
>
> Better :); applied.

Hi, Marcelo

This patch got into trouble when OS don't use PIT/LAPIC timer and don't 
disable them. Then the pending counters would keep increasing, but the HLT 
emulation can't be executed. And this would resulted in mass a lot (above 
220,000 per second) halt_exit for the Windows XP that using RTC as the 
clocksource (and keep PIT enabled after bios did, just mask the pin) idle, 
and the cpu utilize would be about 100% of QEmu process. 

The following patch used another way to fix the issue, though not very formal.

From 4d08ef3173084a6f0b7b76a0727e04ff42b614ba Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng.yang@intel.com>
Date: Fri, 9 May 2008 15:36:27 +0800
Subject: [PATCH] KVM: Fix CPU utilize hit 100% when emulate HLT in some OS


Signed-off-by: Sheng Yang <sheng.yang@intel.com>
---
 arch/x86/kvm/i8254.c       |    2 ++
 arch/x86/kvm/lapic.c       |    2 ++
 include/asm-x86/kvm_host.h |    2 ++
 virt/kvm/kvm_main.c        |    2 +-
 4 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index fba0e4e..b2b9eb7 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -199,6 +199,7 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
 	struct kvm_kpit_timer *pt = &ps->pit_timer;

 	atomic_inc(&pt->pending);
+	vcpu0->arch.timer_pending_updated = 1;
 	smp_mb__after_atomic_inc();
 	/* FIXME: handle case where the guest is in guest mode */
 	if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
@@ -577,6 +578,7 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_kpit_state *ps;

+	kvm->vcpus[0]->arch.timer_pending_updated = 0;
 	if (vcpu && pit) {
 		ps = &pit->pit_state;

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 7652f88..b919f3f 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -944,6 +944,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
 	wait_queue_head_t *q = &apic->vcpu->wq;

 	atomic_inc(&apic->timer.pending);
+	apic->vcpu->arch.timer_pending_updated = 1;
 	if (waitqueue_active(q)) {
 		apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 		wake_up_interruptible(q);
@@ -1067,6 +1068,7 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
 {
 	struct kvm_lapic *apic = vcpu->arch.apic;

+	vcpu->arch.timer_pending_updated = 0;
 	if (apic && apic_lvt_enabled(apic, APIC_LVTT) &&
 		atomic_read(&apic->timer.pending) > 0) {
 		if (__inject_apic_timer_irq(apic))
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 1d8cd01..5eded7b 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -285,6 +285,8 @@ struct kvm_vcpu_arch {
 	struct kvm_vcpu_time_info hv_clock;
 	unsigned int time_offset;
 	struct page *time_page;
+
+	bool timer_check_pending;
 };

 struct kvm_mem_alias {
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 0846d3d..ff635e3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -791,7 +791,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 	 * We will block until either an interrupt or a signal wakes us up
 	 */
 	while (!kvm_cpu_has_interrupt(vcpu)
-	       && !kvm_cpu_has_pending_timer(vcpu)
+	       && !vcpu->arch.timer_pending_updated
 	       && !signal_pending(current)
 	       && !kvm_arch_vcpu_runnable(vcpu)) {
 		set_current_state(TASK_INTERRUPTIBLE);
--
1.5.5


[-- Attachment #2: 0001-KVM-Fix-CPU-utilize-hit-100-when-emulate-HLT-in-so.patch --]
[-- Type: text/x-diff, Size: 2913 bytes --]

From 4d08ef3173084a6f0b7b76a0727e04ff42b614ba Mon Sep 17 00:00:00 2001
From: Sheng Yang <sheng.yang@intel.com>
Date: Fri, 9 May 2008 15:36:27 +0800
Subject: [PATCH] KVM: Fix CPU utilize hit 100% when emulate HLT in some OS


Signed-off-by: Sheng Yang <sheng.yang@intel.com>
---
 arch/x86/kvm/i8254.c       |    2 ++
 arch/x86/kvm/lapic.c       |    2 ++
 include/asm-x86/kvm_host.h |    2 ++
 virt/kvm/kvm_main.c        |    2 +-
 4 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index fba0e4e..b2b9eb7 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -199,6 +199,7 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
 	struct kvm_kpit_timer *pt = &ps->pit_timer;
 
 	atomic_inc(&pt->pending);
+	vcpu0->arch.timer_pending_updated = 1;
 	smp_mb__after_atomic_inc();
 	/* FIXME: handle case where the guest is in guest mode */
 	if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
@@ -577,6 +578,7 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_kpit_state *ps;
 
+	kvm->vcpus[0]->arch.timer_pending_updated = 0;
 	if (vcpu && pit) {
 		ps = &pit->pit_state;
 
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 7652f88..b919f3f 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -944,6 +944,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
 	wait_queue_head_t *q = &apic->vcpu->wq;
 
 	atomic_inc(&apic->timer.pending);
+	apic->vcpu->arch.timer_pending_updated = 1;
 	if (waitqueue_active(q)) {
 		apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
 		wake_up_interruptible(q);
@@ -1067,6 +1068,7 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu)
 {
 	struct kvm_lapic *apic = vcpu->arch.apic;
 
+	vcpu->arch.timer_pending_updated = 0;
 	if (apic && apic_lvt_enabled(apic, APIC_LVTT) &&
 		atomic_read(&apic->timer.pending) > 0) {
 		if (__inject_apic_timer_irq(apic))
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 1d8cd01..5eded7b 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -285,6 +285,8 @@ struct kvm_vcpu_arch {
 	struct kvm_vcpu_time_info hv_clock;
 	unsigned int time_offset;
 	struct page *time_page;
+
+	bool timer_check_pending;
 };
 
 struct kvm_mem_alias {
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 0846d3d..ff635e3 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -791,7 +791,7 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
 	 * We will block until either an interrupt or a signal wakes us up
 	 */
 	while (!kvm_cpu_has_interrupt(vcpu)
-	       && !kvm_cpu_has_pending_timer(vcpu)
+	       && !vcpu->arch.timer_pending_updated
 	       && !signal_pending(current)
 	       && !kvm_arch_vcpu_runnable(vcpu)) {
 		set_current_state(TASK_INTERRUPTIBLE);
-- 
1.5.5


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

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

[-- Attachment #4: Type: text/plain, Size: 158 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

  reply	other threads:[~2008-05-09  7:49 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-10 20:12 [patch 0/2] fix in-kernel timer / IRQ injection races Marcelo Tosatti
2008-04-10 20:12 ` [patch 1/2] KVM: hlt emulation should take in-kernel APIC/PIT timers into account Marcelo Tosatti
2008-04-11 12:12   ` Avi Kivity
2008-04-11 17:53     ` Marcelo Tosatti
2008-04-13  9:28       ` Avi Kivity
2008-05-09  7:49         ` Yang, Sheng [this message]
2008-05-09 14:53           ` Marcelo Tosatti
2008-05-10  2:12             ` Yang, Sheng
2008-05-12 16:40               ` Marcelo Tosatti
2008-05-14  3:03                 ` Yang, Sheng
2008-04-11 22:30     ` Carsten Otte
2008-04-13  9:47       ` Avi Kivity
2008-04-14  9:18         ` Carsten Otte
2008-04-10 20:12 ` [patch 2/2] KVM: fix kvm_vcpu_kick vs __vcpu_run race Marcelo Tosatti
2008-04-11 12:18   ` Avi Kivity
2008-04-11 18:01     ` Marcelo Tosatti
2008-04-13 10:08       ` Avi Kivity
2008-04-13 16:07         ` Avi Kivity
2008-04-13 16:35           ` Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200805091549.20620.sheng.yang@intel.com \
    --to=sheng.yang@intel.com \
    --cc=avi@qumranet.com \
    --cc=kvm-devel@lists.sourceforge.net \
    --cc=mtosatti@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox