[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC v1 2/3] ramlist: apply fine grain lock for ram_list
From: |
Liu Ping Fan |
Subject: |
[Qemu-devel] [RFC v1 2/3] ramlist: apply fine grain lock for ram_list |
Date: |
Fri, 9 Nov 2012 11:14:29 +0800 |
From: Liu Ping Fan <address@hidden>
Signed-off-by: Liu Ping Fan <address@hidden>
---
cpu-all.h | 1 +
exec.c | 46 +++++++++++++++++++++++++++++++++++++++-------
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/cpu-all.h b/cpu-all.h
index 6aa7e58..d3ead99 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -498,6 +498,7 @@ typedef struct RAMBlock {
} RAMBlock;
typedef struct RAMList {
+ QemuMutex lock;
uint8_t *phys_dirty;
QLIST_HEAD(, RAMBlock) blocks;
} RAMList;
diff --git a/exec.c b/exec.c
index fe84718..e5f1c0f 100644
--- a/exec.c
+++ b/exec.c
@@ -2444,6 +2444,7 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
if (QLIST_EMPTY(&ram_list.blocks))
return 0;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
ram_addr_t end, next = RAM_ADDR_MAX;
@@ -2459,6 +2460,7 @@ static ram_addr_t find_ram_offset(ram_addr_t size)
mingap = next - end;
}
}
+ qemu_mutex_unlock(&ram_list.lock);
if (offset == RAM_ADDR_MAX) {
fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n",
@@ -2474,8 +2476,10 @@ ram_addr_t last_ram_offset(void)
RAMBlock *block;
ram_addr_t last = 0;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next)
last = MAX(last, block->offset + block->length);
+ qemu_mutex_unlock(&ram_list.lock);
return last;
}
@@ -2503,6 +2507,7 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char
*name, DeviceState *dev)
RAMBlock *new_block, *block;
new_block = NULL;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (block->offset == addr) {
new_block = block;
@@ -2528,6 +2533,7 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char
*name, DeviceState *dev)
abort();
}
}
+ qemu_mutex_unlock(&ram_list.lock);
}
static int memory_try_enable_merging(void *addr, size_t len)
@@ -2582,12 +2588,6 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void
*host,
}
new_block->length = size;
- QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
-
- ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
- last_ram_offset() >> TARGET_PAGE_BITS);
- memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
- 0, size >> TARGET_PAGE_BITS);
cpu_physical_memory_set_dirty_range(new_block->offset, size, 0xff);
qemu_ram_setup_dump(new_block->host, size);
@@ -2596,6 +2596,15 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void
*host,
if (kvm_enabled())
kvm_setup_guest_memory(new_block->host, size);
+ qemu_mutex_lock(&ram_list.lock);
+ QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
+
+ ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
+ last_ram_offset() >> TARGET_PAGE_BITS);
+ memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
+ 0, size >> TARGET_PAGE_BITS);
+ qemu_mutex_unlock(&ram_list.lock);
+
return new_block->offset;
}
@@ -2608,19 +2617,23 @@ void qemu_ram_free_from_ptr(ram_addr_t addr)
{
RAMBlock *block;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr == block->offset) {
QLIST_REMOVE(block, next);
g_free(block);
+ qemu_mutex_unlock(&ram_list.lock);
return;
}
}
+ qemu_mutex_unlock(&ram_list.lock);
}
void qemu_ram_free(ram_addr_t addr)
{
RAMBlock *block;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr == block->offset) {
QLIST_REMOVE(block, next);
@@ -2649,10 +2662,11 @@ void qemu_ram_free(ram_addr_t addr)
#endif
}
g_free(block);
+ qemu_mutex_unlock(&ram_list.lock);
return;
}
}
-
+ qemu_mutex_unlock(&ram_list.lock);
}
#ifndef _WIN32
@@ -2663,6 +2677,7 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
int flags;
void *area, *vaddr;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
offset = addr - block->offset;
if (offset < block->length) {
@@ -2711,9 +2726,11 @@ void qemu_ram_remap(ram_addr_t addr, ram_addr_t length)
memory_try_enable_merging(vaddr, length);
qemu_ram_setup_dump(vaddr, length);
}
+ qemu_mutex_unlock(&ram_list.lock);
return;
}
}
+ qemu_mutex_unlock(&ram_list.lock);
}
#endif /* !_WIN32 */
@@ -2729,6 +2746,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
{
RAMBlock *block;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr - block->offset < block->length) {
/* Move this entry to to start of the list. */
@@ -2742,15 +2760,18 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
+ qemu_mutex_unlock(&ram_list.lock);
return xen_map_cache(addr, 0, 0);
} else if (block->host == NULL) {
block->host =
xen_map_cache(block->offset, block->length, 1);
}
}
+ qemu_mutex_unlock(&ram_list.lock);
return block->host + (addr - block->offset);
}
}
+ qemu_mutex_unlock(&ram_list.lock);
fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
abort();
@@ -2765,6 +2786,7 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
{
RAMBlock *block;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr - block->offset < block->length) {
if (xen_enabled()) {
@@ -2773,15 +2795,18 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
* In that case just map until the end of the page.
*/
if (block->offset == 0) {
+ qemu_mutex_unlock(&ram_list.lock);
return xen_map_cache(addr, 0, 0);
} else if (block->host == NULL) {
block->host =
xen_map_cache(block->offset, block->length, 1);
}
}
+ qemu_mutex_unlock(&ram_list.lock);
return block->host + (addr - block->offset);
}
}
+ qemu_mutex_unlock(&ram_list.lock);
fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
abort();
@@ -2801,13 +2826,16 @@ void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t
*size)
} else {
RAMBlock *block;
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
if (addr - block->offset < block->length) {
if (addr - block->offset + *size > block->length)
*size = block->length - addr + block->offset;
+ qemu_mutex_lock(&ram_list.lock);
return block->host + (addr - block->offset);
}
}
+ qemu_mutex_unlock(&ram_list.lock);
fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
abort();
@@ -2829,6 +2857,7 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t
*ram_addr)
return 0;
}
+ qemu_mutex_lock(&ram_list.lock);
QLIST_FOREACH(block, &ram_list.blocks, next) {
/* This case append when the block is not mapped. */
if (block->host == NULL) {
@@ -2836,9 +2865,11 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t
*ram_addr)
}
if (host - block->host < block->length) {
*ram_addr = block->offset + (host - block->host);
+ qemu_mutex_unlock(&ram_list.lock);
return 0;
}
}
+ qemu_mutex_unlock(&ram_list.lock);
return -1;
}
@@ -3318,6 +3349,7 @@ static void memory_map_init(void)
address_space_io.name = "I/O";
qemu_mutex_init(&bounce.lock);
+ qemu_mutex_unlock(&ram_list.lock);
memory_listener_register(&core_memory_listener, &address_space_memory);
memory_listener_register(&io_memory_listener, &address_space_io);
--
1.7.4.4
[Qemu-devel] [RFC v1 3/3] make address_space_map safe, Liu Ping Fan, 2012/11/08