qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Alexey Kardashevskiy <aik@ozlabs.ru>
Subject: [Qemu-devel] [PULL 23/26] virtio-pci: Replace modern_as with direct access to modern_bar
Date: Sun, 15 Oct 2017 06:24:00 +0300	[thread overview]
Message-ID: <1508036858-13479-24-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1508036858-13479-1-git-send-email-mst@redhat.com>

From: Alexey Kardashevskiy <aik@ozlabs.ru>

The modern bar is accessed now via yet another address space created just
for that purpose and it does not really need FlatView and dispatch tree
as it has a single memory region so it is just a waste of memory. Things
get even worse when there are dozens or hundreds of virtio-pci devices -
since these address spaces are global, changing any of them triggers
rebuilding all address spaces.

This replaces indirect accesses to the modern BAR with a simple lookup
and direct calls to memory_region_dispatch_read/write.

This is expected to save lots of memory at boot time after applying:
[Qemu-devel] [PULL 00/32] Misc changes for 2017-09-22

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/virtio/virtio-pci.h | 17 +++++++-----
 hw/virtio/virtio-pci.c | 75 +++++++++++++++++++++++++++++---------------------
 2 files changed, 54 insertions(+), 38 deletions(-)

diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 69f5959..12d3a90 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -155,15 +155,18 @@ typedef struct VirtIOPCIQueue {
 struct VirtIOPCIProxy {
     PCIDevice pci_dev;
     MemoryRegion bar;
-    VirtIOPCIRegion common;
-    VirtIOPCIRegion isr;
-    VirtIOPCIRegion device;
-    VirtIOPCIRegion notify;
-    VirtIOPCIRegion notify_pio;
+    union {
+        struct {
+            VirtIOPCIRegion common;
+            VirtIOPCIRegion isr;
+            VirtIOPCIRegion device;
+            VirtIOPCIRegion notify;
+            VirtIOPCIRegion notify_pio;
+        };
+        VirtIOPCIRegion regs[5];
+    };
     MemoryRegion modern_bar;
     MemoryRegion io_bar;
-    MemoryRegion modern_cfg;
-    AddressSpace modern_as;
     uint32_t legacy_io_bar_idx;
     uint32_t msix_bar_idx;
     uint32_t modern_io_bar_idx;
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 6c60aa0..e92837c 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -491,6 +491,24 @@ static const MemoryRegionOps virtio_pci_config_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
+static MemoryRegion *virtio_address_space_lookup(VirtIOPCIProxy *proxy,
+                                                 hwaddr *off, int len)
+{
+    int i;
+    VirtIOPCIRegion *reg;
+
+    for (i = 0; i < ARRAY_SIZE(proxy->regs); ++i) {
+        reg = &proxy->regs[i];
+        if (*off >= reg->offset &&
+            *off + len <= reg->offset + reg->size) {
+            *off -= reg->offset;
+            return &reg->mr;
+        }
+    }
+
+    return NULL;
+}
+
 /* Below are generic functions to do memcpy from/to an address space,
  * without byteswaps, with input validation.
  *
@@ -504,63 +522,72 @@ static const MemoryRegionOps virtio_pci_config_ops = {
  * Note: host pointer must be aligned.
  */
 static
-void virtio_address_space_write(AddressSpace *as, hwaddr addr,
+void virtio_address_space_write(VirtIOPCIProxy *proxy, hwaddr addr,
                                 const uint8_t *buf, int len)
 {
-    uint32_t val;
+    uint64_t val;
+    MemoryRegion *mr;
 
     /* address_space_* APIs assume an aligned address.
      * As address is under guest control, handle illegal values.
      */
     addr &= ~(len - 1);
 
+    mr = virtio_address_space_lookup(proxy, &addr, len);
+    if (!mr) {
+        return;
+    }
+
     /* Make sure caller aligned buf properly */
     assert(!(((uintptr_t)buf) & (len - 1)));
 
     switch (len) {
     case 1:
         val = pci_get_byte(buf);
-        address_space_stb(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
         break;
     case 2:
-        val = pci_get_word(buf);
-        address_space_stw_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
+        val = cpu_to_le16(pci_get_word(buf));
         break;
     case 4:
-        val = pci_get_long(buf);
-        address_space_stl_le(as, addr, val, MEMTXATTRS_UNSPECIFIED, NULL);
+        val = cpu_to_le32(pci_get_long(buf));
         break;
     default:
         /* As length is under guest control, handle illegal values. */
-        break;
+        return;
     }
+    memory_region_dispatch_write(mr, addr, val, len, MEMTXATTRS_UNSPECIFIED);
 }
 
 static void
-virtio_address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len)
+virtio_address_space_read(VirtIOPCIProxy *proxy, hwaddr addr,
+                          uint8_t *buf, int len)
 {
-    uint32_t val;
+    uint64_t val;
+    MemoryRegion *mr;
 
     /* address_space_* APIs assume an aligned address.
      * As address is under guest control, handle illegal values.
      */
     addr &= ~(len - 1);
 
+    mr = virtio_address_space_lookup(proxy, &addr, len);
+    if (!mr) {
+        return;
+    }
+
     /* Make sure caller aligned buf properly */
     assert(!(((uintptr_t)buf) & (len - 1)));
 
+    memory_region_dispatch_read(mr, addr, &val, len, MEMTXATTRS_UNSPECIFIED);
     switch (len) {
     case 1:
-        val = address_space_ldub(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
         pci_set_byte(buf, val);
         break;
     case 2:
-        val = address_space_lduw_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
-        pci_set_word(buf, val);
+        pci_set_word(buf, le16_to_cpu(val));
         break;
     case 4:
-        val = address_space_ldl_le(as, addr, MEMTXATTRS_UNSPECIFIED, NULL);
-        pci_set_long(buf, val);
+        pci_set_long(buf, le32_to_cpu(val));
         break;
     default:
         /* As length is under guest control, handle illegal values. */
@@ -596,8 +623,7 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
 
         if (len == 1 || len == 2 || len == 4) {
             assert(len <= sizeof cfg->pci_cfg_data);
-            virtio_address_space_write(&proxy->modern_as, off,
-                                       cfg->pci_cfg_data, len);
+            virtio_address_space_write(proxy, off, cfg->pci_cfg_data, len);
         }
     }
 }
@@ -621,8 +647,7 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev,
 
         if (len == 1 || len == 2 || len == 4) {
             assert(len <= sizeof cfg->pci_cfg_data);
-            virtio_address_space_read(&proxy->modern_as, off,
-                                      cfg->pci_cfg_data, len);
+            virtio_address_space_read(proxy, off, cfg->pci_cfg_data, len);
         }
     }
 
@@ -1729,15 +1754,6 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
                        /* PCI BAR regions must be powers of 2 */
                        pow2ceil(proxy->notify.offset + proxy->notify.size));
 
-    memory_region_init_alias(&proxy->modern_cfg,
-                             OBJECT(proxy),
-                             "virtio-pci-cfg",
-                             &proxy->modern_bar,
-                             0,
-                             memory_region_size(&proxy->modern_bar));
-
-    address_space_init(&proxy->modern_as, &proxy->modern_cfg, "virtio-pci-cfg-as");
-
     if (proxy->disable_legacy == ON_OFF_AUTO_AUTO) {
         proxy->disable_legacy = pcie_port ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
     }
@@ -1806,10 +1822,7 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
 
 static void virtio_pci_exit(PCIDevice *pci_dev)
 {
-    VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
-
     msix_uninit_exclusive_bar(pci_dev);
-    address_space_destroy(&proxy->modern_as);
 }
 
 static void virtio_pci_reset(DeviceState *qdev)
-- 
MST

  parent reply	other threads:[~2017-10-15  3:24 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-15  3:22 [Qemu-devel] [PULL 00/26] pc, pci, virtio: fixes, features Michael S. Tsirkin
2017-10-15  3:22 ` [Qemu-devel] [PULL 01/26] xio3130_downstream: Report error if pcie_chassis_add_slot() failed Michael S. Tsirkin
2017-10-15  3:22 ` [Qemu-devel] [PULL 02/26] pci: Set err to errp directly rather than through error_propagate() Michael S. Tsirkin
2017-10-15  3:22 ` [Qemu-devel] [PULL 03/26] fw_cfg: add write callback Michael S. Tsirkin
2017-10-15  3:22 ` [Qemu-devel] [PULL 04/26] hw/misc: add vmcoreinfo device Michael S. Tsirkin
2017-10-15  3:22 ` [Qemu-devel] [PULL 05/26] dump: add guest ELF note Michael S. Tsirkin
2017-10-15  3:22 ` [Qemu-devel] [PULL 06/26] dump: update phys_base header field based on VMCOREINFO content Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 07/26] kdump: set vmcoreinfo location Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 08/26] scripts/dump-guest-memory.py: add vmcoreinfo Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 09/26] MAINTAINERS: add Dump maintainers Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 10/26] virtio/vhost: reset dev->log after syncing Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 11/26] pci: allow 32-bit PCI IO accesses to pass through the PCI bridge Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 12/26] hw/pci-bridge/pcie_pci_bridge: properly handle MSI unavailability case Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 13/26] virtio/pci/migration: Convert to VMState Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 14/26] PCI: PCIe access should always be little endian Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 15/26] pci: conventional-pci-device and pci-express-device interfaces Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 16/26] pci: Add interface names to hybrid PCI devices Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 17/26] pci: Add INTERFACE_PCIE_DEVICE to all PCIe devices Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 18/26] pci: Add INTERFACE_CONVENTIONAL_PCI_DEVICE to Conventional PCI devices Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 19/26] xen/pt: Mark TYPE_XEN_PT_DEVICE as hybrid Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 20/26] pci: Validate interfaces on base_class_init Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 21/26] hw/gen_pcie_root_port: make IO RO 0 on IO disabled Michael S. Tsirkin
2017-10-15  3:23 ` [Qemu-devel] [PULL 22/26] virtio: fix descriptor counting in virtqueue_pop Michael S. Tsirkin
2017-10-15  3:24 ` Michael S. Tsirkin [this message]
2017-10-15  3:24 ` [Qemu-devel] [PULL 24/26] isapc: Remove unnecessary migration compatibility code Michael S. Tsirkin
2017-10-15  3:24 ` [Qemu-devel] [PULL 25/26] pc: remove useless hot_add_cpu initialisation Michael S. Tsirkin
2017-10-15  3:24 ` [Qemu-devel] [PULL 26/26] tests/pxe: Test more NICs when running in SPEED=slow mode Michael S. Tsirkin
2017-10-16 17:29 ` [Qemu-devel] [PULL 00/26] pc, pci, virtio: fixes, features Peter Maydell

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=1508036858-13479-24-git-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=aik@ozlabs.ru \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.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;
as well as URLs for NNTP newsgroup(s).