From: Igor Mammedov <imammedo@redhat.com>
To: qemu-devel@nongnu.org
Cc: pbonzini@redhat.com, mst@redhat.com
Subject: [Qemu-devel] [RFC v2 3/6] memory: support unmapping of MemoryRegion mapped into HVA parent
Date: Mon, 8 Jun 2015 17:19:14 +0200 [thread overview]
Message-ID: <1433776757-61958-4-git-send-email-imammedo@redhat.com> (raw)
In-Reply-To: <1433776757-61958-1-git-send-email-imammedo@redhat.com>
due to need to preserve HVA reserved range continous (make it atomic),
unmap subregion's host memory by placing reservation mapping
on it's range and invalidate subregion since it can't be reused
anymore.
Also add memory_region_is_hva_mapped() to let backend check if
MemoryRegion should be recreated instead of returning invalidated
region.
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
exec.c | 17 ++++++++++++++++-
include/exec/cpu-common.h | 1 +
include/exec/memory.h | 13 +++++++++++++
memory.c | 16 ++++++++++++++++
4 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/exec.c b/exec.c
index 7e47f64..7bef7f9 100644
--- a/exec.c
+++ b/exec.c
@@ -1332,11 +1332,22 @@ void *qemu_ram_reserve_hva(ram_addr_t length)
MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
}
+void qemu_ram_unmap_hva(ram_addr_t addr)
+{
+ RAMBlock *block = find_ram_block(addr);
+
+ assert(block);
+ mmap(block->host, block->used_length, PROT_NONE,
+ MAP_FIXED | MAP_NORESERVE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+}
+
void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva)
{
RAMBlock *block = find_ram_block(addr);
assert(block);
+ assert(!(block->flags & RAM_PREALLOC));
+ block->flags |= RAM_PREALLOC;
block->host = mremap(block->host, block->used_length,
block->used_length,
MREMAP_MAYMOVE | MREMAP_FIXED, new_hva);
@@ -1595,11 +1606,15 @@ static void reclaim_ramblock(RAMBlock *block)
#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);
}
+#ifndef _WIN32
+ if (block->fd >= 0) {
+ close(block->fd);
+ }
+#endif
g_free(block);
}
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index ec077ee..817762c 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -62,6 +62,7 @@ typedef uint32_t CPUReadMemoryFunc(void *opaque, hwaddr addr);
void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
void *qemu_ram_reserve_hva(ram_addr_t length);
void qemu_ram_remap_hva(ram_addr_t addr, void *new_hva);
+void qemu_ram_unmap_hva(ram_addr_t addr);
/* This should not be used by devices. */
MemoryRegion *qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 5e16026..f9e86d6 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -175,6 +175,7 @@ struct MemoryRegion {
bool romd_mode;
bool ram;
void *rsvd_hva;
+ bool hva_mapped;
bool skip_dump;
bool readonly; /* For RAM regions */
bool enabled;
@@ -902,6 +903,10 @@ void memory_region_add_subregion(MemoryRegion *mr,
* memory_region_del_subregion()); use memory_region_init_alias() if you
* want a region to be a subregion in multiple locations.
*
+ * if @subregion has HVA container as parent, the call rereseves HVA
+ * range ocicupied by @subregion, freeing host memory along the way
+ * and invalidates @subregion so it coudn't be reused.
+ *
* @mr: the region to contain the new subregion; must be a container
* initialized with memory_region_init().
* @offset: the offset relative to @mr where @subregion is added.
@@ -1003,6 +1008,14 @@ bool memory_region_present(MemoryRegion *container, hwaddr addr);
bool memory_region_is_mapped(MemoryRegion *mr);
/**
+ * memory_region_is_hva_mapped: returns true if #MemoryRegion is/was
+ * mapped into HVA container.
+ *
+ * @mr: a #MemoryRegion which should be checked if it's HVA parent
+ */
+bool memory_region_is_hva_mapped(MemoryRegion *mr);
+
+/**
* memory_region_find: translate an address/size relative to a
* MemoryRegion into a #MemoryRegionSection.
*
diff --git a/memory.c b/memory.c
index f9b8a60..ab6d41b 100644
--- a/memory.c
+++ b/memory.c
@@ -1754,7 +1754,9 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
if (mr->ram) {
MemoryRegionSection rsvd_hva = memory_region_find_hva_range(mr);
+ assert(!subregion->hva_mapped);
if (rsvd_hva.mr) {
+ subregion->hva_mapped = true;
qemu_ram_remap_hva(mr->ram_addr,
memory_region_get_ram_ptr(rsvd_hva.mr) +
rsvd_hva.offset_within_region);
@@ -1788,6 +1790,15 @@ void memory_region_del_subregion(MemoryRegion *mr,
{
memory_region_transaction_begin();
assert(subregion->container == mr);
+
+ if (mr->ram) {
+ MemoryRegionSection rsvd_hva = memory_region_find_hva_range(mr);
+
+ if (rsvd_hva.mr) {
+ qemu_ram_unmap_hva(mr->ram_addr);
+ }
+ }
+
subregion->container = NULL;
QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
memory_region_unref(subregion);
@@ -1903,6 +1914,11 @@ bool memory_region_is_mapped(MemoryRegion *mr)
return mr->container ? true : false;
}
+bool memory_region_is_hva_mapped(MemoryRegion *mr)
+{
+ return mr->hva_mapped ? true : false;
+}
+
MemoryRegionSection memory_region_find_hva_range(MemoryRegion *mr)
{
MemoryRegionSection ret = { .mr = NULL };
--
1.8.3.1
next prev parent reply other threads:[~2015-06-08 15:19 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-08 15:19 [Qemu-devel] [RFC v2 0/6] Fix QEMU crash during memory hotplug with vhost=on Igor Mammedov
2015-06-08 15:19 ` [Qemu-devel] [RFC v2 1/6] memory: get rid of memory_region_destructor_ram_from_ptr() Igor Mammedov
2015-06-08 15:23 ` Paolo Bonzini
2015-06-08 16:08 ` Igor Mammedov
2015-06-08 16:09 ` Paolo Bonzini
2015-06-08 16:26 ` Igor Mammedov
2015-06-08 15:19 ` [Qemu-devel] [RFC v2 2/6] memory: introduce MemoryRegion container with reserved HVA range Igor Mammedov
2015-06-08 15:19 ` Igor Mammedov [this message]
2015-06-08 15:26 ` [Qemu-devel] [RFC v2 3/6] memory: support unmapping of MemoryRegion mapped into HVA parent Paolo Bonzini
2015-06-08 15:32 ` Paolo Bonzini
2015-06-08 16:13 ` Igor Mammedov
2015-06-08 16:25 ` Michael S. Tsirkin
2015-06-08 17:06 ` Paolo Bonzini
2015-06-09 10:08 ` Igor Mammedov
2015-06-17 8:14 ` Paolo Bonzini
2015-06-17 15:04 ` Igor Mammedov
2015-06-17 15:10 ` Michael S. Tsirkin
2015-06-17 16:15 ` Paolo Bonzini
2015-06-17 16:30 ` Michael S. Tsirkin
2015-06-08 15:19 ` [Qemu-devel] [RFC v2 4/6] hostmem: return recreated MemoryRegion if current can't be reused Igor Mammedov
2015-06-08 15:30 ` Paolo Bonzini
2015-06-08 16:25 ` Igor Mammedov
2015-06-08 16:28 ` Paolo Bonzini
2015-06-08 15:19 ` [Qemu-devel] [RFC v2 5/6] pc: reserve hotpluggable memory range with memory_region_init_hva_range() Igor Mammedov
2015-06-08 15:19 ` [Qemu-devel] [RFC v2 6/6] pc: fix QEMU crashing when more than ~50 memory hotplugged Igor Mammedov
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=1433776757-61958-4-git-send-email-imammedo@redhat.com \
--to=imammedo@redhat.com \
--cc=mst@redhat.com \
--cc=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 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).