From: Paolo Bonzini <pbonzini@redhat.com>
To: Sean Christopherson <seanjc@google.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
zhanghao <zhanghao1@kylinos.cn>, Wanpeng Li <kernellwp@gmail.com>
Subject: Re: [PATCH] KVM: Drop kvm_vcpu.ready to squash race where "ready" can get stuck "true"
Date: Tue, 14 Apr 2026 18:06:54 +0200 [thread overview]
Message-ID: <cb458ee1-e0c7-43e2-83a0-9effd9a723af@redhat.com> (raw)
In-Reply-To: <20260409213333.1995382-1-seanjc@google.com>
On 4/9/26 23:33, Sean Christopherson wrote:
> +static inline bool kvm_vcpu_is_runnable_and_scheduled_out(struct kvm_vcpu *vcpu)
> +{
> + return READ_ONCE(vcpu->preempted) ||
> + (READ_ONCE(vcpu->scheduled_out) &&
> + READ_ONCE(vcpu->wants_to_run) &&
wants_to_run doesn't seem important here, because blocking will never be
set outside KVM_RUN (unlike scheduled_out which can be set within any
vcpu_load/vcpu_put pair, if you're unlucky enough).
> + READ_ONCE(vcpu->stat.generic.blocking) &&
> + !kvm_vcpu_is_blocking(vcpu));
If you get here you have done the finish_rcuwait() in kvm_vcpu_block(),
meaning that you've been already scheduled in, haven't you? So, you
would need something like this:
static inline bool kvm_vcpu_is_runnable_and_scheduled_out(struct
kvm_vcpu *vcpu)
{
if (READ_ONCE(vcpu->preempted))
return true;
if (!READ_ONCE(vcpu->scheduled_out))
return false;
if (!READ_ONCE(vcpu->stat.generic.blocking))
return false;
return rcuwait_was_woken(kvm_arch_vcpu_get_wait(vcpu));
}
// in rcuwait.h
static inline bool rcuwait_was_woken(struct rcuwait *w)
{
guard(rcu)();
struct task_struct *t = rcu_access_pointer(w->task);
return t && !task_is_runnable(t);
}
Paolo
> +}
> +
> #ifdef __KVM_HAVE_ARCH_INTC_INITIALIZED
> /*
> * returns true if the virtual interrupt controller is initialized and
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 9faf70ccae7a..9f71e32daac5 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -455,7 +455,6 @@ static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
> kvm_vcpu_set_in_spin_loop(vcpu, false);
> kvm_vcpu_set_dy_eligible(vcpu, false);
> vcpu->preempted = false;
> - vcpu->ready = false;
> preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops);
> vcpu->last_used_slot = NULL;
>
> @@ -3803,7 +3802,6 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_halt);
> bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)
> {
> if (__kvm_vcpu_wake_up(vcpu)) {
> - WRITE_ONCE(vcpu->ready, true);
> ++vcpu->stat.generic.halt_wakeup;
> return true;
> }
> @@ -4008,7 +4006,7 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *me, bool yield_to_kernel_mode)
> continue;
>
> vcpu = xa_load(&kvm->vcpu_array, idx);
> - if (!READ_ONCE(vcpu->ready))
> + if (!kvm_vcpu_is_runnable_and_scheduled_out(vcpu))
> continue;
> if (kvm_vcpu_is_blocking(vcpu) && !vcpu_dy_runnable(vcpu))
> continue;
> @@ -6393,7 +6391,6 @@ static void kvm_sched_in(struct preempt_notifier *pn, int cpu)
> struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
>
> WRITE_ONCE(vcpu->preempted, false);
> - WRITE_ONCE(vcpu->ready, false);
>
> __this_cpu_write(kvm_running_vcpu, vcpu);
> kvm_arch_vcpu_load(vcpu, cpu);
> @@ -6408,10 +6405,9 @@ static void kvm_sched_out(struct preempt_notifier *pn,
>
> WRITE_ONCE(vcpu->scheduled_out, true);
>
> - if (task_is_runnable(current) && vcpu->wants_to_run) {
> + if (task_is_runnable(current) && vcpu->wants_to_run)
> WRITE_ONCE(vcpu->preempted, true);
> - WRITE_ONCE(vcpu->ready, true);
> - }
> +
> kvm_arch_vcpu_put(vcpu);
> __this_cpu_write(kvm_running_vcpu, NULL);
> }
>
> base-commit: b89df297a47e641581ee67793592e5c6ae0428f4
next prev parent reply other threads:[~2026-04-14 16:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-09 21:33 [PATCH] KVM: Drop kvm_vcpu.ready to squash race where "ready" can get stuck "true" Sean Christopherson
2026-04-14 9:09 ` zhanghao
2026-04-14 13:44 ` Sean Christopherson
2026-04-14 16:06 ` Paolo Bonzini [this message]
2026-04-14 22:38 ` Sean Christopherson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cb458ee1-e0c7-43e2-83a0-9effd9a723af@redhat.com \
--to=pbonzini@redhat.com \
--cc=kernellwp@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=seanjc@google.com \
--cc=zhanghao1@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox