Patchwork [v8,10/10] Add XBZRLE statstics information

login
register
mail settings
Submitter Orit Wasserman
Date April 5, 2012, 10:47 a.m.
Message ID <1333622879-12055-11-git-send-email-owasserm@redhat.com>
Download mbox | patch
Permalink /patch/151101/
State New
Headers show

Comments

Orit Wasserman - April 5, 2012, 10:47 a.m.
Signed-off-by: Orit Wasserman <owasserm@redhat.com>
---
 arch_init.c      |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hmp.c            |   11 ++++++++
 migration.c      |   11 ++++++++
 migration.h      |    9 +++++++
 qapi-schema.json |   21 +++++++++++++++-
 5 files changed, 118 insertions(+), 2 deletions(-)

Patch

diff --git a/arch_init.c b/arch_init.c
index 9df9d1c..8c0eb37 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -182,6 +182,64 @@  void xbzrle_cache_resize(int64_t new_size)
     }
 }
 
+/* accounting */
+typedef struct AccountingInfo {
+    uint64_t dup_pages;
+    uint64_t norm_pages;
+    uint64_t xbzrle_bytes;
+    uint64_t xbzrle_pages;
+    uint64_t xbzrle_cache_miss;
+    uint64_t iterations;
+    uint64_t xbzrle_overflows;
+} AccountingInfo;
+
+static AccountingInfo acct_info;
+
+static void acct_clear(void)
+{
+    memset(&acct_info, 0, sizeof(acct_info));
+}
+
+uint64_t dup_mig_bytes_transferred(void)
+{
+    return acct_info.dup_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t dup_mig_pages_transferred(void)
+{
+    return acct_info.dup_pages;
+}
+
+uint64_t norm_mig_bytes_transferred(void)
+{
+    return acct_info.norm_pages * TARGET_PAGE_SIZE;
+}
+
+uint64_t norm_mig_pages_transferred(void)
+{
+    return acct_info.norm_pages;
+}
+
+uint64_t xbzrle_mig_bytes_transferred(void)
+{
+    return acct_info.xbzrle_bytes;
+}
+
+uint64_t xbzrle_mig_pages_transferred(void)
+{
+    return acct_info.xbzrle_pages;
+}
+
+uint64_t xbzrle_mig_pages_cache_miss(void)
+{
+    return acct_info.xbzrle_cache_miss;
+}
+
+uint64_t xbzrle_mig_pages_overflow(void)
+{
+    return acct_info.xbzrle_overflows;
+}
+
 /***********************************************************/
 /* XBRLE page cache implementation */
 static CacheItem *cache_item_get(unsigned long pos, int item)
@@ -350,6 +408,7 @@  static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
     slot = cache_is_cached(current_addr);
     if (slot == -1) {
         cache_insert(current_addr, current_data);
+        acct_info.xbzrle_cache_miss++;
         goto done;
     }
     cache_location = cache_get_cache_pos(current_addr);
@@ -369,6 +428,9 @@  static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
     if (encoded_len < 0) {
         DPRINTF("Unmodifed page - skipping\n");
         goto done;
+    } else if (encoded_len == 0) {
+        DPRINTF("Overflow - sending orginal page\n");
+        acct_info.xbzrle_overflows++;
     }
 
     hdr.xh_len = encoded_len;
@@ -378,7 +440,9 @@  static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
     save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
     qemu_put_buffer(f, (uint8_t *) &hdr, sizeof(hdr));
     qemu_put_buffer(f, encoded_buf, encoded_len);
+    acct_info.xbzrle_pages++;
     bytes_sent = encoded_len + sizeof(hdr);
+    acct_info.xbzrle_bytes += bytes_sent;
 
 done:
     g_free(encoded_buf);
@@ -418,6 +482,7 @@  static int ram_save_block(QEMUFile *f, int stage)
                 save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_COMPRESS);
                 qemu_put_byte(f, *p);
                 bytes_sent = 1;
+                acct_info.dup_pages++;
             } else if (stage == 2 && use_xbzrle) {
                 bytes_sent = save_xbzrle_page(f, p, current_addr, block,
                     offset, cont);
@@ -429,6 +494,7 @@  static int ram_save_block(QEMUFile *f, int stage)
                 save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_PAGE);
                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
                 bytes_sent = TARGET_PAGE_SIZE;
+                 acct_info.norm_pages++;
             }
 
             break;
@@ -546,6 +612,7 @@  int ram_save_live(QEMUFile *f, int stage, void *opaque)
 
         if (migrate_use_xbzrle()) {
             cache_init(migrate_xbzrle_cache_size());
+            acct_clear();
         }
 
         /* Make sure all dirty bits are set */
