dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

Blame 0405-qxl-set-only-off-screen-surfaces-dirty-instead-of-th.patch

Hans de Goede 56753f
From 0386bf2be16745ce87f35ce65153ef4e11f93b22 Mon Sep 17 00:00:00 2001
Hans de Goede 56753f
From: Yonit Halperin <yhalperi@redhat.com>
Hans de Goede 56753f
Date: Wed, 15 Feb 2012 11:22:15 +0200
Hans de Goede 56753f
Subject: [PATCH 405/434] qxl: set only off-screen surfaces dirty instead of
Hans de Goede 56753f
 the whole vram
Hans de Goede 56753f
Hans de Goede 56753f
We used to assure the guest surfaces were saved before migration by
Hans de Goede 56753f
setting the whole vram dirty. This patch sets dirty only the areas
Hans de Goede 56753f
that are actually used in the vram.
Hans de Goede 56753f
Hans de Goede 56753f
Signed-off-by: Yonit Halperin <yhalperi@redhat.com>
Hans de Goede 56753f
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede 56753f
---
Hans de Goede 56753f
 hw/qxl.c |   53 ++++++++++++++++++++++++++++++++++++++++++++---------
Hans de Goede 56753f
 1 file changed, 44 insertions(+), 9 deletions(-)
Hans de Goede 56753f
Hans de Goede 56753f
diff --git a/hw/qxl.c b/hw/qxl.c
Hans de Goede 56753f
index 4fd5e4e..3d9b1b3 100644
Hans de Goede 56753f
--- a/hw/qxl.c
Hans de Goede 56753f
+++ b/hw/qxl.c
Hans de Goede 56753f
@@ -1010,7 +1010,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d)
Hans de Goede 56753f
     qxl_spice_destroy_surfaces(d, QXL_SYNC);
Hans de Goede 56753f
 }
Hans de Goede 56753f
 
Hans de Goede 56753f
-/* called from spice server thread context only */
Hans de Goede 56753f
+/* can be also called from spice server thread context */
Hans de Goede 56753f
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
Hans de Goede 56753f
 {
Hans de Goede 56753f
     uint64_t phys   = le64_to_cpu(pqxl);
Hans de Goede 56753f
@@ -1469,6 +1469,46 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
Hans de Goede 56753f
     }
Hans de Goede 56753f
 }
Hans de Goede 56753f
 
Hans de Goede 56753f
+static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
Hans de Goede 56753f
+{
Hans de Goede 56753f
+    intptr_t vram_start;
Hans de Goede 56753f
+    int i;
Hans de Goede 56753f
+
Hans de Goede 56753f
+    if (qxl->mode != QXL_MODE_NATIVE) {
Hans de Goede 56753f
+        return;
Hans de Goede 56753f
+    }
Hans de Goede 56753f
+
Hans de Goede 56753f
+    /* dirty the primary surface */
Hans de Goede 56753f
+    qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
Hans de Goede 56753f
+                  qxl->shadow_rom.surface0_area_size);
Hans de Goede 56753f
+
Hans de Goede 56753f
+    vram_start =  (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
Hans de Goede 56753f
+
Hans de Goede 56753f
+    /* dirty the off-screen surfaces */
Hans de Goede 56753f
+    for (i = 0; i < NUM_SURFACES; i++) {
Hans de Goede 56753f
+        QXLSurfaceCmd *cmd;
Hans de Goede 56753f
+        intptr_t surface_offset;
Hans de Goede 56753f
+        int surface_size;
Hans de Goede 56753f
+
Hans de Goede 56753f
+        if (qxl->guest_surfaces.cmds[i] == 0) {
Hans de Goede 56753f
+            continue;
Hans de Goede 56753f
+        }
Hans de Goede 56753f
+
Hans de Goede 56753f
+        cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
Hans de Goede 56753f
+                            MEMSLOT_GROUP_GUEST);
Hans de Goede 56753f
+        assert(cmd->type == QXL_SURFACE_CMD_CREATE);
Hans de Goede 56753f
+        surface_offset = (intptr_t)qxl_phys2virt(qxl,
Hans de Goede 56753f
+                                                 cmd->u.surface_create.data,
Hans de Goede 56753f
+                                                 MEMSLOT_GROUP_GUEST);
Hans de Goede 56753f
+        surface_offset -= vram_start;
Hans de Goede 56753f
+        surface_size = cmd->u.surface_create.height *
Hans de Goede 56753f
+                       abs(cmd->u.surface_create.stride);
Hans de Goede 56753f
+        dprint(qxl, 3, "%s: dirty surface %d, offset %d, size %d\n", __func__,
Hans de Goede 56753f
+               i, (int)surface_offset, surface_size);
Hans de Goede 56753f
+        qxl_set_dirty(&qxl->vram_bar, surface_offset, surface_size);
Hans de Goede 56753f
+    }
Hans de Goede 56753f
+}
Hans de Goede 56753f
+
Hans de Goede 56753f
 static void qxl_vm_change_state_handler(void *opaque, int running,
Hans de Goede 56753f
                                         RunState state)
Hans de Goede 56753f
 {
Hans de Goede 56753f
@@ -1482,14 +1522,9 @@ static void qxl_vm_change_state_handler(void *opaque, int running,
Hans de Goede 56753f
          * called
Hans de Goede 56753f
          */
Hans de Goede 56753f
          qxl_update_irq(qxl);
Hans de Goede 56753f
-    } else if (qxl->mode == QXL_MODE_NATIVE) {
Hans de Goede 56753f
-        /* dirty all vram (which holds surfaces) and devram (primary surface)
Hans de Goede 56753f
-         * to make sure they are saved */
Hans de Goede 56753f
-        /* FIXME #1: should go out during "live" stage */
Hans de Goede 56753f
-        /* FIXME #2: we only need to save the areas which are actually used */
Hans de Goede 56753f
-        qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
Hans de Goede 56753f
-        qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
Hans de Goede 56753f
-                      qxl->shadow_rom.surface0_area_size);
Hans de Goede 56753f
+    } else {
Hans de Goede 56753f
+        /* make sure surfaces are saved before migration */
Hans de Goede 56753f
+        qxl_dirty_surfaces(qxl);
Hans de Goede 56753f
     }
Hans de Goede 56753f
 }
Hans de Goede 56753f
 
Hans de Goede 56753f
-- 
Hans de Goede 56753f
1.7.10
Hans de Goede 56753f