qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH v2 00/10] virtio/vring: optimization patches


From: Gonglei (Arei)
Subject: Re: [Qemu-devel] [PATCH v2 00/10] virtio/vring: optimization patches
Date: Fri, 5 Feb 2016 07:17:55 +0000

Dear Paolo,


> 
> From: Paolo Bonzini [mailto:address@hidden
> Sent: Thursday, February 04, 2016 6:19 PM
> 
> On 03/02/2016 13:08, Gonglei (Arei) wrote:
> > 22.56%  qemu-kvm                 [.] address_space_translate
> >  13.29%  qemu-kvm                 [.] qemu_get_ram_ptr
> 
> We could get rid of qemu_get_ram_ptr by storing the RAMBlock pointer
> into the memory region, instead of the ram_addr_t value.  I'm happy to
> answer any question if you want to do it.
> 
Good point! And I simply realize this change, get nearly 8MB/s through output 
bonus.

Testing AES-128-CBC cipher: 
        Encrypting in chunks of 256 bytes: done. 412.16 MiB in 5.02 secs: 82.17 
MiB/sec (1688202 packets)
        Encrypting in chunks of 256 bytes: done. 412.15 MiB in 5.02 secs: 82.16 
MiB/sec (1688158 packets)
        Encrypting in chunks of 256 bytes: done. 412.32 MiB in 5.02 secs: 82.20 
MiB/sec (1688876 packets)
        Encrypting in chunks of 256 bytes: done. 412.47 MiB in 5.02 secs: 82.23 
MiB/sec (1689491 packets)
        Encrypting in chunks of 256 bytes: done. 412.31 MiB in 5.02 secs: 82.20 
MiB/sec (1688825 packets)
        Encrypting in chunks of 256 bytes: done. 411.30 MiB in 5.01 secs: 82.15 
MiB/sec (1684671 packets)
        Encrypting in chunks of 256 bytes: done. 412.08 MiB in 5.01 secs: 82.18 
MiB/sec (1687864 packets)
        Encrypting in chunks of 256 bytes: done. 412.49 MiB in 5.02 secs: 82.23 
MiB/sec (1689564 packets)

Now, 'perf top' shows me:

16.32%  qemu-kvm                 [.] address_space_translate
  5.39%  libpthread-2.19.so       [.] __pthread_mutex_unlock_usercnt
  4.13%  qemu-kvm                 [.] qemu_ram_addr_from_host
  4.01%  qemu-kvm                 [.] address_space_map
  3.82%  libc-2.19.so             [.] _int_malloc
  3.70%  libc-2.19.so             [.] _int_free
  3.49%  libc-2.19.so             [.] malloc
  3.18%  libpthread-2.19.so       [.] pthread_mutex_lock
  3.10%  qemu-kvm                 [.] phys_page_find
  2.93%  qemu-kvm                 [.] address_space_translate_internal
  2.74%  libc-2.19.so             [.] malloc_consolidate
  2.71%  libc-2.19.so             [.] __memcpy_sse2_unaligned
  1.92%  qemu-kvm                 [.] find_next_zero_bit
  1.65%  qemu-kvm                 [.] object_unref
  1.61%  qemu-kvm                 [.] address_space_rw
  1.35%  qemu-kvm                 [.] virtio_notify
  1.33%  qemu-kvm                 [.] object_ref
  1.22%  libc-2.19.so             [.] memset


Please review the below patch (based on qemu-2.3 which I'm using), thanks!
If it's ok, I can rebase it based on the master branch.

[PATCH] exec: store RAMBlock pointer into memory region

Signed-off-by: Gonglei <address@hidden>
---
 exec.c                  | 39 ++++++++++++++++++++++++---------------
 include/exec/memory.h   |  1 +
 include/exec/ram_addr.h |  1 +
 memory.c                |  4 +++-
 4 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/exec.c b/exec.c
index 4a16769..51d6f30 100644
--- a/exec.c
+++ b/exec.c
@@ -1544,6 +1544,7 @@ ram_addr_t qemu_ram_alloc_internal(ram_addr_t size, 
ram_addr_t max_size,
         error_propagate(errp, local_err);
         return -1;
     }
+    mr->ram_block = new_block;
     return addr;
 }
 
@@ -1817,6 +1818,11 @@ found:
     return mr;
 }
 
+void *qemu_get_ram_ptr_from_block(RAMBlock *block, hwaddr addr)
+{
+    return ramblock_ptr(block, addr - block->offset);
+}
+
 static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
                                uint64_t val, unsigned size)
 {
@@ -2350,7 +2356,7 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, 
uint8_t *buf,
             } else {
                 addr1 += memory_region_get_ram_addr(mr);
                 /* RAM case */
-                ptr = qemu_get_ram_ptr(addr1);
+                ptr = qemu_get_ram_ptr_from_block(mr->ram_block, addr1);
                 memcpy(ptr, buf, l);
                 invalidate_and_set_dirty(addr1, l);
             }
