From: Gleb Natapov <gleb@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCHv1 dont apply] RFC: kvm eoi PV using shared memory
Date: Mon, 16 Apr 2012 18:10:11 +0300 [thread overview]
Message-ID: <20120416151011.GB18613@redhat.com> (raw)
In-Reply-To: <20120416131328.GF11605@redhat.com>
On Mon, Apr 16, 2012 at 04:13:29PM +0300, Michael S. Tsirkin wrote:
> On Mon, Apr 16, 2012 at 03:30:47PM +0300, Gleb Natapov wrote:
> > On Mon, Apr 16, 2012 at 03:18:25PM +0300, Michael S. Tsirkin wrote:
> > > On Mon, Apr 16, 2012 at 02:24:46PM +0300, Gleb Natapov wrote:
> > > > On Mon, Apr 16, 2012 at 02:09:20PM +0300, Michael S. Tsirkin wrote:
> > > > > Thanks very much for the review. I'll address the comments.
> > > > > Some questions on your comments below.
> > > > >
> > > > > On Mon, Apr 16, 2012 at 01:08:07PM +0300, Gleb Natapov wrote:
> > > > > > > @@ -37,6 +38,8 @@
> > > > > > > #define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
> > > > > > > #define MSR_KVM_ASYNC_PF_EN 0x4b564d02
> > > > > > > #define MSR_KVM_STEAL_TIME 0x4b564d03
> > > > > > > +#define MSR_KVM_EOI_EN 0x4b564d04
> > > > > > > +#define MSR_KVM_EOI_DISABLED 0x0L
> > > > > > This is valid gpa. Follow others MSR example i.e align the address to,
> > > > > > lets say dword, and use lsb as enable bit.
> > > > >
> > > > > We only need a single byte, since this is per-CPU -
> > > > > it's better to save the memory, so no alignment is required.
> > > > > An explicit disable msr would also address this, right?
> > > > >
> > > > We do not have shortage of memory.
> > > > Better make all MSRs works the same
> > > > way.
> > >
> > > I agree it's nice to have EOI and ASYNC_PF look similar
> > > but wasting memory is also bad. I'll ponder this some more.
> > >
> > Steal time and kvm clock too and may be others (if anything left at
> > all). I hope you are kidding about wasting of 4 bytes per vcpu.
>
> Not vcpu - cpu. It's wasted whenever kernel/kvm.c is built so it has
> cost on physical machines as well.
>
There are less real cpus than vcpus usually :)
> > > > BTW have you added new MSR to msrs_to_save array? I forgot to
> > > > checked.
> > >
> > > I didn't yet. Trying to understand how will that affect
> > > cross-version migration - any input?
> > >
> > Not sure. You need to check what userspace does with them.
> >
> > > > > > > +static void apic_update_isr(struct kvm_lapic *apic)
> > > > > > > +{
> > > > > > > + int vector;
> > > > > > > + if (!eoi_enabled(apic->vcpu) ||
> > > > > > > + !apic->vcpu->arch.eoi.pending ||
> > > > > > > + eoi_get_pending(apic->vcpu))
> > > > > > > + return;
> > > > > > > + apic->vcpu->arch.eoi.pending = false;
> > > > > > > + vector = apic_find_highest_isr(apic);
> > > > > > > + if (vector == -1)
> > > > > > > + return;
> > > > > > > + apic_clear_vector(vector, apic->regs + APIC_ISR);
> > > > > > > +}
> > > > > > > +
> > > > > > We should just call apic_set_eoi() on exit if eoi.pending && !eoi_get_pending().
> > > > > > This removes the need for the function and its calls.
> > > > >
> > > > > It's a bit of a waste: that one does all kind extra things
> > > > > which we know we don't need, some of the atomics. And it's datapath
> > > > > so extra stuff is not free.
> > > > >
> > > > How much time those extra things are taking compared to vmexit you
> > > > already serving? And there is a good chance you will do them during
> > > > vmentry anyway while trying to inject (or just check for) new interrupt.
> > >
> > > No need to do them twice :)
> > >
> > > > > Probably a good idea to replace the call on MSR disable - I think
> > > > > apic_update_ppr is a better thing to call there.
> > > > >
> > > > > Is there anything else that I missed?
> > > > I think that simple things are better then complex things if the end result is
> > > > the same :) Try it and see how much simpler it is.
> > >
> > > It doesn't seem to be simpler at all. The common functionality is
> > > about 4 lines.
> > Send patch for us to see.
>
> That's what you are replying to, no?
> You can see that it is 4 lines of code.
No. I mean something like patch below. Applies on top of yours. Did not
check that it works or even compiles.
>
> > lapic changes should be minimal.
>
> Exactly my motivation.
>
My patch removes 13 lines more :)
> > >
> > > > Have you measured
> > > > that what you are trying to optimize actually worth optimizing? That you
> > > > can measure the optimization at all?
> > >
> > > The claim is not that it's measureable. The claim is that
> > > it does not scale to keep adding things to do on each entry.
> > >
> > Only if there is something to do. "Premature optimization is the root of
> > all evil". The PV eoi is about not exiting on eoi unnecessary. You are
> > mixing this with trying to avoid calling eoi code for given interrupt at
> > all.
>
> I don't think this is what my patch does. EOI still clears ISR
> for each interrupt.
>
> > Two different optimization, do not try lump them together.
> > > > >
> > > > > > We already have
> > > > > > call to kvm_lapic_sync_from_vapic() on exit path which should be
> > > > > > extended to do the above.
> > > > >
> > > > > It already does this. It calls apic_set_tpr
> > > > > which calls apic_update_ppr which calls
> > > > > apic_update_isr.
> > > > >
> > > > It does it only if vapic is in use (and it is usually not).
> > >
> > > When it's not we don't need to update ppr and so
> > > no need to update isr on this exit.
> > If there was eoi we need to update both.
>
> By same logic we should call update_ppr on each entry.
> The overhead is unlikely to be measureable either :).
>
It is small enough for us to not care about it on RHEL6 where it is
called on each entry.
> > >
> > > > But the if()
> > > > is already there so we do not need to worry that one additional if() on
> > > > the exit path will slow KVM to the crawl.
> > >
> > > The number of things we need to do on each entry keeps going up, if we
> > > just keep adding stuff it won't end well.
> > >
> > You do not add stuff. The if() is already there.
>
>
> Your proposal was to check userspace eoi record
> each time when eoi is pending, no?
Yes.
> This would certainly add some overhead.
>
Only when eoi is pending. This is rare.
> I also find the logic easier to follow as is -
> it is contained in lapic.c without relying
> on being called from x86.c as just the right moment.
>
See the patch. It change nothing outside of lapic.c.
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index d184a41..8fb5eca 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -323,20 +323,6 @@ static inline int apic_find_highest_isr(struct kvm_lapic *apic)
return result;
}
-static void apic_update_isr(struct kvm_lapic *apic)
-{
- int vector;
- if (!eoi_enabled(apic->vcpu) ||
- !apic->vcpu->arch.eoi.pending ||
- eoi_get_pending(apic->vcpu))
- return;
- apic->vcpu->arch.eoi.pending = false;
- vector = apic_find_highest_isr(apic);
- if (vector == -1)
- return;
- apic_clear_vector(vector, apic->regs + APIC_ISR);
-}
-
static void apic_update_ppr(struct kvm_lapic *apic)
{
u32 tpr, isrv, ppr, old_ppr;
@@ -344,7 +330,6 @@ static void apic_update_ppr(struct kvm_lapic *apic)
old_ppr = apic_get_reg(apic, APIC_PROCPRI);
tpr = apic_get_reg(apic, APIC_TASKPRI);
- apic_update_isr(apic);
isr = apic_find_highest_isr(apic);
isrv = (isr != -1) ? isr : 0;
@@ -1361,14 +1346,19 @@ void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu)
u32 data;
void *vapic;
- if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr)
+ if (!irqchip_in_kernel(vcpu->kvm) || !vcpu->arch.apic->vapic_addr ||
+ !apic->vcpu->arch.eoi.pending)
return;
- vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
- data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
- kunmap_atomic(vapic);
+ if (apic->vcpu->arch.eoi.pending && !eoi_get_pending(apic->vcpu)) {
+ apic_set_eoi(apic);
+ } else {
+ vapic = kmap_atomic(vcpu->arch.apic->vapic_page);
+ data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr));
+ kunmap_atomic(vapic);
- apic_set_tpr(vcpu->arch.apic, data & 0xff);
+ apic_set_tpr(vcpu->arch.apic, data & 0xff);
+ }
}
void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu)
@@ -1469,13 +1459,10 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
int kvm_pv_enable_apic_eoi(struct kvm_vcpu *vcpu, u64 data)
{
- if (data == MSR_KVM_EOI_DISABLED) {
- struct kvm_lapic *apic = vcpu->arch.apic;
- if (apic && apic_enabled(apic))
- apic_update_isr(apic);
- } else if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.eoi.data,
- data))
- return 1;
+ if (data != MSR_KVM_EOI_DISABLED)
+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.eoi.data,
+ data))
+ return 1;
vcpu->arch.eoi.msr_val = data;
vcpu->arch.eoi.pending = false;
--
Gleb.
next prev parent reply other threads:[~2012-04-16 15:10 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-10 13:27 [PATCHv0 dont apply] RFC: kvm eoi PV using shared memory Michael S. Tsirkin
2012-04-10 14:03 ` Avi Kivity
2012-04-10 14:26 ` Michael S. Tsirkin
2012-04-10 14:33 ` Avi Kivity
2012-04-10 14:53 ` Michael S. Tsirkin
2012-04-10 15:00 ` Avi Kivity
2012-04-10 15:14 ` Michael S. Tsirkin
2012-04-10 16:08 ` Avi Kivity
2012-04-10 17:06 ` Michael S. Tsirkin
2012-04-10 17:59 ` Gleb Natapov
2012-04-10 19:30 ` Michael S. Tsirkin
2012-04-10 19:33 ` Gleb Natapov
2012-04-10 19:40 ` Michael S. Tsirkin
2012-04-10 19:42 ` Gleb Natapov
2012-04-15 16:18 ` [PATCHv1 " Michael S. Tsirkin
2012-04-16 10:08 ` Gleb Natapov
2012-04-16 11:09 ` Michael S. Tsirkin
2012-04-16 11:24 ` Gleb Natapov
2012-04-16 12:18 ` Michael S. Tsirkin
2012-04-16 12:30 ` Gleb Natapov
2012-04-16 13:13 ` Michael S. Tsirkin
2012-04-16 15:10 ` Gleb Natapov [this message]
2012-04-16 16:33 ` Michael S. Tsirkin
2012-04-16 17:51 ` Gleb Natapov
2012-04-16 19:01 ` Michael S. Tsirkin
2012-04-17 8:45 ` Gleb Natapov
2012-04-16 17:24 ` Michael S. Tsirkin
2012-04-16 17:37 ` Gleb Natapov
2012-04-16 18:56 ` Michael S. Tsirkin
2012-04-17 8:59 ` Gleb Natapov
2012-04-17 9:24 ` Avi Kivity
2012-04-17 9:22 ` Avi Kivity
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=20120416151011.GB18613@redhat.com \
--to=gleb@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=mst@redhat.com \
/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 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.