Skip to content

Commit

Permalink
memory: optimize qemu_get_ram_ptr and qemu_ram_ptr_length
Browse files Browse the repository at this point in the history
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 <arei.gonglei@huawei.com>
Message-Id: <1455935721-8804-3-git-send-email-arei.gonglei@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
gongleiarei authored and bonzini committed Feb 25, 2016
1 parent 58eaa21 commit 3655cb9
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
46 changes: 28 additions & 18 deletions exec.c
Expand Up @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions include/exec/memory.h
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion memory.c
Expand Up @@ -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;
Expand Down

0 comments on commit 3655cb9

Please sign in to comment.