All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 39/45] memory: try to inline constant-length reads
Date: Thu, 17 Dec 2015 18:46:35 +0100	[thread overview]
Message-ID: <1450374401-31352-40-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1450374401-31352-1-git-send-email-pbonzini@redhat.com>

memcpy can take a large amount of time for small reads and writes.
Handle the common case of reading s/g descriptors from memory (there
is no corresponding "write" case that is as common, because writes
often use address_space_st* functions) by inlining the relevant
parts of address_space_read into the caller.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c                  | 15 ++--------
 include/exec/memory.h   | 74 +++++++++++++++++++++++++++++++++++++------------
 include/exec/ram_addr.h |  1 -
 3 files changed, 59 insertions(+), 31 deletions(-)

diff --git a/exec.c b/exec.c
index 1597e8a..8718a75 100644
--- a/exec.c
+++ b/exec.c
@@ -390,17 +390,6 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
     return section;
 }
 
-static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
-{
-    if (is_write) {
-        return memory_region_is_ram(mr) && !mr->readonly;
-    } else {
-        return memory_region_is_ram(mr) || memory_region_is_romd(mr);
-    }
-
-    return false;
-}
-
 /* Called from RCU critical section */
 MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
                                       hwaddr *xlat, hwaddr *plen,
@@ -2632,8 +2621,8 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
     return result;
 }
 
-MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
-                               uint8_t *buf, int len)
+MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+                                    MemTxAttrs attrs, uint8_t *buf, int len)
 {
     hwaddr l;
     hwaddr addr1;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index a0993e5..01f1004 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1234,23 +1234,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
                                 MemTxAttrs attrs,
                                 const uint8_t *buf, int len);
 
-/**
- * address_space_read: read from an address space.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault).
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @attrs: memory transaction attributes
- * @buf: buffer with the data transferred
- */
-MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
-                               uint8_t *buf, int len);
-
-/**
- * address_space_ld*: load from an address space
+/* address_space_ld*: load from an address space
  * address_space_st*: store to an address space
  *
  * These functions perform a load or store of the byte, word,
@@ -1385,6 +1369,62 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
                                         MemTxAttrs attrs, uint8_t *buf,
                                         int len, hwaddr addr1, hwaddr l,
 					MemoryRegion *mr);
+MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+                                    MemTxAttrs attrs, uint8_t *buf, int len);
+void *qemu_get_ram_ptr(ram_addr_t addr);
+
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+{
+    if (is_write) {
+        return memory_region_is_ram(mr) && !mr->readonly;
+    } else {
+        return memory_region_is_ram(mr) || memory_region_is_romd(mr);
+    }
+
+    return false;
+}
+
+/**
+ * address_space_read: read from an address space.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @attrs: memory transaction attributes
+ * @buf: buffer with the data transferred
+ */
+static inline __attribute__((__always_inline__))
+MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+                               uint8_t *buf, int len)
+{
+    MemTxResult result = MEMTX_OK;
+    hwaddr l, addr1;
+    void *ptr;
+    MemoryRegion *mr;
+
+    if (__builtin_constant_p(len)) {
+        if (len) {
+            rcu_read_lock();
+            l = len;
+            mr = address_space_translate(as, addr, &addr1, &l, false);
+            if (len == l && memory_access_is_direct(mr, false)) {
+                addr1 += memory_region_get_ram_addr(mr);
+                ptr = qemu_get_ram_ptr(addr1);
+                memcpy(buf, ptr, len);
+            } else {
+                result = address_space_read_continue(as, addr, attrs, buf, len,
+                                                     addr1, l, mr);
+            }
+            rcu_read_unlock();
+        }
+    } else {
+        result = address_space_read_full(as, addr, attrs, buf, len);
+    }
+    return result;
+}
 
 #endif
 
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index d1d9963..ba4c04d 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -73,7 +73,6 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
                                      MemoryRegion *mr, Error **errp);
 int qemu_get_ram_fd(ram_addr_t addr);
 void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
-void *qemu_get_ram_ptr(ram_addr_t addr);
 void qemu_ram_free(ram_addr_t addr);
 
 int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
