On 18.02.2012, at 00:00, Scott Wood wrote: > On 02/17/2012 11:13 AM, Alexander Graf wrote: >> 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. >> >> Signed-off-by: Alexander Graf <agraf@xxxxxxx> >> --- >> arch/powerpc/kvm/booke.c | 15 ++++++++++----- >> 1 files changed, 10 insertions(+), 5 deletions(-) >> >> diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c >> index bfb2092..de30b6d 100644 >> --- a/arch/powerpc/kvm/booke.c >> +++ b/arch/powerpc/kvm/booke.c >> @@ -572,6 +572,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, >> unsigned int exit_nr) >> { >> int r = RESUME_HOST; >> + int resched_needed = 1; >> >> /* update before a new last_exit_type is rewritten */ >> kvmppc_update_timing_stats(vcpu); >> @@ -602,25 +603,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; >> >> @@ -869,8 +866,16 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, >> BUG(); >> } >> >> - local_irq_disable(); >> + /* make sure we reschedule if we need to */ >> + while (resched_needed) { >> + local_irq_disable(); >> >> + resched_needed = need_resched(); >> + if (resched_needed) { >> + local_irq_enable(); >> + cond_resched(); >> + } >> + } >> kvmppc_core_prepare_to_enter(vcpu); >> >> if (!(r & RESUME_HOST)) { > > kvmppc_core_prepare_to_enter can enable interrupts (and block) if guest > MSR_WE is set. We may take an interrupt that wants a resched after > waking but before interrupts are disabled again. > > We also want to check for a resched in kvmppc_vcpu_run. So, the resched > check belongs in kvmppc_core_prepare_to_enter, something like: > > /* Check pending exceptions and deliver one, if possible. */ > void kvmppc_core_prepare_to_enter(struct kvm_vcpu *vcpu) > { > WARN_ON_ONCE(!irqs_disabled()); > > while (true) { > if (signal_pending(current)) > break; > > if (need_resched()) { > local_irq_enable(); > cond_resched(); > local_irq_disable(); > continue; > } > > kvmppc_core_check_exceptions(vcpu); > > if (vcpu->arch.shared->msr & MSR_WE) { > local_irq_enable(); > kvm_vcpu_block(vcpu); > local_irq_disable(); > > kvmppc_set_exit_type(vcpu, > EMULATED_MTMSRWE_EXITS); > continue; > } > > break; > } > } > > It would be simpler (both here and in the idle hcall) if we could just > drop support for CONFIG_PREEMPT=n. :-P When running with CONFIG_PREEMPT=n we don't have to worry about interrupts being enabled though, since we only preempt on known good checkpoints, right? While for CONFIG_PREEMPT=y we can always get preempted, rendering most of these checks void. So essentially we could just be lazy and do a "best effort" resched check, but not worry about races wrt guest entry/exit, right? And for real preemption modes we don't have to worry about any of the resched stuff IIUC, correct? Alex -- 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