All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: Glauber Costa <glommer@redhat.com>
Cc: aliguori@us.ibm.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] vga optmization
Date: Wed, 05 Nov 2008 14:42:22 +0000	[thread overview]
Message-ID: <4911B0CE.5070108@eu.citrix.com> (raw)
In-Reply-To: <20081104202846.GB27481@poweredge.glommer>

Glauber Costa wrote:

>> That's also how currently qemu-xen works.
>> I am glad that we agree :)
> 
> I'm attaching a new version. Let me know if it's better this way.
> 



Yes, this is much better thanks.

I still have comments about possible improvements, so I wrote patch
(against your patch).
This patch is not meant to be applied, is only meant to be read (I believe
that C code is more meaningful than English :).

Some of the changes include:

- instead of adding cirrus_lfb_addr, add a more generic lfb_addr to
VGAState, so that can be reused in the future for possible stdvga only
mappings;

- instead of using cirrus_lfb_mapped as a boolean, use it as the
mapping address, it is more useful that way;

- instead of keeping the kvm dirty map always enabled, enable it only
when the framebuffer is linear and in graphical mode;

- look at the changes to vga.c, there is a simple check to reduce the
dirty area to sync.

It would be nice to check if the last two changes are actually a
performance improvement.


diff -r a5bcebe9e2bc hw/cirrus_vga.c
--- a/hw/cirrus_vga.c	Wed Nov 05 12:09:13 2008 +0000
+++ b/hw/cirrus_vga.c	Wed Nov 05 14:29:54 2008 +0000
@@ -249,9 +249,6 @@
     int cirrus_linear_io_addr;
     int cirrus_linear_bitblt_io_addr;
     int cirrus_mmio_io_addr;
-    uint32_t cirrus_lfb_addr;
-    uint32_t cirrus_lfb_end;
-    uint32_t cirrus_lfb_mapped;
     uint32_t cirrus_addr_mask;
     uint32_t linear_mmio_mask;
     uint8_t cirrus_shadow_gr0;