-- 
2.5.0

  parent reply	other threads:[~2015-12-17 17:47 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-17 17:45 [Qemu-devel] [PULL 00/45] KVM, memory, SCSI, qemu_log, Coverity patches for 2015-12-17 Paolo Bonzini
2015-12-17 17:45 ` [Qemu-devel] [PULL 01/45] exec: Eliminate qemu_ram_free_from_ptr() Paolo Bonzini
2015-12-17 17:45 ` [Qemu-devel] [PULL 02/45] memory: Eliminate memory_region_destructor_ram_from_ptr() Paolo Bonzini
2015-12-17 17:45 ` [Qemu-devel] [PULL 03/45] exec: Remove unnecessary RAM_FILE flag Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 04/45] kvm-all: PAGE_SIZE should be real host page size Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 05/45] memory: emulate ioeventfd Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 06/45] vmw_pvscsi: Set device subsystem and revision Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 07/45] vmw_pvscsi: Change offset of msi pci capability Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 08/45] vmw_pvscsi: Introduce 'x-old-pci-configuration' backword compatability property Paolo Bonzini
2015-12-17 18:08   ` Eric Blake
2015-12-18  6:21     ` Shmulik Ladkani
2015-12-17 17:46 ` [Qemu-devel] [PULL 09/45] vmw_pvscsi: coding: Introduce PVSCSIClass Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 10/45] vmw_pvscsi: The pvscsi device is a PCIE endpoint Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 11/45] vmw_pvscsi: Introduce 'x-disable-pcie' backword compatability property Paolo Bonzini
2015-12-17 18:09   ` Eric Blake
2015-12-17 17:46 ` [Qemu-devel] [PULL 12/45] linux-headers: update from kvm/next Paolo Bonzini
2015-12-17 17:46 ` [PULL 13/45] target-i386/kvm: Hyper-V SynIC MSR's support Paolo Bonzini
2015-12-17 17:46   ` [Qemu-devel] " Paolo Bonzini
2015-12-17 17:46 ` [PULL 14/45] kvm: Hyper-V SynIC irq routing support Paolo Bonzini
2015-12-17 17:46   ` [Qemu-devel] " Paolo Bonzini
2015-12-17 17:46 ` [PULL 15/45] target-i386/hyperv: Hyper-V SynIC SINT routing and vcpu exit Paolo Bonzini
2015-12-17 17:46   ` [Qemu-devel] " Paolo Bonzini
2015-12-17 17:46 ` [PULL 16/45] hw/misc: Hyper-V test device 'hyperv-testdev' Paolo Bonzini
2015-12-17 17:46   ` [Qemu-devel] " Paolo Bonzini
2015-12-17 17:46 ` [PULL 17/45] target-i386/kvm: Hyper-V SynIC timers MSR's support Paolo Bonzini
2015-12-17 17:46   ` [Qemu-devel] " Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 18/45] kvm: add support for -machine kernel_irqchip=split Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 19/45] kvm: x86: add support for KVM_CAP_SPLIT_IRQCHIP Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 20/45] qemu-char: append opt to stop truncation of serial file Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 21/45] qemu-log: introduce qemu_log_separate Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 22/45] alpha: convert "naked" qemu_log to tracepoint Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 23/45] cris: avoid "naked" qemu_log Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 24/45] microblaze: " Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 25/45] s390x: " Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 26/45] ppc: cleanup logging Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 27/45] tricore: avoid "naked" qemu_log Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 28/45] xtensa: " Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 29/45] user: introduce "-d page" Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 30/45] linux-user: avoid "naked" qemu_log Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 31/45] linux-user: convert DEBUG_SIGNAL logging to tracepoints Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 32/45] exec: always call qemu_get_ram_ptr within rcu_read_lock Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 33/45] exec: make qemu_ram_ptr_length more similar to qemu_get_ram_ptr Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 34/45] memory: reorder MemoryRegion fields Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 35/45] memory: avoid unnecessary object_ref/unref Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 36/45] memory: split address_space_read and address_space_write Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 37/45] memory: extract first iteration of " Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 38/45] memory: inline a few small accessors Paolo Bonzini
2015-12-17 17:46 ` Paolo Bonzini [this message]
2015-12-17 17:46 ` [Qemu-devel] [PULL 40/45] rcu: optimize rcu_read_lock Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 41/45] target-i386: kvm: clear unusable segments' flags in migration Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 42/45] scsi: use scsi_req_cancel_async when purging requests Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 43/45] scsi: always call notifier on async cancellation Paolo Bonzini
2015-12-18  0:57   ` Fam Zheng
2015-12-18  6:05     ` Paolo Bonzini
2015-12-18  7:51       ` Fam Zheng
2015-12-17 17:46 ` [Qemu-devel] [PULL 44/45] coverity: Model g_poll() Paolo Bonzini
2015-12-17 17:46 ` [Qemu-devel] [PULL 45/45] coverity: Model g_memdup() Paolo Bonzini
2015-12-17 19:55 ` [Qemu-devel] [PULL 00/45] KVM, memory, SCSI, qemu_log, Coverity patches for 2015-12-17 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=1450374401-31352-40-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --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 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.