@@ -2384,7 +2390,7 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, 
uint8_t *buf,
                 }
             } else {
                 /* RAM case */
-                ptr = qemu_get_ram_ptr(mr->ram_addr + addr1);
+                ptr = qemu_get_ram_ptr_from_block(mr->ram_block, mr->ram_addr 
+ addr1);
                 memcpy(buf, ptr, l);
             }
         }
@@ -2437,7 +2443,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_from_block(mr->ram_block, addr1);
             switch (type) {
             case WRITE_DATA:
                 memcpy(ptr, buf, l);
@@ -2681,9 +2687,10 @@ static inline uint32_t ldl_phys_internal(AddressSpace 
*as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
-                                & TARGET_PAGE_MASK)
-                               + addr1);
+        ptr = qemu_get_ram_ptr_from_block(mr->ram_block,
+                                (memory_region_get_ram_addr(mr)
+                                 & TARGET_PAGE_MASK)
+                                 + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldl_le_p(ptr);
@@ -2740,9 +2747,10 @@ static inline uint64_t ldq_phys_internal(AddressSpace 
*as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
-                                & TARGET_PAGE_MASK)
-                               + addr1);
+        ptr = qemu_get_ram_ptr_from_block(mr->ram_block,
+                                (memory_region_get_ram_addr(mr)
+                                 & TARGET_PAGE_MASK)
+                                 + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = ldq_le_p(ptr);
@@ -2807,9 +2815,10 @@ static inline uint32_t lduw_phys_internal(AddressSpace 
*as, hwaddr addr,
 #endif
     } else {
         /* RAM case */
-        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(mr)
-                                & TARGET_PAGE_MASK)
-                               + addr1);
+        ptr = qemu_get_ram_ptr_from_block(mr->ram_block,
+                                (memory_region_get_ram_addr(mr)
+                                 & TARGET_PAGE_MASK)
+                                 + addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             val = lduw_le_p(ptr);
@@ -2856,7 +2865,7 @@ void stl_phys_notdirty(AddressSpace *as, hwaddr addr, 
uint32_t val)
         io_mem_write(mr, addr1, val, 4);
     } else {
         addr1 += memory_region_get_ram_addr(mr) & TARGET_PAGE_MASK;
-        ptr = qemu_get_ram_ptr(addr1);
+        ptr = qemu_get_ram_ptr_from_block(mr->ram_block, addr1);
         stl_p(ptr, val);
 
         if (unlikely(in_migration)) {
@@ -2896,7 +2905,7 @@ static inline void stl_phys_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_from_block(mr->ram_block, addr1);
         switch (endian) {
         case DEVICE_LITTLE_ENDIAN:
             stl_le_p(ptr, val);
@@ -2959,7 +2968,7 @@ static inline void stw_phys_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_from_block(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 06ffa1d..bd9ddea 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -146,6 +146,7 @@ struct MemoryRegion {
     Int128 size;
     hwaddr addr;
     void (*destructor)(MemoryRegion *mr);
+    void *ram_block;   /* RAMBlock pointer */
     ram_addr_t ram_addr;
     uint64_t align;
     bool subpage;
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index ff558a4..cc8d769 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -38,6 +38,7 @@ void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
 void *qemu_get_ram_ptr(ram_addr_t addr);
 void qemu_ram_free(ram_addr_t addr);
 void qemu_ram_free_from_ptr(ram_addr_t addr);
+void *qemu_get_ram_ptr_from_block(RAMBlock *block, hwaddr addr);
 
 int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);
 
diff --git a/memory.c b/memory.c
index ee3f2a8..31bd84a 100644
--- a/memory.c
+++ b/memory.c
@@ -877,6 +877,7 @@ void memory_region_init(MemoryRegion *mr,
         mr->size = int128_2_64();
     }
     mr->name = g_strdup(name);
+    mr->ram_block = NULL;
 
     if (name) {
         char *escaped_name = memory_region_escape_name(name);
@@ -1449,7 +1450,8 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
 
     assert(mr->terminates);
 
-    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
+    return qemu_get_ram_ptr_from_block(mr->ram_block,
+                                       mr->ram_addr & TARGET_PAGE_MASK);
 }
 
 static void memory_region_update_coalesced_range_as(MemoryRegion *mr, 
AddressSpace *as)
-- 
1.8.5.2

Regards,
-Gonglei



reply via email to

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