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 18/21] exec: protect mru_block with RCU
Date: Mon, 16 Feb 2015 19:17:59 +0100	[thread overview]
Message-ID: <1424110682-14334-19-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1424110682-14334-1-git-send-email-pbonzini@redhat.com>

Hence, freeing a RAMBlock has to be switched to call_rcu.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 exec.c                 | 52 +++++++++++++++++++++++++++++++++++---------------
 include/exec/cpu-all.h |  2 ++
 2 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/exec.c b/exec.c
index 76b3b6c..5a27c42 100644
--- a/exec.c
+++ b/exec.c
@@ -811,7 +811,7 @@ static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
     RAMBlock *block;
 
     /* The list is protected by the iothread lock here.  */
-    block = ram_list.mru_block;
+    block = atomic_rcu_read(&ram_list.mru_block);
     if (block && addr - block->offset < block->max_length) {
         goto found;
     }
@@ -825,6 +825,22 @@ static RAMBlock *qemu_get_ram_block(ram_addr_t addr)
     abort();
 
 found:
+    /* It is safe to write mru_block outside the iothread lock.  This
+     * is what happens:
+     *
+     *     mru_block = xxx
+     *     rcu_read_unlock()
+     *                                        xxx removed from list
+     *                  rcu_read_lock()
+     *                  read mru_block
+     *                                        mru_block = NULL;
+     *                                        call_rcu(reclaim_ramblock, xxx);
+     *                  rcu_read_unlock()
+     *
+     * atomic_rcu_set is not needed here.  The block was already published
+     * when it was placed into the list.  Here we're just making an extra
+     * copy of the pointer.
+     */
     ram_list.mru_block = block;
     return block;
 }
@@ -1526,13 +1542,31 @@ void qemu_ram_free_from_ptr(ram_addr_t addr)
             QTAILQ_REMOVE(&ram_list.blocks, block, next);
             ram_list.mru_block = NULL;
             ram_list.version++;
-            g_free(block);
+            g_free_rcu(block, rcu);
             break;
         }
     }
     qemu_mutex_unlock_ramlist();
 }
 
+static void reclaim_ramblock(RAMBlock *block)
+{
+    if (block->flags & RAM_PREALLOC) {
+        ;
+    } else if (xen_enabled()) {
+        xen_invalidate_map_cache_entry(block->host);
+#ifndef _WIN32
+    } else if (block->fd >= 0) {
+        munmap(block->host, block->max_length);
+        close(block->fd);
+#endif
+    } else {
+        qemu_anon_ram_free(block->host, block->max_length);
+    }
+    g_free(block);
+}
+
+/* Called with the iothread lock held */
 void qemu_ram_free(ram_addr_t addr)
 {
     RAMBlock *block;
@@ -1544,19 +1578,7 @@ void qemu_ram_free(ram_addr_t addr)
             QTAILQ_REMOVE(&ram_list.blocks, block, next);
             ram_list.mru_block = NULL;
             ram_list.version++;
-            if (block->flags & RAM_PREALLOC) {
-                ;
-            } else if (xen_enabled()) {
-                xen_invalidate_map_cache_entry(block->host);
-#ifndef _WIN32
-            } else if (block->fd >= 0) {
-                munmap(block->host, block->max_length);
-                close(block->fd);
-#endif
-            } else {
-                qemu_anon_ram_free(block->host, block->max_length);
-            }
-            g_free(block);
+            call_rcu(block, reclaim_ramblock, rcu);
             break;
         }
     }
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 2c48286..b8781d1 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -24,6 +24,7 @@
 #include "exec/memory.h"
 #include "qemu/thread.h"
 #include "qom/cpu.h"
+#include "qemu/rcu.h"
 
 /* some important defines:
  *
@@ -268,6 +269,7 @@ CPUArchState *cpu_copy(CPUArchState *env);
 typedef struct RAMBlock RAMBlock;
 
 struct RAMBlock {
+    struct rcu_head rcu;
     struct MemoryRegion *mr;
     uint8_t *host;
     ram_addr_t offset;
-- 
2.3.0

  parent reply	other threads:[~2015-02-16 18:19 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-16 18:17 [Qemu-devel] [PULL 00/21] SCSI, RCU, KVM changes for 2015-02-16 Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 01/21] kvm_stat: Add kvm_exit reasons for aarch64 Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 02/21] qdev: support to get a device firmware path directly Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 03/21] vhost-scsi: add bootindex property Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 04/21] vhost-scsi: expose the TYPE_FW_PATH_PROVIDER interface Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 05/21] vhost-scsi: add a property for booting Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 06/21] vhost-scsi: set the bootable value of channel/target/lun Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 07/21] rcu: do not let RCU callbacks pile up indefinitely Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 08/21] rcu: run RCU callbacks under the BQL Paolo Bonzini
2015-02-25 17:16   ` Leon Alrae
2015-02-26 11:35     ` Paolo Bonzini
2015-02-26 13:40       ` Leon Alrae
2015-02-26 14:39         ` Paolo Bonzini
     [not found]           ` <54EF30AD.9040302@redhat.com>
     [not found]             ` <54EF425A.8010204@imgtec.com>
     [not found]               ` <1644893486.26759341.1424978182441.JavaMail.zimbra@zmail13.collab.prod.int.phx2.redhat.com>
     [not found]                 ` <54F03A7D.90401@imgtec.com>
     [not found]                   ` <54F06E59.2080609@redhat.com>
     [not found]                     ` <54F07E28.6090004@imgtec.com>
2015-02-27 18:27                       ` Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 09/21] memory: keep the owner of the AddressSpace alive until do_address_space_destroy Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 10/21] pcie: remove mmconfig memory leak and wrap mmconfig update with transaction Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 11/21] pci: split shpc_cleanup and shpc_free Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 12/21] docs: clarify memory region lifecycle Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 13/21] exec: introduce cpu_reload_memory_map Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 14/21] exec: make iotlb RCU-friendly Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 15/21] exec: RCUify AddressSpaceDispatch Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 16/21] rcu: introduce RCU-enabled QLIST Paolo Bonzini
2015-02-16 18:17 ` [Qemu-devel] [PULL 17/21] rcu: add g_free_rcu Paolo Bonzini
2015-02-16 18:17 ` Paolo Bonzini [this message]
2015-02-16 18:18 ` [Qemu-devel] [PULL 19/21] cosmetic changes preparing for the following patches Paolo Bonzini
2015-02-16 18:18 ` [Qemu-devel] [PULL 20/21] exec: convert ram_list to QLIST Paolo Bonzini
2015-02-16 18:18 ` [Qemu-devel] [PULL 21/21] Convert ram_list to RCU Paolo Bonzini
2015-02-25 11:01 ` [Qemu-devel] [PULL 00/21] SCSI, RCU, KVM changes for 2015-02-16 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=1424110682-14334-19-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.