qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v1 3/6] memory: Add address_space_init_shareable()


From: Peter Crosthwaite
Subject: [Qemu-devel] [PATCH v1 3/6] memory: Add address_space_init_shareable()
Date: Tue, 2 Sep 2014 01:42:52 -0700

This will either create a new AS or return a pointer to an
already existing equivalent one. Both name and root mr must
match.

The motivation is to reuse address spaces as much as possible.
It's going to be quite common that bus masters out in device land
have pointers to the same memory region for their mastering yet
each will need to create its own address space. Let the memory
API implement sharing for them.

Aside from the perf optimisations, this should reduce the amount
of redundant output on info mtree as well.

Thee returned value will be malloced, but the malloc will be
automatically freed when the AS runs out of refs.

Signed-off-by: Peter Crosthwaite <address@hidden>
---
We could change the equivalency test only match mr to support device
specific naming of these shared ASes. The singleton AS can ultimately
only have one name however. So perhaps some strcatting each time a new
sharer is added to the share. That or first-in-best-dressed.

Changed since v1:
Implement ref counting and garbage collection.

 include/exec/memory.h |  3 +++
 memory.c              | 25 +++++++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 18cb6b2..cbd7336 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -208,6 +208,7 @@ struct AddressSpace {
     char *name;
     MemoryRegion *root;
     int ref_count;
+    bool malloced;
     struct FlatView *current_map;
     int ioeventfd_nb;
     struct MemoryRegionIoeventfd *ioeventfds;
@@ -977,6 +978,8 @@ void mtree_info(fprintf_function mon_printf, void *f);
  */
 void address_space_init(AddressSpace *as, MemoryRegion *root, const char 
*name);
 
+AddressSpace *address_space_init_shareable(MemoryRegion *root,
+                                           const char *name);
 
 /**
  * address_space_destroy: destroy an address space
diff --git a/memory.c b/memory.c
index 27beef1..08ab918 100644
--- a/memory.c
+++ b/memory.c
@@ -1932,6 +1932,7 @@ void address_space_init(AddressSpace *as, MemoryRegion 
*root, const char *name)
     memory_region_transaction_begin();
     as->ref_count = 1;
     as->root = root;
+    as->malloced = false;
     as->current_map = g_new(FlatView, 1);
     flatview_init(as->current_map);
     as->ioeventfd_nb = 0;
@@ -1943,6 +1944,27 @@ void address_space_init(AddressSpace *as, MemoryRegion 
*root, const char *name)
     memory_region_transaction_commit();
 }
 
+AddressSpace *address_space_init_shareable(MemoryRegion *root, const char 
*name)
+{
+    AddressSpace *as;
+
+    if (!root) {
+        return NULL;
+    }
+
+    QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
+        if (root == as->root && !strcmp(name ? name : "anonymous", as->name)) {
+            as->ref_count++;
+            return as;
+        }
+    }
+
+    as = g_malloc0(sizeof *as);
+    address_space_init(as, root, name);
+    as->malloced = true;
+    return as;
+}
+
 void address_space_destroy(AddressSpace *as)
 {
     MemoryListener *listener;
@@ -1965,6 +1987,9 @@ void address_space_destroy(AddressSpace *as)
     flatview_unref(as->current_map);
     g_free(as->name);
     g_free(as->ioeventfds);
+    if (as->malloced) {
+        g_free(as);
+    }
 }
 
 bool io_mem_read(MemoryRegion *mr, hwaddr addr, uint64_t *pval, unsigned size)
-- 
2.1.0.1.g27b9230




reply via email to

[Prev in Thread] Current Thread [Next in Thread]