qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Subject: [Qemu-devel] [PATCH 3/8] memory: Provide address_space_rw_unlocked
Date: Wed, 18 Mar 2015 14:21:44 +0100	[thread overview]
Message-ID: <1426684909-95030-4-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1426684909-95030-1-git-send-email-pbonzini@redhat.com>

From: Jan Kiszka <jan.kiszka@siemens.com>

Break up address_space_rw into two version: The standard one continues
to require the caller to hold BQL on invocation, the unlocked one takes
or avoids BQL depending on the locking strategy of the target memory
region and its coalesced MMIO handling.

As memory_region_read/write_accessor may now also run without BQL held,
we need to move coalesced MMIO flushing earlier in the dispatch process.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c                | 41 +++++++++++++++++++++++++++++++++++++++--
 include/exec/memory.h | 19 +++++++++++++++++++
 memory.c              |  6 ------
 3 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/exec.c b/exec.c
index b264e76..d60abfc 100644
--- a/exec.c
+++ b/exec.c
@@ -48,6 +48,7 @@
 #endif
 #include "exec/cpu-all.h"
 #include "qemu/rcu_queue.h"
+#include "qemu/main-loop.h"
 #include "exec/cputlb.h"
 #include "translate-all.h"
 
@@ -2295,8 +2296,9 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
     return l;
 }
 
-bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
-                      int len, bool is_write)
+static bool address_space_rw_internal(AddressSpace *as, hwaddr addr,
+                                      uint8_t *buf, int len, bool is_write,
+                                      bool unlocked)
 {
     hwaddr l;
     uint8_t *ptr;
@@ -2304,12 +2306,29 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
     hwaddr addr1;
     MemoryRegion *mr;
     bool error = false;
+    bool release_lock;
 
     rcu_read_lock();
     while (len > 0) {
         l = len;
         mr = address_space_translate(as, addr, &addr1, &l, is_write);
 
+        release_lock = false;
+        if (unlocked && mr->global_locking) {
+            qemu_mutex_lock_iothread();
+            unlocked = false;
+            release_lock = true;
+        }
+        if (mr->flush_coalesced_mmio) {
+            if (unlocked) {
+                qemu_mutex_lock_iothread();
+            }
+            qemu_flush_coalesced_mmio_buffer();
+            if (unlocked) {
+                qemu_mutex_unlock_iothread();
+            }
+        }
+
         if (is_write) {
             if (!memory_access_is_direct(mr, is_write)) {
                 l = memory_access_size(mr, l, addr1);
@@ -2380,6 +2399,12 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                 memcpy(buf, ptr, l);
             }
         }
+
+        if (release_lock) {
+            qemu_mutex_unlock_iothread();
+            unlocked = true;
+        }
+
         len -= l;
         buf += l;
         addr += l;
@@ -2389,6 +2414,18 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
     return error;
 }
 
+bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
+                      int len, bool is_write)
+{
+    return address_space_rw_internal(as, addr, buf, len, is_write, false);
+}
+
+bool address_space_rw_unlocked(AddressSpace *as, hwaddr addr, uint8_t *buf,
+                               int len, bool is_write)
+{
+    return address_space_rw_internal(as, addr, buf, len, is_write, true);
+}
+
 bool address_space_write(AddressSpace *as, hwaddr addr,
                          const uint8_t *buf, int len)
 {
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 0644dc6..cf39a40 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1084,6 +1084,8 @@ void address_space_destroy(AddressSpace *as);
  * Return true if the operation hit any unassigned memory or encountered an
  * IOMMU fault.
  *
+ * NOTE: The iothread lock must be held when calling this function.
+ *
  * @as: #AddressSpace to be accessed
  * @addr: address within that address space
  * @buf: buffer with the data transferred
@@ -1093,6 +1095,23 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
                       int len, bool is_write);
 
 /**
+ * address_space_rw_unlocked: read from or write to an address space outside
+ * of the iothread lock.
+ *
+ * Return true if the operation hit any unassigned memory or encountered an
+ * IOMMU fault.
+ *
+ * NOTE: The iothread lock *must not* be held when calling this function.
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @buf: buffer with the data transferred
+ * @is_write: indicates the transfer direction
+ */
+bool address_space_rw_unlocked(AddressSpace *as, hwaddr addr, uint8_t *buf,
+                               int len, bool is_write);
+
+/**
  * address_space_write: write to address space.
  *
  * Return true if the operation hit any unassigned memory or encountered an
diff --git a/memory.c b/memory.c
index cc798e1..838e2f1 100644
--- a/memory.c
+++ b/memory.c
@@ -391,9 +391,6 @@ static void memory_region_read_accessor(MemoryRegion *mr,
 {
     uint64_t tmp;
 
-    if (mr->flush_coalesced_mmio) {
-        qemu_flush_coalesced_mmio_buffer();
-    }
     tmp = mr->ops->read(mr->opaque, addr, size);
     trace_memory_region_ops_read(mr, addr, tmp, size);
     *value |= (tmp & mask) << shift;
@@ -422,9 +419,6 @@ static void memory_region_write_accessor(MemoryRegion *mr,
 {
     uint64_t tmp;
 
-    if (mr->flush_coalesced_mmio) {
-        qemu_flush_coalesced_mmio_buffer();
-    }
     tmp = (*value >> shift) & mask;
     trace_memory_region_ops_write(mr, addr, tmp, size);
     mr->ops->write(mr->opaque, addr, tmp, size);
-- 
2.3.0

  parent reply	other threads:[~2015-03-18 13:22 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-18 13:21 [Qemu-devel] [PATCH for-2.4 0/8] memory: enable unlocked PIO/MMIO in KVM Paolo Bonzini
2015-03-18 13:21 ` [Qemu-devel] [PATCH 1/8] memory: Add global-locking property to memory regions Paolo Bonzini
2015-03-18 13:21 ` [Qemu-devel] [PATCH 2/8] exec: move rcu_read_lock/unlock to address_space_translate callers Paolo Bonzini
2015-03-19 13:27   ` Jan Kiszka
2015-03-19 14:55     ` Jan Kiszka
2015-03-19 16:23       ` Paolo Bonzini
2015-03-18 13:21 ` Paolo Bonzini [this message]
2015-03-18 13:21 ` [Qemu-devel] [PATCH 4/8] kvm: First step to push iothread lock out of inner run loop Paolo Bonzini
2015-03-18 13:21 ` [Qemu-devel] [PATCH 5/8] kvm: Switch to unlocked PIO Paolo Bonzini
2015-03-18 13:21 ` [Qemu-devel] [PATCH 6/8] exec: mark unassigned_io_ops as unlocked Paolo Bonzini
2015-03-18 14:33   ` Jan Kiszka
2015-03-18 14:53     ` Paolo Bonzini
2015-03-18 13:21 ` [Qemu-devel] [PATCH 7/8] acpi: mark PMTIMER " Paolo Bonzini
2015-03-18 13:21 ` [Qemu-devel] [PATCH 8/8] kvm: Switch to unlocked MMIO Paolo Bonzini
2015-03-18 14:33 ` [Qemu-devel] [PATCH for-2.4 0/8] memory: enable unlocked PIO/MMIO in KVM Jan Kiszka
2015-03-18 14:52   ` Paolo Bonzini
2015-03-18 15:04     ` Jan Kiszka
2015-03-19  8:52       ` Paolo Bonzini

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=1426684909-95030-4-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=jan.kiszka@siemens.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 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).