@@ -2655,9 +2652,10 @@
 static void map_linear_vram(CirrusVGAState *s)
 {
 
-    if (!s->cirrus_lfb_mapped && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
-        set_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end, s->vram_offset);
-        s->cirrus_lfb_mapped = 1;
+    if (!s->map_addr && s->lfb_addr && s->lfb_end) {
+        set_vram_mapping(s->lfb_addr, s->lfb_end, s->vram_offset);
+        s->map_addr = s->lfb_addr;
+        s->map_end = s->lfb_end;
     }
     
     if(!(s->cirrus_srcptr != s->cirrus_srcptr_end)
@@ -2674,10 +2672,10 @@
 static void unmap_linear_vram(CirrusVGAState *s)
 {
 
-    if (s->cirrus_lfb_mapped && s->cirrus_lfb_addr && s->cirrus_lfb_end) {
-        unset_vram_mapping(s->cirrus_lfb_addr,
-                           s->cirrus_lfb_end);
-        s->cirrus_lfb_mapped = 0;
+    if (s->map_addr && s->lfb_addr && s->lfb_end) {
+        unset_vram_mapping(s->lfb_addr,
+                           s->lfb_end);
+        s->map_addr = s->map_end = 0;
     }
 
     cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
@@ -3331,9 +3329,9 @@
     cpu_register_physical_memory(addr + 0x1000000, 0x400000,
 				 s->cirrus_linear_bitblt_io_addr);
 
-    s->cirrus_lfb_mapped = 0;
-    s->cirrus_lfb_addr = addr;
-    s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
+    s->map_addr = 0;
+    s->lfb_addr = addr;
+    s->lfb_end = addr + VGA_RAM_SIZE;
 }
 
 static void cirrus_pci_mmio_map(PCIDevice *d, int region_num,
diff -r a5bcebe9e2bc hw/vga.c
--- a/hw/vga.c	Wed Nov 05 12:09:13 2008 +0000
+++ b/hw/vga.c	Wed Nov 05 14:29:54 2008 +0000
@@ -1244,6 +1244,9 @@
     vga_draw_glyph8_func *vga_draw_glyph8;
     vga_draw_glyph9_func *vga_draw_glyph9;
 
+    /* disable dirty bit tracking */
+    // kvm_log_stop();
+
     full_update |= update_palette16(s);
     palette = s->last_palette;
 
@@ -1569,7 +1572,8 @@
     uint32_t v, addr1, addr;
     vga_draw_line_func *vga_draw_line;
 
-    qemu_physical_sync_dirty_bitmap(s->vram_offset, s->vram_offset + VGA_RAM_SIZE);
+    /* Enable dirty bit tracking */
+    // kvm_log_start
 
     full_update |= update_basic_params(s);
 
@@ -1657,6 +1661,31 @@
         s->cursor_invalidate(s);
 
     line_offset = s->line_offset;
+
+    if (s->lfb_addr) {
+        if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3) {
+            /* Tricky things happen, just track all video memory */
+            start = 0;
+            end = s->vram_size;
+        } else {
+            /* Tricky things won't have any effect, i.e. we are in the very simple
+             * (and very usual) case of a linear buffer. */
+            /* use page table dirty bit tracking for the LFB plus border */
+            start = (s->start_addr * 4) & TARGET_PAGE_MASK;
+            end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
+        }
+
+        for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
+            /* We will not read that anyway. */
+            cpu_physical_memory_set_dirty(s->vram_offset + y);
+
+        qemu_physical_sync_dirty_bitmap(s->lfb_addr + y, end);
+
+        for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
+            /* We will not read that anyway. */
+            cpu_physical_memory_set_dirty(s->vram_offset + y);
+    }
+
 #if 0
     printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
            width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);
@@ -1746,6 +1775,10 @@
         return;
     if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
         return;
+
+    /* disable dirty bit tracking */
+    // kvm_log_stop();
+
     if (s->ds->depth == 8)
         val = s->rgb_to_pixel(0, 0, 0);
     else
diff -r a5bcebe9e2bc hw/vga_int.h
--- a/hw/vga_int.h	Wed Nov 05 12:09:13 2008 +0000
+++ b/hw/vga_int.h	Wed Nov 05 14:29:54 2008 +0000
@@ -106,6 +106,10 @@
     unsigned int bios_size;                                             \
     target_phys_addr_t base_ctrl;                                       \
     int it_shift;                                                       \
+    unsigned long lfb_addr;                                             \
+    unsigned long lfb_end;                                              \
+    uint32_t map_addr;                                                  \
+    uint32_t map_end;                                                   \
     PCIDevice *pci_dev;                                                 \
     uint32_t latch;                                                     \
     uint8_t sr_index;                                                   \

  parent reply	other threads:[~2008-11-05 14:39 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-03 17:31 [Qemu-devel] vga optmization Glauber Costa
2008-11-03 17:43 ` Stefano Stabellini
2008-11-03 17:52   ` Glauber Costa
2008-11-03 18:06     ` Stefano Stabellini
2008-11-03 18:03 ` Blue Swirl
2008-11-03 18:14   ` Glauber Costa
2008-11-03 18:41     ` Blue Swirl
2008-11-03 18:47       ` Glauber Costa
2008-11-03 18:13 ` Fabrice Bellard
2008-11-03 18:18   ` Glauber Costa
2008-11-04  7:23 ` Avi Kivity
2008-11-04  9:31 ` andrzej zaborowski
2008-11-04 11:40   ` Stefano Stabellini
2008-11-04 13:43     ` Glauber Costa
2008-11-04 14:51     ` Avi Kivity
2008-11-04 14:52       ` Anthony Liguori
2008-11-04 14:55       ` Glauber Costa
2008-11-04 15:13         ` Stefano Stabellini
2008-11-04 20:42         ` Avi Kivity
2008-11-04 20:51           ` Anthony Liguori
2008-11-04 15:01       ` Stefano Stabellini
2008-11-04 20:28         ` Glauber Costa
2008-11-04 20:40           ` Anthony Liguori
2008-11-05 14:42           ` Stefano Stabellini [this message]
2008-11-07 11:15             ` Glauber Costa
2008-11-07 11:33               ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4911B0CE.5070108@eu.citrix.com \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=aliguori@us.ibm.com \
    --cc=glommer@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.