All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: LAPIC: make the kvm unblock information globally seen before calling kvm_vcpu_kick
@ 2017-10-25  7:26 Zhuangyanying
  2017-10-27 22:41 ` Paolo Bonzini
  0 siblings, 1 reply; 2+ messages in thread
From: Zhuangyanying @ 2017-10-25  7:26 UTC (permalink / raw)
  To: kvm, pbonzini, longman, xiexiangyou, liuxiaojian6

From: Xiangyou Xie <xiexiangyou@huawei.com>

When the guest is using the pv-spinlock, and there is a race of vcpu1 decides to HALT and vcpu2 releasing the lock,  the vcpu2 might fail to wake up vcpu1.
In the case of PV spinlock, the vcpu2 executes the following to wake up vcpu:
case APIC_DM_REMRD:
	result = 1;
	vcpu->arch.pv.pv_unhalted = 1;
	kvm_make_request(KVM_REQ_EVENT, vcpu);
	kvm_vcpu_kick(vcpu);
	break;
Due to lack of smp_mb before kvm_vcpu_kick, the changes of pv_unhalted and vcpu->requests may be delayed to be after the operation of kvm_vcpu_kick.
On the other part, if the vcpu1 is just to execute the prepare_to_wait, vcpu2's kvm_vcpu_kick will have no effect, but vcpu1 fails to pass the kvm_vcpu_check_block() and as a result get blocked.
for (;;) {
          //------->when vcpu2 do the kvm_vcpu_kick, vcpu1 has not reached here
	prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);

	if (kvm_vcpu_check_block(vcpu) < 0)
		break;

	waited = true;
	schedule();
}

Adding an smp_mb() before vcpu2 doing the kvm_vcpu_kick works.

Signed-off-by: Xiangyou Xie<xiexiangyou@huawei.com>
Signed-off-by: Liuxiaojian <liuxiaojian6@huawei.com>
---
 arch/x86/kvm/lapic.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 69c5612..d37c0fd 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -987,6 +987,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
 		result = 1;
 		vcpu->arch.pv.pv_unhalted = 1;
 		kvm_make_request(KVM_REQ_EVENT, vcpu);
+		smp_mb();
 		kvm_vcpu_kick(vcpu);
 		break;
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] KVM: LAPIC: make the kvm unblock information globally seen before calling kvm_vcpu_kick
  2017-10-25  7:26 [PATCH] KVM: LAPIC: make the kvm unblock information globally seen before calling kvm_vcpu_kick Zhuangyanying
@ 2017-10-27 22:41 ` Paolo Bonzini
  0 siblings, 0 replies; 2+ messages in thread
From: Paolo Bonzini @ 2017-10-27 22:41 UTC (permalink / raw)
  To: Zhuangyanying, kvm, longman, xiexiangyou, liuxiaojian6

On 25/10/2017 09:26, Zhuangyanying wrote:
> From: Xiangyou Xie <xiexiangyou@huawei.com>
> 
> When the guest is using the pv-spinlock, and there is a race of vcpu1 decides to HALT and vcpu2 releasing the lock,  the vcpu2 might fail to wake up vcpu1.
> In the case of PV spinlock, the vcpu2 executes the following to wake up vcpu:
> case APIC_DM_REMRD:
> 	result = 1;
> 	vcpu->arch.pv.pv_unhalted = 1;
> 	kvm_make_request(KVM_REQ_EVENT, vcpu);
> 	kvm_vcpu_kick(vcpu);
> 	break;
> Due to lack of smp_mb before kvm_vcpu_kick, the changes of pv_unhalted
> and vcpu->requests may be delayed to be after the operation of kvm_vcpu_kick.

Since Linux 4.7 (commit 2e4682ba2ed7, "KVM: add missing memory barrier
in kvm_{make,check}_request", 2016-04-20), kvm_make_request has a smp_wmb().

However, even before that commit "set_bit" implicitly has a barrier on
x86, so there is no effect from the patch below.

Paolo

> On the other part, if the vcpu1 is just to execute the prepare_to_wait, vcpu2's kvm_vcpu_kick will have no effect, but vcpu1 fails to pass the kvm_vcpu_check_block() and as a result get blocked.
> for (;;) {
>           //------->when vcpu2 do the kvm_vcpu_kick, vcpu1 has not reached here
> 	prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
> 
> 	if (kvm_vcpu_check_block(vcpu) < 0)
> 		break;
> 
> 	waited = true;
> 	schedule();
> }
> 
> Adding an smp_mb() before vcpu2 doing the kvm_vcpu_kick works.
> 
> Signed-off-by: Xiangyou Xie<xiexiangyou@huawei.com>
> Signed-off-by: Liuxiaojian <liuxiaojian6@huawei.com>
> ---
>  arch/x86/kvm/lapic.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 69c5612..d37c0fd 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -987,6 +987,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
>  		result = 1;
>  		vcpu->arch.pv.pv_unhalted = 1;
>  		kvm_make_request(KVM_REQ_EVENT, vcpu);
> +		smp_mb();
>  		kvm_vcpu_kick(vcpu);
>  		break;
>  
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-10-27 22:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-25  7:26 [PATCH] KVM: LAPIC: make the kvm unblock information globally seen before calling kvm_vcpu_kick Zhuangyanying
2017-10-27 22:41 ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.