> -----Original Message----- > From: kvm-owner@xxxxxxxxxxxxxxx [mailto:kvm-owner@xxxxxxxxxxxxxxx] On Behalf Of > Alexander Graf > Sent: Friday, February 24, 2012 7:56 PM > To: kvm-ppc@xxxxxxxxxxxxxxx > Cc: kvm@xxxxxxxxxxxxxxx; linuxppc-dev@xxxxxxxxxxxxxxxx; Wood Scott-B07421 > Subject: [PATCH 24/37] KVM: PPC: booke: rework rescheduling checks > > 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. > > 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 signal and > reschedule checking for us. > > Signed-off-by: Alexander Graf <agraf@xxxxxxx> > --- > arch/powerpc/include/asm/kvm_ppc.h | 2 +- > arch/powerpc/kvm/book3s.c | 4 ++- > arch/powerpc/kvm/booke.c | 70 ++++++++++++++++++++++++----------- > 3 files changed, 52 insertions(+), 24 deletions(-) > > 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); extern void > kvmppc_core_vcpu_put(struct kvm_vcpu *vcpu); > > -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 void > kvmppc_core_queue_dec(struct kvm_vcpu *vcpu); diff --git > a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 7d54f4e..c8ead7b > 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, unsigned > int priority) > return true; > } > > -void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) > +int kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) > { > unsigned long *pending = &vcpu->arch.pending_exceptions; > unsigned long old_pending = vcpu->arch.pending_exceptions; @@ -283,6 > +283,8 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) > > /* Tell the guest about our interrupt status */ > kvmppc_update_int_pending(vcpu, *pending, old_pending); > + > + return 0; > } > > 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..3fcec2c > 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_vcpu > *vcpu) } > > /* 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 = 0; > WARN_ON_ONCE(!irqs_disabled()); > > kvmppc_core_check_exceptions(vcpu); > @@ -451,8 +452,44 @@ void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) > local_irq_disable(); > > kvmppc_set_exit_type(vcpu, EMULATED_MTMSRWE_EXITS); > - kvmppc_core_check_exceptions(vcpu); > + r = 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 = 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 this 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 = 1; > + > + break; > + } > + > + return r; > } > > 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 *vcpu) > } > > local_irq_disable(); > - > - kvmppc_core_prepare_to_enter(vcpu); > - > - if (signal_pending(current)) { > + if (kvmppc_prepare_to_enter(vcpu, true)) { > kvm_run->exit_reason = KVM_EXIT_INTR; > ret = -EINTR; > goto out; > @@ -598,25 +632,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct > kvm_vcpu *vcpu, > > switch (exit_nr) { > case BOOKE_INTERRUPT_MACHINE_CHECK: > - kvm_resched(vcpu); > r = RESUME_GUEST; > break; > > case BOOKE_INTERRUPT_EXTERNAL: > kvmppc_account_exit(vcpu, EXT_INTR_EXITS); > - kvm_resched(vcpu); > r = RESUME_GUEST; > break; > > case BOOKE_INTERRUPT_DECREMENTER: > kvmppc_account_exit(vcpu, DEC_EXITS); > - kvm_resched(vcpu); > r = RESUME_GUEST; > break; > > case BOOKE_INTERRUPT_DOORBELL: > kvmppc_account_exit(vcpu, DBELL_EXITS); > - kvm_resched(vcpu); > r = RESUME_GUEST; > break; > > @@ -865,19 +895,15 @@ int kvmppc_handle_exit(struct kvm_run *run, struct > kvm_vcpu *vcpu, > BUG(); > } > > + /* > + * 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 = KVM_EXIT_INTR; > - r = (-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 = KVM_EXIT_INTR; > + r = (-EINTR << 2) | RESUME_HOST | (r & RESUME_FLAG_NV); > + kvmppc_account_exit(vcpu, SIGNAL_EXITS); > } > > return r; > -- > 1.6.0.2 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a > message to majordomo@xxxxxxxxxxxxxxx More majordomo info at > http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html