[Qemu-devel] [PATCH v3 2/3] ivshmem: add a new PIO BAR4(Doorbell) to reduce notification time

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hongyong Zang <zanghongyong@xxxxxxxxxx>

This patch adds a PIO BAR4 for guest notifying qemu to reduce notification time.
And the new notification way of PIO BAR4 reduces 30% time in comparison with the
original MMIO BAR0 way.

Also, this patch introduces a new feature named IVSHMEM_PIO_NOTIFY to make PIO
BAR4 disappeared for compatible with machine type pc-1.0 or blow.

Signed-off-by: Hongyong Zang <zanghongyong@xxxxxxxxxx>
---
 hw/ivshmem.c |   34 ++++++++++++++++++++++++++++++++--
 hw/pc_piix.c |   28 ++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 80b5db0..6845ade 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -26,11 +26,13 @@
 
 #define IVSHMEM_IOEVENTFD   0
 #define IVSHMEM_MSI     1
+#define IVSHMEM_PIO_NOTIFY 2
 
 #define IVSHMEM_PEER    0
 #define IVSHMEM_MASTER  1
 
 #define IVSHMEM_REG_BAR_SIZE 0x100
+#define IVSHIO_REG_BAR_SIZE 0x10
 
 //#define DEBUG_IVSHMEM
 #ifdef DEBUG_IVSHMEM
@@ -59,6 +61,7 @@ typedef struct IVShmemState {
     CharDriverState **eventfd_chr;
     CharDriverState *server_chr;
     MemoryRegion ivshmem_mmio;
+    MemoryRegion ivshmem_pio;
 
     /* We might need to register the BAR before we actually have the memory.
      * So prepare a container MemoryRegion for the BAR immediately and
@@ -237,7 +240,7 @@ static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr,
     return ret;
 }
 
-static const MemoryRegionOps ivshmem_mmio_ops = {
+static const MemoryRegionOps ivshmem_io_ops = {
     .read = ivshmem_io_read,
     .write = ivshmem_io_write,
     .endianness = DEVICE_NATIVE_ENDIAN,
@@ -356,6 +359,14 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
                                      true,
                                      (posn << 16) | i,
                                      s->peers[posn].eventfds[i]);
+            if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+                memory_region_del_eventfd(&s->ivshmem_pio,
+                                         DOORBELL,
+                                         4,
+                                         true,
+                                         (posn << 16) | i,
+                                         s->peers[posn].eventfds[i]);
+            }
         }
         close(s->peers[posn].eventfds[i]);
     }
@@ -490,6 +501,14 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
                                   true,
                                   (incoming_posn << 16) | guest_max_eventfd,
                                   incoming_fd);
+        if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+            memory_region_add_eventfd(&s->ivshmem_pio,
+                                      DOORBELL,
+                                      4,
+                                      true,
+                                      (incoming_posn << 16) | guest_max_eventfd,
+                                      incoming_fd);
+        }
     }
 
     return;
@@ -652,13 +671,20 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     s->shm_fd = 0;
 
-    memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
+    memory_region_init_io(&s->ivshmem_mmio, &ivshmem_io_ops, s,
                           "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
 
     /* region for registers*/
     pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
                      &s->ivshmem_mmio);
 
+    if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+        memory_region_init_io(&s->ivshmem_pio, &ivshmem_io_ops, s,
+                          "ivshmem-pio", IVSHIO_REG_BAR_SIZE);
+        pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
+                     &s->ivshmem_pio);
+    }
+
     memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
 
     if ((s->server_chr != NULL) &&
@@ -738,6 +764,9 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
         error_free(s->migration_blocker);
     }
 
+    if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+        memory_region_destroy(&s->ivshmem_pio);
+    }
     memory_region_destroy(&s->ivshmem_mmio);
     memory_region_del_subregion(&s->bar, &s->ivshmem);
     memory_region_destroy(&s->ivshmem);
@@ -762,6 +791,7 @@ static PCIDeviceInfo ivshmem_info = {
         DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1),
         DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, false),
         DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
+        DEFINE_PROP_BIT("pio_notify", IVShmemState, features, IVSHMEM_PIO_NOTIFY, true),
         DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
         DEFINE_PROP_STRING("role", IVShmemState, role),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 970f43c..fe64874 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -304,6 +304,14 @@ static QEMUMachine pc_machine_v1_0 = {
     .init = pc_init_pci,
     .max_cpus = 255,
     .is_default = 1,
+    .compat_props = (GlobalProperty[]) {
+        {
+            .driver   = "ivshmem",
+            .property = "pio_notify",
+            .value    = "off",
+        },
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine pc_machine_v0_14 = {
@@ -320,6 +328,10 @@ static QEMUMachine pc_machine_v0_14 = {
             .driver   = "qxl-vga",
             .property = "revision",
             .value    = stringify(2),
+        },{
+            .driver   = "ivshmem",
+            .property = "pio_notify",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -363,6 +375,10 @@ static QEMUMachine pc_machine_v0_13 = {
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
+        },{
+            .driver   = "ivshmem",
+            .property = "pio_notify",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -410,6 +426,10 @@ static QEMUMachine pc_machine_v0_12 = {
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
+        },{
+            .driver   = "ivshmem",
+            .property = "pio_notify",
+            .value    = "off",
         },
         { /* end of list */ }
     }
@@ -465,6 +485,10 @@ static QEMUMachine pc_machine_v0_11 = {
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
+        },{
+            .driver   = "ivshmem",
+            .property = "pio_notify",
+            .value    = "off",
         },
         { /* end of list */ }
     }
@@ -532,6 +556,10 @@ static QEMUMachine pc_machine_v0_10 = {
             .driver   = "AC97",
             .property = "use_broken_id",
             .value    = stringify(1),
+        },{
+            .driver   = "ivshmem",
+            .property = "pio_notify",
+            .value    = "off",
         },
         { /* end of list */ }
     },
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux