RE: [v3 24/26] KVM: Update Posted-Interrupts Descriptor when vCPU is blocked

From: Wu, Feng
Date: Wed Dec 17 2014 - 22:17:07 EST




> -----Original Message-----
> From: kvm-owner@xxxxxxxxxxxxxxx [mailto:kvm-owner@xxxxxxxxxxxxxxx] On
> Behalf Of Paolo Bonzini
> Sent: Thursday, December 18, 2014 1:10 AM
> To: Wu, Feng; Thomas Gleixner; Ingo Molnar; H. Peter Anvin; x86@xxxxxxxxxx;
> Gleb Natapov; Paolo Bonzini; dwmw2@xxxxxxxxxxxxx; joro@xxxxxxxxxx; Alex
> Williamson
> Cc: iommu@xxxxxxxxxxxxxxxxxxxxxxxxxx; linux-kernel@xxxxxxxxxxxxxxx; KVM list;
> Eric Auger
> Subject: Re: [v3 24/26] KVM: Update Posted-Interrupts Descriptor when vCPU
> is blocked
>
>
>
> On 12/12/2014 16:14, Feng Wu wrote:
> > This patch updates the Posted-Interrupts Descriptor when vCPU
> > is blocked.
> >
> > pre-block:
> > - Add the vCPU to the blocked per-CPU list
> > - Clear 'SN'
>
> Should SN be already clear (and NV set to POSTED_INTR_VECTOR)?

I think the SN bit should be clear here, Adding it here is just to make sure
SN is clear when vCPU is blocked, so it can receive wakeup notification event later.

> Can it
> happen that you go from sched-out to blocked without doing a sched-in first?
>

I cannot imagine this scenario, can you please be more specific? Thanks a lot!

> In fact, if this is possible, what happens if vcpu->preempted &&
> vcpu->blocked?

In fact, vcpu->preempted && vcpu->blocked happens sometimes, but I think there is
no issues. Please refer to the following case:

kvm_vcpu_block()
-> vcpu->blocked = true;
-> prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);

before schedule() is called, this vcpu is woken up by another guy, so
the state of the vcpu associated thread is changed to TASK_RUNNING,
then preemption happens after interrupts or the following schedule() is
hit, this will call kvm_sched_out(), in which current->state == TASK_RUNNING
and vcpu->preempted is set to true. So now vcpu->preempted and vcpu->blocked
are both true. In vmx_vcpu_put(), we will check vcpu->preempted first, so
the vCPU will not be blocked, and the vcpu->blocked will be set the false in
vmx_vcpu_load().

But maybe I need do a little change to the vmx_vcpu_load() like below:

/*
* Delete the vCPU from the related wakeup queue
* if we are resuming from blocked state
*/
if (vcpu->blocked) {
vcpu->blocked = false;
+ /* if wakeup_cpu == -1, the vcpu is currently not blocked on any
+ pCPU, don't need dequeue here */
+ if (vcpu->wakeup_cpu != -1) {
spin_lock_irqsave(&per_cpu(blocked_vcpu_on_cpu_lock,
vcpu->wakeup_cpu), flags);
list_del(&vcpu->blocked_vcpu_list);
spin_unlock_irqrestore(&per_cpu(blocked_vcpu_on_cpu_lock,
vcpu->wakeup_cpu), flags);
vcpu->wakeup_cpu = -1;
+ }
}

Any ideas about this? Thanks a lot!

Thanks,
Feng


-> schedule();


>
> > - Set 'NV' to POSTED_INTR_WAKEUP_VECTOR
> >
> > post-block:
> > - Remove the vCPU from the per-CPU list
>
> Paolo
>
> > Signed-off-by: Feng Wu <feng.wu@xxxxxxxxx>
> --
> 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 linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/