[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 16/19] memory: optimize qemu_get_ram_ptr and qemu_ram
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 16/19] memory: optimize qemu_get_ram_ptr and qemu_ram_ptr_length |
Date: |
Wed, 24 Feb 2016 14:27:38 +0100 |
From: Gonglei <address@hidden>
these two functions consume too much cpu overhead to
find the RAMBlock by ram address.
After this patch, we can pass the RAMBlock pointer
to them so that they don't need to find the RAMBlock
anymore most of the time. We can get better performance
in address translation processing.
Signed-off-by: Gonglei <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
exec.c | 46 ++++++++++++++++++++++++++++------------------
include/exec/memory.h | 4 ++--
memory.c | 2 +-
3 files changed, 31 insertions(+), 21 deletions(-)
diff --git a/exec.c b/exec.c
index 4c0114a..c62c439 100644
--- a/exec.c
+++ b/exec.c
@@ -1868,9 +1868,13 @@ void *qemu_get_ram_block_host_ptr(ram_addr_t addr)
*
* Called within RCU critical section.
*/
-void *qemu_get_ram_ptr(ram_addr_t addr)
+void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr)
{
- RAMBlock *block = qemu_get_ram_block(addr);
+ RAMBlock *block = ram_block;
+
+ if (block == NULL) {
+ block = qemu_get_ram_block(addr);
+ }
if (xen_enabled() && block->host == NULL) {
/* We need to check if the requested address is in the RAM
@@ -1891,15 +1895,18 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
*
* Called within RCU critical section.
*/
-static void *qemu_ram_ptr_length(ram_addr_t addr, hwaddr *size)
+static void *qemu_ram_ptr_length(RAMBlock *ram_block, ram_addr_t addr,
+ hwaddr *size)
{
- RAMBlock *block;
+ RAMBlock *block = ram_block;
ram_addr_t offset_inside_block;
if (*size == 0) {
return NULL;
}
- block = qemu_get_ram_block(addr);
+ if (block == NULL) {
+ block = qemu_get_ram_block(addr);
+ }
offset_inside_block = addr - block->offset;
*size = MIN(*size, block->max_length - offset_inside_block);
@@ -2027,13 +2034,13 @@ static void notdirty_mem_write(void *opaque, hwaddr
ram_addr,
}
switch (size) {
case 1:
- stb_p(qemu_get_ram_ptr(ram_addr), val);
+ stb_p(qemu_get_ram_ptr(NULL, ram_addr), val);
break;
case 2:
- stw_p(qemu_get_ram_ptr(ram_addr), val);
+ stw_p(qemu_get_ram_ptr(NULL, ram_addr), val);
break;
case 4:
- stl_p(qemu_get_ram_ptr(ram_addr), val);
+ stl_p(qemu_get_ram_ptr(NULL, ram_addr), val);
break;
default:
abort();
@@ -2609,7 +2616,7 @@ static MemTxResult
address_space_write_continue(AddressSpace *as, hwaddr addr,
} else {
addr1 += memory_region_get_ram_addr(mr);
/* RAM case */
- ptr = qemu_get_ram_ptr(addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(mr, addr1, l);
}
@@ -2700,7 +2707,7 @@ MemTxResult address_space_read_continue(AddressSpace *as,
hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr(mr->ram_addr + addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, mr->ram_addr + addr1);
memcpy(buf, ptr, l);
}
@@ -2785,7 +2792,7 @@ static inline void
cpu_physical_memory_write_rom_internal(AddressSpace *as,
} else {
addr1 += memory_region_get_ram_addr(mr);
/* ROM/RAM case */
- ptr = qemu_get_ram_ptr(addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
switch (type) {
case WRITE_DATA:
memcpy(ptr, buf, l);
@@ -2997,7 +3004,7 @@ void *address_space_map(AddressSpace *as,
memory_region_ref(mr);
*plen = done;
- ptr = qemu_ram_ptr_length(raddr + base, plen);
+ ptr = qemu_ram_ptr_length(mr->ram_block, raddr + base, plen);
rcu_read_unlock();
return ptr;
@@ -3081,7 +3088,8 @@ static inline uint32_t
address_space_ldl_internal(AddressSpace *as, hwaddr addr,
#endif
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
+ ptr = qemu_get_ram_ptr(mr->ram_block,
+ (memory_region_get_ram_addr(mr)
& TARGET_PAGE_MASK)
+ addr1);
switch (endian) {
@@ -3176,7 +3184,8 @@ static inline uint64_t
address_space_ldq_internal(AddressSpace *as, hwaddr addr,
#endif
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
+ ptr = qemu_get_ram_ptr(mr->ram_block,
+ (memory_region_get_ram_addr(mr)
& TARGET_PAGE_MASK)
+ addr1);
switch (endian) {
@@ -3291,7 +3300,8 @@ static inline uint32_t
address_space_lduw_internal(AddressSpace *as,
#endif
} else {
/* RAM case */
- ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
+ ptr = qemu_get_ram_ptr(mr->ram_block,
+ (memory_region_get_ram_addr(mr)
& TARGET_PAGE_MASK)
+ addr1);
switch (endian) {
@@ -3376,7 +3386,7 @@ void address_space_stl_notdirty(AddressSpace *as, hwaddr
addr, uint32_t val,
r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
} else {
addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
- ptr = qemu_get_ram_ptr(addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
stl_p(ptr, val);
dirty_log_mask = memory_region_get_dirty_log_mask(mr);
@@ -3431,7 +3441,7 @@ static inline void
address_space_stl_internal(AddressSpace *as,
} else {
/* RAM case */
addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
- ptr = qemu_get_ram_ptr(addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
stl_le_p(ptr, val);
@@ -3541,7 +3551,7 @@ static inline void
address_space_stw_internal(AddressSpace *as,
} else {
/* RAM case */
addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
- ptr = qemu_get_ram_ptr(addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
switch (endian) {
case DEVICE_LITTLE_ENDIAN:
stw_le_p(ptr, val);
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 4025729..1cf2e51 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -1391,7 +1391,7 @@ MemTxResult address_space_read_continue(AddressSpace *as,
hwaddr addr,
MemoryRegion *mr);
MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs, uint8_t *buf, int len);
-void *qemu_get_ram_ptr(ram_addr_t addr);
+void *qemu_get_ram_ptr(RAMBlock *ram_block, ram_addr_t addr);
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
@@ -1432,7 +1432,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr
addr, MemTxAttrs attrs,
mr = address_space_translate(as, addr, &addr1, &l, false);
if (len == l && memory_access_is_direct(mr, false)) {
addr1 += memory_region_get_ram_addr(mr);
- ptr = qemu_get_ram_ptr(addr1);
+ ptr = qemu_get_ram_ptr(mr->ram_block, addr1);
memcpy(buf, ptr, len);
} else {
result = address_space_read_continue(as, addr, attrs, buf, len,
diff --git a/memory.c b/memory.c
index b4451dd..0dd9695 100644
--- a/memory.c
+++ b/memory.c
@@ -1570,7 +1570,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
mr = mr->alias;
}
assert(mr->ram_addr != RAM_ADDR_INVALID);
- ptr = qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
+ ptr = qemu_get_ram_ptr(mr->ram_block, mr->ram_addr & TARGET_PAGE_MASK);
rcu_read_unlock();
return ptr + offset;
--
2.5.0
- [Qemu-devel] [PULL 08/19] dump-guest-memory: disable dump when in INMIGRATE state, (continued)
- [Qemu-devel] [PULL 08/19] dump-guest-memory: disable dump when in INMIGRATE state, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 09/19] dump-guest-memory: add "detach" support, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 07/19] dump-guest-memory: introduce dump_process() helper function., Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 06/19] dump-guest-memory: add dump_in_progress() helper function, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 10/19] DumpState: adding total_size and written_size fields, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 12/19] Dump: add hmp command "info dump", Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 11/19] Dump: add qmp command "query-dump", Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 14/19] log: Redirect stderr to logfile if deamonized, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 13/19] dump-guest-memory: add qmp event DUMP_COMPLETED, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 16/19] memory: optimize qemu_get_ram_ptr and qemu_ram_ptr_length,
Paolo Bonzini <=
- [Qemu-devel] [PULL 17/19] memory: Remove unreachable return statement, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 18/19] chardev: Properly initialize ChardevCommon components, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 15/19] exec: store RAMBlock pointer into memory region, Paolo Bonzini, 2016/02/24
- [Qemu-devel] [PULL 19/19] target-i386: fix confusion in xcr0 bit position vs. mask, Paolo Bonzini, 2016/02/24
- Re: [Qemu-devel] [PULL 00/19] Misc changes for 2016-02-24, Peter Maydell, 2016/02/25