From 7d0709ffbbfa96e1be4966b66f23fb35d152dd1f Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela@redhat.com>
Date: Mon, 5 Mar 2012 17:21:50 +0100
Subject: [PATCH 04/11] migration: Fix calculation of bytes_transferred

RH-Author: Juan Quintela <quintela@redhat.com>
Message-id: <06bd6848024789f82e40af980b27165956693167.1330967827.git.quintela@redhat.com>
Patchwork-id: 37961
O-Subject: [PATCH qemu-kvm RHEL-6.3 2/3] migration: Fix calculation of bytes_transferred
Bugzilla: 752138
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>

From: Pierre Riteau <Pierre.Riteau@irisa.fr>

Upstream commit: 3fc250b4be58cac2e392d8d01949f9e8471c36f9

When a page with all identical bytes is transferred, it is counted
as a full page (TARGET_PAGE_SIZE) although only one byte is actually
sent. Fix this by changing ram_save_block() to return the number of
bytes sent instead of a boolean value. This makes bandwidth
estimation, and consequently downtime estimation, more precise.

Signed-off-by: Pierre Riteau <Pierre.Riteau@irisa.fr>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

Conflicts:

	arch_init.c

Author:    Pierre Riteau <Pierre.Riteau@irisa.fr>

We have the code in vl.c not in arch_init.c as upstream.

Signed-off-by: Juan Quintela <quintela@redhat.com>
---
 vl.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 vl.c |   21 +++++++++++++--------
 1 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/vl.c b/vl.c
index fbf01ef..4b869e1 100644
--- a/vl.c
+++ b/vl.c
@@ -2827,7 +2827,7 @@ static int ram_save_block(QEMUFile *f)
     RAMBlock *block = last_block;
     ram_addr_t offset = last_offset;
     ram_addr_t current_addr;
-    int found = 0;
+    int bytes_sent = 0;
 
     if (!block)
         block = QLIST_FIRST(&ram_list.blocks);
@@ -2862,6 +2862,7 @@ static int ram_save_block(QEMUFile *f)
                                     strlen(block->idstr));
                 }
                 qemu_put_byte(f, *p);
+                bytes_sent = 1;
             } else {
                 qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE);
                 if (!cont) {
@@ -2870,9 +2871,9 @@ static int ram_save_block(QEMUFile *f)
                                     strlen(block->idstr));
                 }
                 qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+                bytes_sent = TARGET_PAGE_SIZE;
             }
 
-            found = 1;
             break;
         }
 
@@ -2891,7 +2892,7 @@ static int ram_save_block(QEMUFile *f)
     last_block = block;
     last_offset = offset;
 
-    return found;
+    return bytes_sent;
 }
 
 static uint64_t bytes_transferred;
@@ -2974,9 +2975,11 @@ static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
 
     i = 0;
     while ((ret = qemu_file_rate_limit(f)) == 0) {
-        ret = ram_save_block(f);
-        bytes_transferred += ret * TARGET_PAGE_SIZE;
-        if (ret == 0) /* no more blocks */
+        int bytes_sent;
+
+        bytes_sent = ram_save_block(f);
+        bytes_transferred += bytes_sent;
+        if (bytes_sent == 0) /* no more blocks */
             break;
        /* we want to check in the 1st loop, just in case it was the 1st time
            and we had to sync the dirty bitmap.
@@ -3006,9 +3009,11 @@ static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
 
     /* try transferring iterative blocks of memory */
     if (stage == 3) {
+        int bytes_sent;
+
         /* flush all remaining blocks regardless of rate limiting */
-        while (ram_save_block(f) != 0) {
-            bytes_transferred += TARGET_PAGE_SIZE;
+        while ((bytes_sent = ram_save_block(f)) != 0) {
+            bytes_transferred += bytes_sent;
         }
         cpu_physical_memory_set_dirty_tracking(0);
     }
-- 
1.7.7.6