[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 07/13] vga: make display updates thread safe.
From: |
Gerd Hoffmann |
Subject: |
[Qemu-devel] [PULL 07/13] vga: make display updates thread safe. |
Date: |
Mon, 24 Apr 2017 14:17:02 +0200 |
The vga code clears the dirty bits *after* reading the framebuffer
memory. So if the guest framebuffer updates hits the race window
between vga reading the framebuffer and vga clearing the dirty bits
vga will miss that update
Fix it by using the new memory_region_copy_and_clear_dirty()
memory_region_copy_get_dirty() functions. That way we clear the
dirty bitmap before reading the framebuffer. Any guest display
updates happening in parallel will be properly tracked in the
dirty bitmap then and the next display refresh will pick them up.
Problem triggers with mttcg only. Before mttcg was merged tcg
never ran in parallel to vga emulation. Using kvm will hide the
problem too, due to qemu operating on a userspace copy of the
kernel's dirty bitmap.
Signed-off-by: Gerd Hoffmann <address@hidden>
Message-id: address@hidden
Signed-off-by: Gerd Hoffmann <address@hidden>
---
hw/display/vga.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 3991b88aac..b2516c8d21 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1465,7 +1465,8 @@ static void vga_draw_graphic(VGACommonState *s, int
full_update)
DisplaySurface *surface = qemu_console_surface(s->con);
int y1, y, update, linesize, y_start, double_scan, mask, depth;
int width, height, shift_control, line_offset, bwidth, bits;
- ram_addr_t page0, page1, page_min, page_max;
+ ram_addr_t page0, page1;
+ DirtyBitmapSnapshot *snap = NULL;
int disp_width, multi_scan, multi_run;
uint8_t *d;
uint32_t v, addr1, addr;
@@ -1480,9 +1481,6 @@ static void vga_draw_graphic(VGACommonState *s, int
full_update)
full_update |= update_basic_params(s);
- if (!full_update)
- vga_sync_dirty_bitmap(s);
-
s->get_resolution(s, &width, &height);
disp_width = width;
@@ -1625,11 +1623,17 @@ static void vga_draw_graphic(VGACommonState *s, int
full_update)
addr1 = (s->start_addr * 4);
bwidth = (width * bits + 7) / 8;
y_start = -1;
- page_min = -1;
- page_max = 0;
d = surface_data(surface);
linesize = surface_stride(surface);
y1 = 0;
+
+ if (!full_update) {
+ vga_sync_dirty_bitmap(s);
+ snap = memory_region_snapshot_and_clear_dirty(&s->vram, addr1,
+ bwidth * height,
+ DIRTY_MEMORY_VGA);
+ }
+
for(y = 0; y < height; y++) {
addr = addr1;
if (!(s->cr[VGA_CRTC_MODE] & 1)) {
@@ -1644,17 +1648,17 @@ static void vga_draw_graphic(VGACommonState *s, int
full_update)
update = full_update;
page0 = addr;
page1 = addr + bwidth - 1;
- update |= memory_region_get_dirty(&s->vram, page0, page1 - page0,
- DIRTY_MEMORY_VGA);
+ if (full_update) {
+ update = 1;
+ } else {
+ update = memory_region_snapshot_get_dirty(&s->vram, snap,
+ page0, page1 - page0);
+ }
/* explicit invalidation for the hardware cursor (cirrus only) */
update |= vga_scanline_invalidated(s, y);
if (update) {
if (y_start < 0)
y_start = y;
- if (page0 < page_min)
- page_min = page0;
- if (page1 > page_max)
- page_max = page1;
if (!(is_buffer_shared(surface))) {
vga_draw_line(s, d, s->vram_ptr + addr, width);
if (s->cursor_draw_line)
@@ -1687,13 +1691,7 @@ static void vga_draw_graphic(VGACommonState *s, int
full_update)
dpy_gfx_update(s->con, 0, y_start,
disp_width, y - y_start);
}
- /* reset modified pages */
- if (page_max >= page_min) {
- memory_region_reset_dirty(&s->vram,
- page_min,
- page_max - page_min,
- DIRTY_MEMORY_VGA);
- }
+ g_free(snap);
memset(s->invalidated_y_table, 0, sizeof(s->invalidated_y_table));
}
--
2.9.3
- [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition, (continued)
- [Qemu-devel] [PULL 01/13] console: add same surface replace pre-condition, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 03/13] virtio-gpu: replace PIXMAN_* by PIXMAN_BE_*, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 12/13] qxl: add xres and yres properties, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 06/13] vga: add vga_scanline_invalidated helper, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 13/13] virtio-gpu: add xres and yres properties, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 10/13] g364fb: make display updates thread safe, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 08/13] framebuffer: make display updates thread safe, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 04/13] bitmap: add bitmap_copy_and_clear_atomic, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 02/13] console: add same displaychangelistener registration pre-condition, Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 05/13] memory: add support getting and using a dirty bitmap copy., Gerd Hoffmann, 2017/04/24
- [Qemu-devel] [PULL 07/13] vga: make display updates thread safe.,
Gerd Hoffmann <=
- [Qemu-devel] [PULL 09/13] exynos: make display updates thread safe, Gerd Hoffmann, 2017/04/24
- Re: [Qemu-devel] [PULL 00/13] vga patch queue, Peter Maydell, 2017/04/24