From: Maxim Levitsky <mlevitsk@redhat.com>
To: Paolo Bonzini <pbonzini@redhat.com>, kvm@vger.kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>,
Sean Christopherson <seanjc@google.com>,
linux-kernel@vger.kernel.org,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, Borislav Petkov <bp@alien8.de>
Subject: Re: [PATCH 1/3] KVM: x86: VMX: __kvm_apic_update_irr must update the IRR atomically
Date: Tue, 18 Jul 2023 16:35:30 +0300 [thread overview]
Message-ID: <f867061cdc25ee887e43ebf6164733b309ccd631.camel@redhat.com> (raw)
In-Reply-To: <bda79e85-c0bf-8d59-2750-d922a59bb859@redhat.com>
У вт, 2023-07-18 у 13:41 +0200, Paolo Bonzini пише:
> On 7/18/23 11:13, Maxim Levitsky wrote:
> > + irr_val = READ_ONCE(*((u32 *)(regs + APIC_IRR + i * 0x10)));
>
> Let's separate out the complicated arithmetic, as it recurs below too:
>
> u32 *p_irr = (u32 *)(regs + APIC_IRR + i * 0x10);
No objections at all for this change, I wanted to have a minimal patch.
>
> > + while (!try_cmpxchg(((u32 *)(regs + APIC_IRR + i * 0x10)),
> > + &irr_val, irr_val | pir_val));
> > +
> > prev_irr_val = irr_val;
> > - irr_val |= xchg(&pir[i], 0);
> > - *((u32 *)(regs + APIC_IRR + i * 0x10)) = irr_val;
> > - if (prev_irr_val != irr_val) {
> > - max_updated_irr =
> > - __fls(irr_val ^ prev_irr_val) + vec;
> > - }
> > + irr_val |= pir_val;
> > +
> > + if (prev_irr_val != irr_val)
> > + max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec;
>
> We can write this a bit more cleanly too, and avoid unnecessary
To be honest as far as I see, no matter what to do with this function, it is still
a bit complicated IMHO:
The root cause of the complexity in this function is that it does two things at the same time -
copies both the new bits to IRR and also counts the max_irr.
It would be so much cleaner to first copy new bits from PIR to irr (and that can be done
with 'lock or' or even by setting each bit with atomic bit set (in this way the setting of the bits
will be pretty much the same as what other users of IRR do (set bit atomically + set irr_pending).
And then let the common code count the max_irr.
I doubt this will affect performance in any way, but I don't have a good way to measure it,
so I won't be arguing about it.
On the other hand, I am thinking now that maybe I should make the cmpxchg conditional on
apicv beeing inhibited, as otherwise it works for nothing and actually might affect performance.
This though might in theory cause a race if a sender incorrectly thinks that this's vCPU APICv is
inhibited or not.
It probalby doesn't matter as the only reason for APICv to be inhibited is that AutoEOI thing which
should happen just once when the guest boots.
I also have another idea - I can make the IPI senders still set bits in the PIR even if APICv is inhibited,
then there is no race to worry about although then the bits will always have to be copied from PIR to IRR
(but then again APICv inhibition is rare).
> try_cmpxchg too:
>
> prev_irr_val = irr_val;
> do
> irr_val = prev_irr_val | pir_val;
> while (prev_irr_val != irr_val &&
> !try_cmpxchg(p_irr, &prev_irr_val, irr_val));
>
> if (prev_irr_val != irr_val)
> max_updated_irr = __fls(irr_val ^ prev_irr_val) + vec;
>
> If this looks okay to you, I'll queue the patches for -rc3 and also Cc
> them for inclusion in stable kernels.
No objections for this change as well.
Best regards,
Maxim Levitsky
>
> Paolo
>
next prev parent reply other threads:[~2023-07-18 13:36 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-18 9:13 [PATCH 0/3] Fix 'Spurious APIC interrupt (vector 0xFF) on CPU#n' issue Maxim Levitsky
2023-07-18 9:13 ` [PATCH 1/3] KVM: x86: VMX: __kvm_apic_update_irr must update the IRR atomically Maxim Levitsky
2023-07-18 11:41 ` Paolo Bonzini
2023-07-18 13:35 ` Maxim Levitsky [this message]
2023-07-18 9:13 ` [PATCH 2/3] KVM: x86: VMX: set irr_pending in kvm_apic_update_irr Maxim Levitsky
2023-07-18 9:13 ` [PATCH 3/3] KVM: x86: check the kvm_cpu_get_interrupt result before using it Maxim Levitsky
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=f867061cdc25ee887e43ebf6164733b309ccd631.camel@redhat.com \
--to=mlevitsk@redhat.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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
all inboxes | Powered by JetHome®