9ae3a8
From c18e8f4bf7a628949f0d79facf91ddf6d07401e9 Mon Sep 17 00:00:00 2001
9ae3a8
From: Juan Quintela <quintela@redhat.com>
9ae3a8
Date: Tue, 14 Jan 2014 15:07:49 +0100
9ae3a8
Subject: [PATCH 38/40] memory: syncronize kvm bitmap using bitmaps operations
9ae3a8
9ae3a8
RH-Author: Juan Quintela <quintela@redhat.com>
9ae3a8
Message-id: <1389712071-23303-39-git-send-email-quintela@redhat.com>
9ae3a8
Patchwork-id: 56693
9ae3a8
O-Subject: [RHEL7 qemu-kvm PATCH 38/40] memory: syncronize kvm bitmap using bitmaps operations
9ae3a8
Bugzilla: 997559
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>
9ae3a8
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
9ae3a8
9ae3a8
If bitmaps are aligned properly, use bitmap operations.  If they are
9ae3a8
not, just use old bit at a time code.
9ae3a8
9ae3a8
Signed-off-by: Juan Quintela <quintela@redhat.com>
9ae3a8
Reviewed-by: Orit Wasserman <owasserm@redhat.com>
9ae3a8
(cherry picked from commit ae2810c4bb3b383176e8e1b33931b16c01483aab)
9ae3a8
Signed-off-by: Juan Quintela <quintela@trasno.org>
9ae3a8
---
9ae3a8
 include/exec/ram_addr.h | 54 ++++++++++++++++++++++++++++++++-----------------
9ae3a8
 1 file changed, 36 insertions(+), 18 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 include/exec/ram_addr.h |   54 +++++++++++++++++++++++++++++++---------------
9ae3a8
 1 files changed, 36 insertions(+), 18 deletions(-)
9ae3a8
9ae3a8
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
9ae3a8
index 9962e12..080a8b1 100644
9ae3a8
--- a/include/exec/ram_addr.h
9ae3a8
+++ b/include/exec/ram_addr.h
9ae3a8
@@ -82,29 +82,47 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap,
9ae3a8
                                                           ram_addr_t start,
9ae3a8
                                                           ram_addr_t pages)
9ae3a8
 {
9ae3a8
-    unsigned int i, j;
9ae3a8
+    unsigned long i, j;
9ae3a8
     unsigned long page_number, c;
9ae3a8
     hwaddr addr;
9ae3a8
     ram_addr_t ram_addr;
9ae3a8
-    unsigned int len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
9ae3a8
+    unsigned long len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
9ae3a8
     unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE;
9ae3a8
+    unsigned long page = BIT_WORD(start >> TARGET_PAGE_BITS);
9ae3a8
 
9ae3a8
-    /*
9ae3a8
-     * bitmap-traveling is faster than memory-traveling (for addr...)
9ae3a8
-     * especially when most of the memory is not dirty.
9ae3a8
-     */
9ae3a8
-    for (i = 0; i < len; i++) {
9ae3a8
-        if (bitmap[i] != 0) {
9ae3a8
-            c = leul_to_cpu(bitmap[i]);
9ae3a8
-            do {
9ae3a8
-                j = ffsl(c) - 1;
9ae3a8
-                c &= ~(1ul << j);
9ae3a8
-                page_number = (i * HOST_LONG_BITS + j) * hpratio;
9ae3a8
-                addr = page_number * TARGET_PAGE_SIZE;
9ae3a8
-                ram_addr = start + addr;
9ae3a8
-                cpu_physical_memory_set_dirty_range(ram_addr,
9ae3a8
-                                                    TARGET_PAGE_SIZE * hpratio);
9ae3a8
-            } while (c != 0);
9ae3a8
+    /* start address is aligned at the start of a word? */
9ae3a8
+    if (((page * BITS_PER_LONG) << TARGET_PAGE_BITS) == start) {
9ae3a8
+        long k;
9ae3a8
+        long nr = BITS_TO_LONGS(pages);
9ae3a8
+
9ae3a8
+        for (k = 0; k < nr; k++) {
9ae3a8
+            if (bitmap[k]) {
9ae3a8
+                unsigned long temp = leul_to_cpu(bitmap[k]);
9ae3a8
+
9ae3a8
+                ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION][page + k] |= temp;
9ae3a8
+                ram_list.dirty_memory[DIRTY_MEMORY_VGA][page + k] |= temp;
9ae3a8
+                ram_list.dirty_memory[DIRTY_MEMORY_CODE][page + k] |= temp;
9ae3a8
+            }
9ae3a8
+        }
9ae3a8
+        xen_modified_memory(start, pages);
9ae3a8
+    } else {
9ae3a8
+        /*
9ae3a8
+         * bitmap-traveling is faster than memory-traveling (for addr...)
9ae3a8
+         * especially when most of the memory is not dirty.
9ae3a8
+         */
9ae3a8
+        for (i = 0; i < len; i++) {
9ae3a8
+            if (bitmap[i] != 0) {
9ae3a8
+                c = leul_to_cpu(bitmap[i]);
9ae3a8
+                do {
9ae3a8
+                    j = ffsl(c) - 1;
9ae3a8
+                    c &= ~(1ul << j);
9ae3a8
+                    page_number = (i * HOST_LONG_BITS + j) * hpratio;
9ae3a8
+                    addr = page_number * TARGET_PAGE_SIZE;
9ae3a8
+                    ram_addr = start + addr;
9ae3a8
+                    cpu_physical_memory_set_dirty_range(ram_addr,
9ae3a8
+                                       TARGET_PAGE_SIZE * hpratio);
9ae3a8
+                } while (c != 0);
9ae3a8
+            }
9ae3a8
         }
9ae3a8
     }
9ae3a8
 }
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8