* [PATCH 0/7] kvm-userspace: Batch writes to MMIO
@ 2008-05-23 8:50 Laurent Vivier
2008-05-23 8:50 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Laurent Vivier
0 siblings, 1 reply; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
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.
WITHOUT WITH
PATCH PATCH
iperf (e1000) 169 MB/s 185,5 MB/s +9,7%
host_state_reload (626594) (391825) -37%
[9,7% is a more realistic value than my previous benchmark]
boot XP
host_state_reload 764677 516059 -32%
VGA text scroll
host_state_reload 13280568 (6:15) 3608362 (4:42) -73% (-25%)
This is the userspace part of the MMIO batching functionality.
[PATCH 1/7] libkvm: delayed MMIO support (common part)
This patch introduces in libkvm the common part of MMIO batching
interface.
[PATCH 2/7] libkvm: delayed MMIO support (x86 part)
This patch enables MMIO batching for x86 architecture.
[PATCH 3/7] libkvm: delayed MMIO support (powerpc part)
This patch enables MMIO batching for powerpc architecture.
WARNING: this has not been tested.
[PATCH 4/7] libkvm: delayed MMIO support (ia64 part)
This patch enables MMIO batching for ia64 architecture.
WARNING: this has not been tested.
[PATCH 5/7] qemu: delayed MMIO support (core)
This patch introduces in qemu the MMIO batching.
[PATCH 6/7] qemu: delayed MMIO support (VGA)
This patch defines delayed MMIO zones for VGA cards.
[PATCH 7/7] qemu: delayed MMIO support (e1000)
This patch defines delayed MMIO zones for e1000 ethernet card.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/7] libkvm: delayed MMIO support (common part)
2008-05-23 8:50 [PATCH 0/7] kvm-userspace: Batch writes to MMIO Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-23 8:50 ` [PATCH 2/7] libkvm: delayed MMIO support (x86 part) Laurent Vivier
2008-05-26 13:55 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Avi Kivity
0 siblings, 2 replies; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch introduces in libkvm the common part of MMIO batching interface.
It checks the MMIO batching availability with ioctl(KVM_CHECK_EXTENSION).
If KVM_CAP_DELAYED_MMIO is available, it processes the MMIO ring buffer
at the return of ioctl(KVM_RUN).
It defines kvm_register_delayed_mmio() to register a delayed MMIO zone, and
kvm_unregister_delayed_mmio() to unregister it.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
libkvm/kvm-common.h | 2 +
libkvm/libkvm.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
libkvm/libkvm.h | 2 +
3 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/libkvm/kvm-common.h b/libkvm/kvm-common.h
index a3549e2..f975d56 100644
--- a/libkvm/kvm-common.h
+++ b/libkvm/kvm-common.h
@@ -49,6 +49,8 @@ struct kvm_context {
int no_pit_creation;
/// in-kernel pit status
int pit_in_kernel;
+ /// in-kernel delayed mmio
+ int delayed_mmio;
};
void init_slots(void);
diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
index d1e95a4..718f4c6 100644
--- a/libkvm/libkvm.c
+++ b/libkvm/libkvm.c
@@ -879,6 +879,20 @@ again:
post_kvm_run(kvm, vcpu);
+#if defined(KVM_CAP_DELAYED_MMIO)
+ if (kvm->delayed_mmio) {
+ struct kvm_batch *batch = (void *)run +
+ kvm->delayed_mmio * PAGE_SIZE;
+ while (batch->first != batch->last) {
+ kvm->callbacks->mmio_write(kvm->opaque,
+ batch->mmio[batch->first].phys_addr,
+ &batch->mmio[batch->first].data[0],
+ batch->mmio[batch->first].len);
+ batch->first = (batch->first + 1) % KVM_MAX_BATCH;
+ }
+ }
+#endif
+
if (r == -1) {
r = handle_io_window(kvm);
goto more;
@@ -983,3 +997,62 @@ int kvm_pit_in_kernel(kvm_context_t kvm)
{
return kvm->pit_in_kernel;
}
+
+int kvm_init_delayed_mmio(kvm_context_t kvm)
+{
+ int r = 0;
+ kvm->delayed_mmio = 0;
+#ifdef KVM_CAP_DELAYED_MMIO
+ r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_DELAYED_MMIO);
+ if (r > 0) {
+ kvm->delayed_mmio = r;
+ return 0;
+ }
+#endif
+ return r;
+}
+
+int kvm_register_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size)
+{
+#ifdef KVM_CAP_DELAYED_MMIO
+ struct kvm_delayed_mmio_zone zone;
+ int r;
+
+ if (kvm->delayed_mmio) {
+
+ zone.addr = addr;
+ zone.size = size;
+
+ r = ioctl(kvm->vm_fd, KVM_REGISTER_DELAYED_MMIO, &zone);
+ if (r == -1) {
+ perror("kvm_register_delayed_mmio_zone");
+ return -errno;
+ }
+ return 0;
+ }
+#endif
+ return -1;
+}
+
+int kvm_unregister_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size)
+{
+#ifdef KVM_CAP_DELAYED_MMIO
+ struct kvm_delayed_mmio_zone zone;
+ int r;
+
+ if (kvm->delayed_mmio) {
+
+ zone.addr = addr;
+ zone.size = size;
+
+ r = ioctl(kvm->vm_fd, KVM_UNREGISTER_DELAYED_MMIO, &zone);
+ if (r == -1) {
+ perror("kvm_unregister_delayed_mmio_zone");
+ return -errno;
+ }
+ return 0;
+ }
+#endif
+ return -1;
+}
+
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index 63183b8..dfb615a 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -457,6 +457,8 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
unsigned long end_addr, void *buf, void*opaque,
int (*cb)(unsigned long start, unsigned long len,
void*bitmap, void *opaque));
+int kvm_register_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size);
+int kvm_unregister_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size);
/*!
* \brief Create a memory alias
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/7] libkvm: delayed MMIO support (x86 part)
2008-05-23 8:50 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-23 8:50 ` [PATCH 3/7] libkvm: delayed MMIO support (powerpc part) Laurent Vivier
2008-05-26 13:55 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Avi Kivity
1 sibling, 1 reply; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch enables MMIO batching for x86 architecture.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
libkvm/libkvm-x86.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
index d46fdcc..6762b91 100644
--- a/libkvm/libkvm-x86.c
+++ b/libkvm/libkvm-x86.c
@@ -179,6 +179,10 @@ int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
if (r < 0)
return r;
+ r = kvm_init_delayed_mmio(kvm);
+ if (r < 0)
+ return r;
+
return 0;
}
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/7] libkvm: delayed MMIO support (powerpc part)
2008-05-23 8:50 ` [PATCH 2/7] libkvm: delayed MMIO support (x86 part) Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-23 8:50 ` [PATCH 4/7] libkvm: delayed MMIO support (ia64 part) Laurent Vivier
0 siblings, 1 reply; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch enables MMIO batching for powerpc architecture.
WARNING: this has not been tested.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
libkvm/libkvm-powerpc.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/libkvm/libkvm-powerpc.c b/libkvm/libkvm-powerpc.c
index 53a2478..0f342d7 100644
--- a/libkvm/libkvm-powerpc.c
+++ b/libkvm/libkvm-powerpc.c
@@ -93,6 +93,12 @@ void kvm_show_regs(kvm_context_t kvm, int vcpu)
int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
void **vm_mem)
{
+ int r;
+
+ r = kvm_init_delayed_mmio(kvm);
+ if (r < 0)
+ return r;
+
return 0;
}
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/7] libkvm: delayed MMIO support (ia64 part)
2008-05-23 8:50 ` [PATCH 3/7] libkvm: delayed MMIO support (powerpc part) Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-23 8:50 ` [PATCH 5/7] qemu: delayed MMIO support (core) Laurent Vivier
0 siblings, 1 reply; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch enables MMIO batching for ia64 architecture.
WARNING: this has not been tested.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
libkvm/libkvm-ia64.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/libkvm/libkvm-ia64.c b/libkvm/libkvm-ia64.c
index d7477d0..b9ea600 100644
--- a/libkvm/libkvm-ia64.c
+++ b/libkvm/libkvm-ia64.c
@@ -67,6 +67,12 @@ void *kvm_create_kernel_phys_mem(kvm_context_t kvm, unsigned long phys_start,
int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
void **vm_mem)
{
+ int r;
+
+ r = kvm_init_delayed_mmio(kvm);
+ if (r < 0)
+ return r;
+
return 0;
}
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/7] qemu: delayed MMIO support (core)
2008-05-23 8:50 ` [PATCH 4/7] libkvm: delayed MMIO support (ia64 part) Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-23 8:50 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Laurent Vivier
0 siblings, 1 reply; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch introduces in qemu the MMIO batching.
It defines qemu_kvm_register_delayed_mmio() and
qemu_kvm_unregister_delayed_mmio() to register and unregister delayed MMIO
zone.
It calls qemu_kvm_unregister_delayed_mmio() on pci_update_mappings().
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
qemu/hw/pci.c | 4 ++++
qemu/qemu-kvm.c | 10 ++++++++++
qemu/qemu-kvm.h | 2 ++
3 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index a23a466..70809fb 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -26,6 +26,7 @@
#include "console.h"
#include "net.h"
#include "pc.h"
+#include "qemu-kvm.h"
//#define DEBUG_PCI
@@ -323,6 +324,9 @@ static void pci_update_mappings(PCIDevice *d)
cpu_register_physical_memory(pci_to_cpu_addr(r->addr),
r->size,
IO_MEM_UNASSIGNED);
+ if (kvm_enabled())
+ qemu_kvm_unregister_delayed_mmio(r->addr,
+ r->size);
}
}
r->addr = new_addr;
diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
index 02776bc..484a713 100644
--- a/qemu/qemu-kvm.c
+++ b/qemu/qemu-kvm.c
@@ -928,3 +928,13 @@ void kvm_mutex_lock(void)
pthread_mutex_lock(&qemu_mutex);
cpu_single_env = NULL;
}
+
+int qemu_kvm_register_delayed_mmio(target_phys_addr_t addr, unsigned int size)
+{
+ return kvm_register_delayed_mmio(kvm_context, addr, size);
+}
+
+int qemu_kvm_unregister_delayed_mmio(target_phys_addr_t addr, unsigned int size)
+{
+ return kvm_unregister_delayed_mmio(kvm_context, addr, size);
+}
diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
index 7412e20..a69142c 100644
--- a/qemu/qemu-kvm.h
+++ b/qemu/qemu-kvm.h
@@ -76,6 +76,8 @@ int handle_tpr_access(void *opaque, int vcpu,
void kvm_tpr_vcpu_start(CPUState *env);
int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf);
+int qemu_kvm_register_delayed_mmio(target_phys_addr_t addr, unsigned int size);
+int qemu_kvm_unregister_delayed_mmio(target_phys_addr_t addr, unsigned int size);
void qemu_kvm_system_reset_request(void);
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/7] qemu: delayed MMIO support (VGA)
2008-05-23 8:50 ` [PATCH 5/7] qemu: delayed MMIO support (core) Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-23 8:50 ` [PATCH 7/7] qemu: delayed MMIO support (e1000) Laurent Vivier
2008-05-26 13:58 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Avi Kivity
0 siblings, 2 replies; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch defines delayed MMIO zones for VGA cards.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
qemu/hw/cirrus_vga.c | 2 ++
qemu/hw/vga.c | 4 ++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c
index 2c4aeec..9eb6929 100644
--- a/qemu/hw/cirrus_vga.c
+++ b/qemu/hw/cirrus_vga.c
@@ -3291,6 +3291,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
cirrus_vga_mem_write, s);
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
vga_io_memory);
+ if (kvm_enabled())
+ qemu_kvm_register_delayed_mmio(isa_mem_base + 0x000a0000, 0x20000);
s->sr[0x06] = 0x0f;
if (device_id == CIRRUS_ID_CLGD5446) {
diff --git a/qemu/hw/vga.c b/qemu/hw/vga.c
index 3a49573..69afbd9 100644
--- a/qemu/hw/vga.c
+++ b/qemu/hw/vga.c
@@ -2257,6 +2257,8 @@ void vga_init(VGAState *s)
vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
vga_io_memory);
+ if (kvm_enabled())
+ qemu_kvm_register_delayed_mmio(isa_mem_base + 0x000a0000, 0x20000);
}
/* Memory mapped interface */
@@ -2332,6 +2334,8 @@ static void vga_mm_init(VGAState *s, target_phys_addr_t vram_base,
cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
s->bank_offset = 0;
cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
+ if (kvm_enabled())
+ qemu_kvm_register_delayed_mmio(vram_base + 0x000a0000, 0x20000);
}
int isa_vga_init(DisplayState *ds, uint8_t *vga_ram_base,
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/7] qemu: delayed MMIO support (e1000)
2008-05-23 8:50 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Laurent Vivier
@ 2008-05-23 8:50 ` Laurent Vivier
2008-05-26 14:05 ` Avi Kivity
2008-05-26 13:58 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Avi Kivity
1 sibling, 1 reply; 13+ messages in thread
From: Laurent Vivier @ 2008-05-23 8:50 UTC (permalink / raw)
To: kvm; +Cc: Laurent Vivier
This patch defines delayed MMIO zones for e1000 ethernet card.
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
qemu/hw/e1000.c | 17 +++++++++++++++++
1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c
index 01f8983..97f46f6 100644
--- a/qemu/hw/e1000.c
+++ b/qemu/hw/e1000.c
@@ -26,6 +26,7 @@
#include "hw.h"
#include "pci.h"
#include "net.h"
+#include "qemu-kvm.h"
#include "e1000_hw.h"
@@ -938,6 +939,22 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
d->mmio_base = addr;
cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
+
+ if (kvm_enabled()) {
+ /* delayed zones are:
+ * 0x00000 -> 0x000C0 exclude: E1000_ICR,4
+ * 0x000C4 -> 0x00400 exclude: E1000_TCTL,4
+ * 0x00404 -> 0x03818 exclude: E1000_TDT,4
+ * 0x0381C -> 0x20000 PNPMMIO_SIZE
+ */
+ qemu_kvm_register_delayed_mmio(addr, E1000_ICR);
+ qemu_kvm_register_delayed_mmio(addr + E1000_ICR + 4,
+ E1000_TCTL - (E1000_ICR + 4));
+ qemu_kvm_register_delayed_mmio(addr + E1000_TCTL + 4,
+ E1000_TDT - (E1000_TCTL + 4));
+ qemu_kvm_register_delayed_mmio(addr + E1000_TDT + 4,
+ PNPMMIO_SIZE - (E1000_TDT + 4));
+ }
}
static int
--
1.5.2.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/7] libkvm: delayed MMIO support (common part)
2008-05-23 8:50 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Laurent Vivier
2008-05-23 8:50 ` [PATCH 2/7] libkvm: delayed MMIO support (x86 part) Laurent Vivier
@ 2008-05-26 13:55 ` Avi Kivity
2008-05-26 14:15 ` Laurent Vivier
1 sibling, 1 reply; 13+ messages in thread
From: Avi Kivity @ 2008-05-26 13:55 UTC (permalink / raw)
To: Laurent Vivier; +Cc: kvm
Laurent Vivier wrote:
> This patch introduces in libkvm the common part of MMIO batching interface.
>
> It checks the MMIO batching availability with ioctl(KVM_CHECK_EXTENSION).
> If KVM_CAP_DELAYED_MMIO is available, it processes the MMIO ring buffer
> at the return of ioctl(KVM_RUN).
> It defines kvm_register_delayed_mmio() to register a delayed MMIO zone, and
> kvm_unregister_delayed_mmio() to unregister it.
>
>
> void init_slots(void);
> diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
> index d1e95a4..718f4c6 100644
> --- a/libkvm/libkvm.c
> +++ b/libkvm/libkvm.c
> @@ -879,6 +879,20 @@ again:
>
> post_kvm_run(kvm, vcpu);
>
> +#if defined(KVM_CAP_DELAYED_MMIO)
> + if (kvm->delayed_mmio) {
> + struct kvm_batch *batch = (void *)run +
> + kvm->delayed_mmio * PAGE_SIZE;
> + while (batch->first != batch->last) {
> + kvm->callbacks->mmio_write(kvm->opaque,
> + batch->mmio[batch->first].phys_addr,
> + &batch->mmio[batch->first].data[0],
> + batch->mmio[batch->first].len);
> + batch->first = (batch->first + 1) % KVM_MAX_BATCH;
>
There needs to be a write barrier after this (smp_wmb()), to avoid
compiler and cpu reordering. Especially important for non-x86. Also
need a read barrier before reading batch->first.
Or maybe not, likely the pthread_mutex_lock() acts as the correct
barrier. But we do need the equivalent barriers in the kernel code
(missed it on that review).
> + }
> + }
> +#endif
> +
> if (r == -1) {
> r = handle_io_window(kvm);
> goto more;
>
> +
> +int kvm_register_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size)
> +{
> +#ifdef KVM_CAP_DELAYED_MMIO
> + struct kvm_delayed_mmio_zone zone;
> + int r;
> +
> + if (kvm->delayed_mmio) {
> +
> + zone.addr = addr;
> + zone.size = size;
> +
> + r = ioctl(kvm->vm_fd, KVM_REGISTER_DELAYED_MMIO, &zone);
> + if (r == -1) {
> + perror("kvm_register_delayed_mmio_zone");
> + return -errno;
> + }
> + return 0;
> + }
> +#endif
> + return -1;
>
-ENOSYS, or something. -1 is -ENOPERM.
> +}
> +
> +int kvm_unregister_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size)
> +{
> +#ifdef KVM_CAP_DELAYED_MMIO
> + struct kvm_delayed_mmio_zone zone;
> + int r;
> +
> + if (kvm->delayed_mmio) {
> +
> + zone.addr = addr;
> + zone.size = size;
> +
> + r = ioctl(kvm->vm_fd, KVM_UNREGISTER_DELAYED_MMIO, &zone);
> + if (r == -1) {
> + perror("kvm_unregister_delayed_mmio_zone");
> + return -errno;
> + }
> + return 0;
> + }
> +#endif
> + return -1;
>
ditto.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 6/7] qemu: delayed MMIO support (VGA)
2008-05-23 8:50 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Laurent Vivier
2008-05-23 8:50 ` [PATCH 7/7] qemu: delayed MMIO support (e1000) Laurent Vivier
@ 2008-05-26 13:58 ` Avi Kivity
1 sibling, 0 replies; 13+ messages in thread
From: Avi Kivity @ 2008-05-26 13:58 UTC (permalink / raw)
To: Laurent Vivier; +Cc: kvm
Laurent Vivier wrote:
> This patch defines delayed MMIO zones for VGA cards.
>
> Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> ---
> qemu/hw/cirrus_vga.c | 2 ++
> qemu/hw/vga.c | 4 ++++
> 2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c
> index 2c4aeec..9eb6929 100644
> --- a/qemu/hw/cirrus_vga.c
> +++ b/qemu/hw/cirrus_vga.c
> @@ -3291,6 +3291,8 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
> cirrus_vga_mem_write, s);
> cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
> vga_io_memory);
> + if (kvm_enabled())
> + qemu_kvm_register_delayed_mmio(isa_mem_base + 0x000a0000, 0x20000);
>
>
Cirrus has some mmio registers that cause actions (bitblt), which could
be mapped at this address. But I guess that since all the actions are
synchronous anyway, no harm is done in delaying them.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] qemu: delayed MMIO support (e1000)
2008-05-23 8:50 ` [PATCH 7/7] qemu: delayed MMIO support (e1000) Laurent Vivier
@ 2008-05-26 14:05 ` Avi Kivity
2008-05-26 14:27 ` Laurent Vivier
0 siblings, 1 reply; 13+ messages in thread
From: Avi Kivity @ 2008-05-26 14:05 UTC (permalink / raw)
To: Laurent Vivier; +Cc: kvm
Laurent Vivier wrote:
> This patch defines delayed MMIO zones for e1000 ethernet card.
>
> Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> ---
> qemu/hw/e1000.c | 17 +++++++++++++++++
> 1 files changed, 17 insertions(+), 0 deletions(-)
>
> diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c
> index 01f8983..97f46f6 100644
> --- a/qemu/hw/e1000.c
> +++ b/qemu/hw/e1000.c
> @@ -26,6 +26,7 @@
> #include "hw.h"
> #include "pci.h"
> #include "net.h"
> +#include "qemu-kvm.h"
>
> #include "e1000_hw.h"
>
> @@ -938,6 +939,22 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
>
> d->mmio_base = addr;
> cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
> +
> + if (kvm_enabled()) {
> + /* delayed zones are:
> + * 0x00000 -> 0x000C0 exclude: E1000_ICR,4
> + * 0x000C4 -> 0x00400 exclude: E1000_TCTL,4
> + * 0x00404 -> 0x03818 exclude: E1000_TDT,4
> + * 0x0381C -> 0x20000 PNPMMIO_SIZE
> + */
> + qemu_kvm_register_delayed_mmio(addr, E1000_ICR);
> + qemu_kvm_register_delayed_mmio(addr + E1000_ICR + 4,
> + E1000_TCTL - (E1000_ICR + 4));
> + qemu_kvm_register_delayed_mmio(addr + E1000_TCTL + 4,
> + E1000_TDT - (E1000_TCTL + 4));
> + qemu_kvm_register_delayed_mmio(addr + E1000_TDT + 4,
> + PNPMMIO_SIZE - (E1000_TDT + 4));
> + }
> }
>
What about the calls to set_ics()? They can cause interrupts to be
deasserted AFAICS. So IMC (and maybe a few other registers) need to be
excluded as well.
Instead of hardcoding this, how about a
uint32_t delayed_mmi_excluded_regs[] = {
E1000_ICR, E1000_TCTL, ...
};
The code can sort them and generate the ranges automatically.
(alternatively, a boolmap:
bool delayed_mmi_excluded_regs[] = {
[E1000_ICR]: true, ...
};
)
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/7] libkvm: delayed MMIO support (common part)
2008-05-26 13:55 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Avi Kivity
@ 2008-05-26 14:15 ` Laurent Vivier
0 siblings, 0 replies; 13+ messages in thread
From: Laurent Vivier @ 2008-05-26 14:15 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
Le lundi 26 mai 2008 à 16:55 +0300, Avi Kivity a écrit :
> Laurent Vivier wrote:
> > This patch introduces in libkvm the common part of MMIO batching interface.
> >
> > It checks the MMIO batching availability with ioctl(KVM_CHECK_EXTENSION).
> > If KVM_CAP_DELAYED_MMIO is available, it processes the MMIO ring buffer
> > at the return of ioctl(KVM_RUN).
> > It defines kvm_register_delayed_mmio() to register a delayed MMIO zone, and
> > kvm_unregister_delayed_mmio() to unregister it.
> >
> >
> > void init_slots(void);
> > diff --git a/libkvm/libkvm.c b/libkvm/libkvm.c
> > index d1e95a4..718f4c6 100644
> > --- a/libkvm/libkvm.c
> > +++ b/libkvm/libkvm.c
> > @@ -879,6 +879,20 @@ again:
> >
> > post_kvm_run(kvm, vcpu);
> >
> > +#if defined(KVM_CAP_DELAYED_MMIO)
> > + if (kvm->delayed_mmio) {
> > + struct kvm_batch *batch = (void *)run +
> > + kvm->delayed_mmio * PAGE_SIZE;
> > + while (batch->first != batch->last) {
> > + kvm->callbacks->mmio_write(kvm->opaque,
> > + batch->mmio[batch->first].phys_addr,
> > + &batch->mmio[batch->first].data[0],
> > + batch->mmio[batch->first].len);
> > + batch->first = (batch->first + 1) % KVM_MAX_BATCH;
> >
>
> There needs to be a write barrier after this (smp_wmb()), to avoid
> compiler and cpu reordering. Especially important for non-x86. Also
> need a read barrier before reading batch->first.
>
> Or maybe not, likely the pthread_mutex_lock() acts as the correct
> barrier. But we do need the equivalent barriers in the kernel code
> (missed it on that review).
OK
> > + }
> > + }
> > +#endif
> > +
> > if (r == -1) {
> > r = handle_io_window(kvm);
> > goto more;
> >
>
> > +
> > +int kvm_register_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size)
> > +{
> > +#ifdef KVM_CAP_DELAYED_MMIO
> > + struct kvm_delayed_mmio_zone zone;
> > + int r;
> > +
> > + if (kvm->delayed_mmio) {
> > +
> > + zone.addr = addr;
> > + zone.size = size;
> > +
> > + r = ioctl(kvm->vm_fd, KVM_REGISTER_DELAYED_MMIO, &zone);
> > + if (r == -1) {
> > + perror("kvm_register_delayed_mmio_zone");
> > + return -errno;
> > + }
> > + return 0;
> > + }
> > +#endif
> > + return -1;
> >
>
> -ENOSYS, or something. -1 is -ENOPERM.
OK
>
> > +}
> > +
> > +int kvm_unregister_delayed_mmio(kvm_context_t kvm, uint64_t addr, uint32_t size)
> > +{
> > +#ifdef KVM_CAP_DELAYED_MMIO
> > + struct kvm_delayed_mmio_zone zone;
> > + int r;
> > +
> > + if (kvm->delayed_mmio) {
> > +
> > + zone.addr = addr;
> > + zone.size = size;
> > +
> > + r = ioctl(kvm->vm_fd, KVM_UNREGISTER_DELAYED_MMIO, &zone);
> > + if (r == -1) {
> > + perror("kvm_unregister_delayed_mmio_zone");
> > + return -errno;
> > + }
> > + return 0;
> > + }
> > +#endif
> > + return -1;
> >
>
> ditto.
OK
--
------------- Laurent.Vivier@bull.net ---------------
"The best way to predict the future is to invent it."
- Alan Kay
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 7/7] qemu: delayed MMIO support (e1000)
2008-05-26 14:05 ` Avi Kivity
@ 2008-05-26 14:27 ` Laurent Vivier
0 siblings, 0 replies; 13+ messages in thread
From: Laurent Vivier @ 2008-05-26 14:27 UTC (permalink / raw)
To: Avi Kivity; +Cc: kvm
Le lundi 26 mai 2008 à 17:05 +0300, Avi Kivity a écrit :
> Laurent Vivier wrote:
> > This patch defines delayed MMIO zones for e1000 ethernet card.
> >
> > Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
> > ---
> > qemu/hw/e1000.c | 17 +++++++++++++++++
> > 1 files changed, 17 insertions(+), 0 deletions(-)
> >
> > diff --git a/qemu/hw/e1000.c b/qemu/hw/e1000.c
> > index 01f8983..97f46f6 100644
> > --- a/qemu/hw/e1000.c
> > +++ b/qemu/hw/e1000.c
> > @@ -26,6 +26,7 @@
> > #include "hw.h"
> > #include "pci.h"
> > #include "net.h"
> > +#include "qemu-kvm.h"
> >
> > #include "e1000_hw.h"
> >
> > @@ -938,6 +939,22 @@ e1000_mmio_map(PCIDevice *pci_dev, int region_num,
> >
> > d->mmio_base = addr;
> > cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
> > +
> > + if (kvm_enabled()) {
> > + /* delayed zones are:
> > + * 0x00000 -> 0x000C0 exclude: E1000_ICR,4
> > + * 0x000C4 -> 0x00400 exclude: E1000_TCTL,4
> > + * 0x00404 -> 0x03818 exclude: E1000_TDT,4
> > + * 0x0381C -> 0x20000 PNPMMIO_SIZE
> > + */
> > + qemu_kvm_register_delayed_mmio(addr, E1000_ICR);
> > + qemu_kvm_register_delayed_mmio(addr + E1000_ICR + 4,
> > + E1000_TCTL - (E1000_ICR + 4));
> > + qemu_kvm_register_delayed_mmio(addr + E1000_TCTL + 4,
> > + E1000_TDT - (E1000_TCTL + 4));
> > + qemu_kvm_register_delayed_mmio(addr + E1000_TDT + 4,
> > + PNPMMIO_SIZE - (E1000_TDT + 4));
> > + }
> > }
> >
>
> What about the calls to set_ics()? They can cause interrupts to be
> deasserted AFAICS. So IMC (and maybe a few other registers) need to be
> excluded as well.
Well, I don't know how I missed them...
> Instead of hardcoding this, how about a
>
> uint32_t delayed_mmi_excluded_regs[] = {
> E1000_ICR, E1000_TCTL, ...
> };
>
> The code can sort them and generate the ranges automatically.
>
> (alternatively, a boolmap:
>
> bool delayed_mmi_excluded_regs[] = {
> [E1000_ICR]: true, ...
> };
> )
I'll try...
Regards,
Laurent
--
------------- Laurent.Vivier@bull.net ---------------
"The best way to predict the future is to invent it."
- Alan Kay
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2008-05-26 14:27 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-05-23 8:50 [PATCH 0/7] kvm-userspace: Batch writes to MMIO Laurent Vivier
2008-05-23 8:50 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Laurent Vivier
2008-05-23 8:50 ` [PATCH 2/7] libkvm: delayed MMIO support (x86 part) Laurent Vivier
2008-05-23 8:50 ` [PATCH 3/7] libkvm: delayed MMIO support (powerpc part) Laurent Vivier
2008-05-23 8:50 ` [PATCH 4/7] libkvm: delayed MMIO support (ia64 part) Laurent Vivier
2008-05-23 8:50 ` [PATCH 5/7] qemu: delayed MMIO support (core) Laurent Vivier
2008-05-23 8:50 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Laurent Vivier
2008-05-23 8:50 ` [PATCH 7/7] qemu: delayed MMIO support (e1000) Laurent Vivier
2008-05-26 14:05 ` Avi Kivity
2008-05-26 14:27 ` Laurent Vivier
2008-05-26 13:58 ` [PATCH 6/7] qemu: delayed MMIO support (VGA) Avi Kivity
2008-05-26 13:55 ` [PATCH 1/7] libkvm: delayed MMIO support (common part) Avi Kivity
2008-05-26 14:15 ` Laurent Vivier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox