From: Avi Kivity <avi@qumranet.com>
To: Laurent Vivier <Laurent.Vivier@bull.net>
Cc: kvm-devel@lists.sourceforge.net
Subject: Re: [PATCH 1/2] kvm: Batch writes to MMIO
Date: Wed, 23 Apr 2008 17:31:02 +0300 [thread overview]
Message-ID: <480F4826.5010301@qumranet.com> (raw)
In-Reply-To: <12089560581424-git-send-email-Laurent.Vivier@bull.net>
Laurent Vivier wrote:
> This patch is the kernel part of the "batch writes to MMIO" patch.
>
> When kernel has to send MMIO writes to userspace, it stores them
> in memory until it has to pass the hand to userspace for another
> reason. This avoids to have too many context switches on operations
> that can wait.
>
> WARNING: this breaks compatibility with old userspace part.
>
> Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> ---
> arch/x86/kvm/x86.c | 21 +++++++++++++++++++++
> include/asm-x86/kvm_host.h | 2 ++
> include/linux/kvm.h | 10 +++++++++-
> virt/kvm/kvm_main.c | 3 +++
> 4 files changed, 35 insertions(+), 1 deletions(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 0ce5563..3881056 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2942,8 +2942,21 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
> kvm_x86_ops->decache_regs(vcpu);
> }
>
> +batch:
> r = __vcpu_run(vcpu, kvm_run);
>
> + if (!r && vcpu->mmio_is_write &&
> + kvm_run->exit_reason == KVM_EXIT_MMIO &&
> + kvm_run->batch_count < KVM_MAX_BATCH) {
> + struct kvm_batch *batch = vcpu->arch.batch_data;
> + int i = kvm_run->batch_count++;
> +
> + batch[i].phys_addr = vcpu->mmio_phys_addr;
> + batch[i].len = vcpu->mmio_size;
> + memcpy(batch[i].data, vcpu->mmio_data, batch[i].len);
>
This breaks ordering on smp guests. batch_data needs to be a kvm thing,
not a vcpu thing, and locked, of course.
Also, you don't want to queue writes which trigger I/O since that will
affect latency. Userspace should tell the kernel which mmio addresses
are queuable.
> +
> + goto batch;
>
If you move this to within __vcpu_run, you won't need to loop. Maybe
the best place is where we actually decide it's an mmio write.
You also need to flush the queue each time you have an in-kernel mmio
write. For example:
vcpu0 vcpu1
mmio write (queued)
apic write -> IPI
doesn't see effects of write
> + }
> out:
> if (vcpu->sigset_active)
> sigprocmask(SIG_SETMASK, &sigsaved, NULL);
> @@ -3830,6 +3843,13 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
> }
> vcpu->arch.pio_data = page_address(page);
>
> + page = alloc_page(GFP_KERNEL | __GFP_ZERO);
> + if (!page) {
> + r = -ENOMEM;
> + goto fail;
> + }
> + vcpu->arch.batch_data = page_address(page);
> +
> r = kvm_mmu_create(vcpu);
> if (r < 0)
> goto fail_free_pio_data;
> @@ -3857,6 +3877,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
> kvm_mmu_destroy(vcpu);
> up_read(&vcpu->kvm->slots_lock);
> free_page((unsigned long)vcpu->arch.pio_data);
> + free_page((unsigned long)vcpu->arch.batch_data);
> }
>
> #define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
> #define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD))
> @@ -255,6 +256,7 @@ struct kvm_vcpu_arch {
> gva_t mmio_fault_cr2;
> struct kvm_pio_request pio;
> void *pio_data;
> + void *batch_data;
>
>
It's an array of structs, no? So it shouldn't be a void *.
>
> +#define KVM_MAX_BATCH (PAGE_SIZE / sizeof(struct kvm_batch))
> +struct kvm_batch {
> + __u64 phys_addr;
> + __u32 len;
> + __u8 data[8];
> +};
>
Size is 24 on 64-bit and 20 on 32-bit. Please pad (after len, so data
is nicely aligned).
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
next prev parent reply other threads:[~2008-04-23 14:31 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-23 13:07 [PATCH 0/2] Batch writes to MMIO Laurent Vivier
2008-04-23 13:07 ` [PATCH 1/2] kvm: " Laurent Vivier
2008-04-23 13:07 ` [PATCH 2/2] kvm-userspace: " Laurent Vivier
2008-04-23 14:31 ` Avi Kivity [this message]
2008-04-23 14:59 ` [PATCH 1/2] kvm: " Laurent Vivier
2008-04-23 15:04 ` Avi Kivity
2008-04-23 16:53 ` Anthony Liguori
2008-04-23 14:05 ` [PATCH 0/2] " Avi Kivity
2008-04-23 14:22 ` Laurent Vivier
2008-04-23 14:40 ` Avi Kivity
2008-04-23 15:10 ` Anthony Liguori
2008-04-23 15:12 ` Avi Kivity
2008-04-23 15:47 ` Anthony Liguori
2008-04-23 17:13 ` Avi Kivity
2008-04-23 16:24 ` Laurent Vivier
2008-04-23 16:25 ` Avi Kivity
2008-04-23 16:41 ` Laurent Vivier
2008-04-23 16:48 ` Anthony Liguori
2008-04-23 16:51 ` Avi Kivity
2008-04-23 18:54 ` Laurent Vivier
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=480F4826.5010301@qumranet.com \
--to=avi@qumranet.com \
--cc=Laurent.Vivier@bull.net \
--cc=kvm-devel@lists.sourceforge.net \
/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