@@ -579,6 +646,7 @@  int ram_save_live(QEMUFile *f, int stage, void *opaque)
         /* bytes_sent -1 represent unchanged page */
         if (bytes_sent > 0) {
             bytes_transferred += bytes_sent;
+            acct_info.iterations++;
         } else if (bytes_sent == 0) { /* no more blocks */
             break;
         }
diff --git a/hmp.c b/hmp.c
index c1b5380..f1c6439 100644
--- a/hmp.c
+++ b/hmp.c
@@ -153,6 +153,17 @@  void hmp_info_migrate(Monitor *mon)
                        info->disk->total >> 10);
     }
 
+    if (info->has_cache) {
+        monitor_printf(mon, "xbzrle transferred: %" PRIu64 " kbytes\n",
+                       info->cache->xbzrle_bytes >> 10);
+        monitor_printf(mon, "xbzrle pages: %" PRIu64 " pages\n",
+                       info->cache->xbzrle_pages);
+        monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
+                       info->cache->xbzrle_cache_miss);
+        monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
+                       info->cache->xbzrle_overflow);
+    }
+
     qapi_free_MigrationInfo(info);
 }
 
diff --git a/migration.c b/migration.c
index ec51ad3..561ff65 100644
--- a/migration.c
+++ b/migration.c
@@ -135,6 +135,8 @@  MigrationInfo *qmp_query_migrate(Error **errp)
         info->ram->transferred = ram_bytes_transferred();
         info->ram->remaining = ram_bytes_remaining();
         info->ram->total = ram_bytes_total();
+        info->ram->duplicate = dup_mig_pages_transferred();
+        info->ram->norm  = norm_mig_pages_transferred();
 
         if (blk_mig_active()) {
             info->has_disk = true;
@@ -143,6 +145,15 @@  MigrationInfo *qmp_query_migrate(Error **errp)
             info->disk->remaining = blk_mig_bytes_remaining();
             info->disk->total = blk_mig_bytes_total();
         }
+
+        if (s->params.use_xbzrle) {
+            info->has_cache = true;
+            info->cache = g_malloc0(sizeof(*info->cache));
+            info->cache->xbzrle_bytes  = xbzrle_mig_bytes_transferred();
+            info->cache->xbzrle_pages  = xbzrle_mig_pages_transferred();
+            info->cache->xbzrle_cache_miss = xbzrle_mig_pages_cache_miss();
+            info->cache->xbzrle_overflow = xbzrle_mig_pages_overflow();
+        }
         break;
     case MIG_STATE_COMPLETED:
         info->has_status = true;
diff --git a/migration.h b/migration.h
index 3426c94..03f116d 100644
--- a/migration.h
+++ b/migration.h
@@ -82,6 +82,15 @@  uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_transferred(void);
 uint64_t ram_bytes_total(void);
 
+uint64_t dup_mig_bytes_transferred(void);
+uint64_t dup_mig_pages_transferred(void);
+uint64_t norm_mig_bytes_transferred(void);
+uint64_t norm_mig_pages_transferred(void);
+uint64_t xbzrle_mig_bytes_transferred(void);
+uint64_t xbzrle_mig_pages_transferred(void);
+uint64_t xbzrle_mig_pages_overflow(void);
+uint64_t xbzrle_mig_pages_cache_miss(void);
+
 int ram_save_live(QEMUFile *f, int stage, void *opaque);
 int ram_load(QEMUFile *f, void *opaque, int version_id);
 
diff --git a/qapi-schema.json b/qapi-schema.json
index f055ec6..20ba316 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -239,7 +239,24 @@ 
 # Since: 0.14.0.
 ##
 { 'type': 'MigrationStats',
-  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int' } }
+  'data': {'transferred': 'int', 'remaining': 'int', 'total': 'int', 'duplicate': 'int', 'norm': 'int' } }
+
+##
+# @CacheStats
+#
+# Detailed XBZRLE migration cache statistics
+#
+# @xbzrle_bytes: amount of bytes already transferred to the target VM
+#
+# @xbzrle_pages: amount of pages transferred to the target VM
+#
+# @xbzrle_cache_miss: numer of cache miss
+#
+# Since: 1.1
+##
+{ 'type': 'CacheStats',
+  'data': {'xbzrle_bytes': 'int', 'xbzrle_pages': 'int', 'xbzrle_cache_miss': 'int',
+           'xbzrle_overflow': 'int' } }
 
 ##
 # @MigrationInfo
@@ -262,7 +279,7 @@ 
 ##
 { 'type': 'MigrationInfo',
   'data': {'*status': 'str', '*ram': 'MigrationStats',
-           '*disk': 'MigrationStats'} }
+           '*disk': 'MigrationStats', '*cache': 'CacheStats'} }
 
 ##
 # @query-migrate