Thread (51 messages) 51 messages, 3 authors, 2012-02-28

RE: [PATCH 24/37] KVM: PPC: booke: rework rescheduling checks

flat view

From: Bhushan Bharat-R65777 <hidden>
Date: 2012-02-27 16:35:04
Also in: kvm

-----Original Message-----
From: kvm-owner@vger.kernel.org [mailto:kvm-owner@vger.kernel.org] On Beh=
alf Of
Alexander Graf
Sent: Friday, February 24, 2012 7:56 PM
To: kvm-ppc@vger.kernel.org
Cc: kvm@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; Wood Scott-B07421
Subject: [PATCH 24/37] KVM: PPC: booke: rework rescheduling checks
=20
Instead of checking whether we should reschedule only when we exited due =
to an
interrupt, let's always check before entering the guest back again. This =
gets
the target more in line with the other archs.
=20
Also while at it, generalize the whole thing so that eventually we could =
have a
single kvmppc_prepare_to_enter function for all ppc targets that does sig=
nal and
reschedule checking for us.
=20
Signed-off-by: Alexander Graf <redacted>
---
 arch/powerpc/include/asm/kvm_ppc.h |    2 +-
 arch/powerpc/kvm/book3s.c          |    4 ++-
 arch/powerpc/kvm/booke.c           |   70 ++++++++++++++++++++++++------=
-----
quoted hunk ↗ jump to hunk
 3 files changed, 52 insertions(+), 24 deletions(-)
=20
diff --git a/arch/powerpc/include/asm/kvm_ppc.h
b/arch/powerpc/include/asm/kvm_ppc.h
index e709975..7f0a3da 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -95,7 +95,7 @@ extern int kvmppc_core_vcpu_translate(struct kvm_vcpu *=
vcpu,
extern void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu);  exter=
n void
kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu);
=20
-extern void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu);
+extern int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu);
 extern int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu);  extern void
kvmppc_core_queue_program(struct kvm_vcpu *vcpu, ulong flags);  extern vo=
id
kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); diff --git
a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 7d54f4e..c8=
ead7b
quoted hunk ↗ jump to hunk
100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -258,7 +258,7 @@ static bool clear_irqprio(struct kvm_vcpu *vcpu, unsi=
gned
int priority)
 	return true;
 }
=20
-void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
+int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
 {
 	unsigned long *pending =3D &vcpu->arch.pending_exceptions;
 	unsigned long old_pending =3D vcpu->arch.pending_exceptions; @@ -283,6
+283,8 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
=20
 	/* Tell the guest about our interrupt status */
 	kvmppc_update_int_pending(vcpu, *pending, old_pending);
+
+	return 0;
 }
=20
 pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn) diff --git
a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 9979be1..3fce=
c2c
quoted hunk ↗ jump to hunk
100644
--- a/arch/powerpc/kvm/booke.c
+++ b/arch/powerpc/kvm/booke.c
@@ -439,8 +439,9 @@ static void kvmppc_core_check_exceptions(struct kvm_v=
cpu
quoted hunk ↗ jump to hunk
*vcpu)  }
=20
 /* Check pending exceptions and deliver one, if possible. */ -void
kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
+int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu)
 {
+	int r =3D 0;
 	WARN_ON_ONCE(!irqs_disabled());
=20
 	kvmppc_core_check_exceptions(vcpu);
@@ -451,8 +452,44 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *v=
cpu)
 		local_irq_disable();
=20
 		kvmppc_set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS);
-		kvmppc_core_check_exceptions(vcpu);
+		r =3D 1;
 	};
+
+	return r;
+}
+
+/*
+ * Common checks before entering the guest world.  Call with interrupts
+ * disabled.
+ *
+ * returns !0 if a signal is pending and check_signal is true  */
+static int kvmppc_prepare_to_enter(struct kvm_vcpu *vcpu, bool
+check_signal) {
+	int r =3D 0;
+
+	WARN_ON_ONCE(!irqs_disabled());
+	while (true) {
+		if (need_resched()) {
+			local_irq_enable();
+			cond_resched();
+			local_irq_disable();
+			continue;
+		}
+
+		if (kvmppc_core_prepare_to_enter(vcpu)) {
kvmppc_prepare_to_enter() is called even on heavyweight_exit. Should not th=
is be called only on lightweight_exit?

Thanks
-Bharat
+			/* interrupts got enabled in between, so we
+			   are back at square 1 */
+			continue;
+		}
+
+		if (check_signal && signal_pending(current))
+			r =3D 1;
+
+		break;
+	}
+
+	return r;
 }
=20
 int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) @@ -=
470,10
+507,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *v=
cpu)
quoted hunk ↗ jump to hunk
 	}
=20
 	local_irq_disable();
-
-	kvmppc_core_prepare_to_enter(vcpu);
-
-	if (signal_pending(current)) {
+	if (kvmppc_prepare_to_enter(vcpu, true)) {
 		kvm_run->exit_reason =3D KVM_EXIT_INTR;
 		ret =3D -EINTR;
 		goto out;
@@ -598,25 +632,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct
kvm_vcpu *vcpu,
=20
 	switch (exit_nr) {
 	case BOOKE_INTERRUPT_MACHINE_CHECK:
-		kvm_resched(vcpu);
 		r =3D RESUME_GUEST;
 		break;
=20
 	case BOOKE_INTERRUPT_EXTERNAL:
 		kvmppc_account_exit(vcpu, EXT_INTR_EXITS);
-		kvm_resched(vcpu);
 		r =3D RESUME_GUEST;
 		break;
=20
 	case BOOKE_INTERRUPT_DECREMENTER:
 		kvmppc_account_exit(vcpu, DEC_EXITS);
-		kvm_resched(vcpu);
 		r =3D RESUME_GUEST;
 		break;
=20
 	case BOOKE_INTERRUPT_DOORBELL:
 		kvmppc_account_exit(vcpu, DBELL_EXITS);
-		kvm_resched(vcpu);
 		r =3D RESUME_GUEST;
 		break;
=20
@@ -865,19 +895,15 @@ int kvmppc_handle_exit(struct kvm_run *run, struct
kvm_vcpu *vcpu,
 		BUG();
 	}
=20
+	/*
+	 * To avoid clobbering exit_reason, only check for signals if we
+	 * aren't already exiting to userspace for some other reason.
+	 */
 	local_irq_disable();
-
-	kvmppc_core_prepare_to_enter(vcpu);
-
-	if (!(r & RESUME_HOST)) {
-		/* To avoid clobbering exit_reason, only check for signals if
-		 * we aren't already exiting to userspace for some other
-		 * reason. */
-		if (signal_pending(current)) {
-			run->exit_reason =3D KVM_EXIT_INTR;
-			r =3D (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV);
-			kvmppc_account_exit(vcpu, SIGNAL_EXITS);
-		}
+	if (kvmppc_prepare_to_enter(vcpu, !(r & RESUME_HOST))) {
+		run->exit_reason =3D KVM_EXIT_INTR;
+		r =3D (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV);
+		kvmppc_account_exit(vcpu, SIGNAL_EXITS);
 	}
=20
 	return r;
--
1.6.0.2
=20
--
To unsubscribe from this list: send the line "unsubscribe kvm" in the bod=
y of a
message to majordomo@vger.kernel.org More majordomo info at
http://vger.kernel.org/majordomo-info.html
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help