From nobody Mon Feb 9 14:38:02 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493036799091201.56415160734844; Mon, 24 Apr 2017 05:26:39 -0700 (PDT) Received: from localhost ([::1]:43888 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d2d4f-0005m7-Jc for importer@patchew.org; Mon, 24 Apr 2017 08:26:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42118) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d2cvj-0006ae-Ru for qemu-devel@nongnu.org; Mon, 24 Apr 2017 08:17:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d2cvf-0007Nl-DS for qemu-devel@nongnu.org; Mon, 24 Apr 2017 08:17:23 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44104) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d2cvf-0007MF-4C for qemu-devel@nongnu.org; Mon, 24 Apr 2017 08:17:19 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9E7D280F94 for ; Mon, 24 Apr 2017 12:17:15 +0000 (UTC) Received: from nilsson.home.kraxel.org (ovpn-116-121.ams2.redhat.com [10.36.116.121]) by smtp.corp.redhat.com (Postfix) with ESMTP id 05975B4288; Mon, 24 Apr 2017 12:17:15 +0000 (UTC) Received: by nilsson.home.kraxel.org (Postfix, from userid 500) id 497CE80D5A; Mon, 24 Apr 2017 14:17:10 +0200 (CEST) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9E7D280F94 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=kraxel@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 9E7D280F94 From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Mon, 24 Apr 2017 14:17:02 +0200 Message-Id: <20170424121708.31953-8-kraxel@redhat.com> In-Reply-To: <20170424121708.31953-1-kraxel@redhat.com> References: <20170424121708.31953-1-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 24 Apr 2017 12:17:15 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 07/13] vga: make display updates thread safe. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Gerd Hoffmann Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Message-id: 20170421091632.30900-5-kraxel@redhat.com Signed-off-by: Gerd Hoffmann --- 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 f= ull_update) DisplaySurface *surface =3D 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 =3D 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 f= ull_update) =20 full_update |=3D update_basic_params(s); =20 - if (!full_update) - vga_sync_dirty_bitmap(s); - s->get_resolution(s, &width, &height); disp_width =3D width; =20 @@ -1625,11 +1623,17 @@ static void vga_draw_graphic(VGACommonState *s, int= full_update) addr1 =3D (s->start_addr * 4); bwidth =3D (width * bits + 7) / 8; y_start =3D -1; - page_min =3D -1; - page_max =3D 0; d =3D surface_data(surface); linesize =3D surface_stride(surface); y1 =3D 0; + + if (!full_update) { + vga_sync_dirty_bitmap(s); + snap =3D memory_region_snapshot_and_clear_dirty(&s->vram, addr1, + bwidth * height, + DIRTY_MEMORY_VGA); + } + for(y =3D 0; y < height; y++) { addr =3D addr1; if (!(s->cr[VGA_CRTC_MODE] & 1)) { @@ -1644,17 +1648,17 @@ static void vga_draw_graphic(VGACommonState *s, int= full_update) update =3D full_update; page0 =3D addr; page1 =3D addr + bwidth - 1; - update |=3D memory_region_get_dirty(&s->vram, page0, page1 - page0, - DIRTY_MEMORY_VGA); + if (full_update) { + update =3D 1; + } else { + update =3D memory_region_snapshot_get_dirty(&s->vram, snap, + page0, page1 - page0= ); + } /* explicit invalidation for the hardware cursor (cirrus only) */ update |=3D vga_scanline_invalidated(s, y); if (update) { if (y_start < 0) y_start =3D y; - if (page0 < page_min) - page_min =3D page0; - if (page1 > page_max) - page_max =3D 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 >=3D 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)); } =20 --=20 2.9.3