From patchwork Sun Oct 16 16:50:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Blue Swirl X-Patchwork-Id: 120045 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 1A589B70FF for ; Mon, 17 Oct 2011 03:51:34 +1100 (EST) Received: from localhost ([::1]:53894 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RFTvl-0002Al-Qy for incoming@patchwork.ozlabs.org; Sun, 16 Oct 2011 12:51:21 -0400 Received: from eggs.gnu.org ([140.186.70.92]:47613) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RFTvc-0002AR-EK for qemu-devel@nongnu.org; Sun, 16 Oct 2011 12:51:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RFTvZ-0004bV-TJ for qemu-devel@nongnu.org; Sun, 16 Oct 2011 12:51:12 -0400 Received: from mail-gx0-f173.google.com ([209.85.161.173]:50781) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RFTvZ-0004bQ-LM for qemu-devel@nongnu.org; Sun, 16 Oct 2011 12:51:09 -0400 Received: by ggnr5 with SMTP id r5so2919459ggn.4 for ; Sun, 16 Oct 2011 09:51:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; bh=9aGrhhpBSaUrj+1CKk60tRF6ig8ZP3x4MkTmwFtTXgI=; b=L53zMSXxLdLyiiUx6YRdZhhBdUWHhnRV7fDgxP4yNapmLoG/jDJD3/dpCP1Bl/wu35 9iMt3OhUtNJSWNzZYy5kZlog1/beZNvrbSkjLc/Yn0yTSBdYtTld6sIKGodQS2YBceAY 7GDo1d1GHBbcebVZ0nvbx0lsimPjmBy3fA11s= Received: by 10.182.8.10 with SMTP id n10mr8829587oba.36.1318783869107; Sun, 16 Oct 2011 09:51:09 -0700 (PDT) MIME-Version: 1.0 Received: by 10.182.121.8 with HTTP; Sun, 16 Oct 2011 09:50:49 -0700 (PDT) From: Blue Swirl Date: Sun, 16 Oct 2011 16:50:49 +0000 Message-ID: To: Avi Kivity , qemu-devel X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.161.173 Subject: [Qemu-devel] [PATCH v2 3/4] memory: change dirtying APIs to take a size X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Instead of each target knowing or guessing the guest page size, just pass the desired size of dirtied memory area. This should also improve performance due to memset() optimizations. Signed-off-by: Blue Swirl --- arch_init.c | 3 ++- cpu-all.h | 9 +++++++-- hw/cirrus_vga.c | 18 ++++++++---------- hw/g364fb.c | 11 +++-------- hw/qxl.c | 5 +---- hw/tcx.c | 14 +++----------- hw/vga.c | 6 +++--- hw/vhost.c | 2 +- kvm-all.c | 8 +++++--- memory.c | 5 +++-- memory.h | 6 ++++-- xen-all.c | 4 +++- 12 files changed, 43 insertions(+), 48 deletions(-) From a8ae486bb6c00ddd7d7d51329e9810829f23c0bf Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Blue Swirl Date: Sun, 16 Oct 2011 16:04:59 +0000 Subject: [PATCH 3/4] memory: change dirtying APIs to take a size Instead of each target knowing or guessing the guest page size, just pass the desired size of dirtied memory area. This should also improve performance due to memset() optimizations. Signed-off-by: Blue Swirl --- arch_init.c | 3 ++- cpu-all.h | 9 +++++++-- hw/cirrus_vga.c | 18 ++++++++---------- hw/g364fb.c | 11 +++-------- hw/qxl.c | 5 +---- hw/tcx.c | 14 +++----------- hw/vga.c | 6 +++--- hw/vhost.c | 2 +- kvm-all.c | 8 +++++--- memory.c | 5 +++-- memory.h | 6 ++++-- xen-all.c | 4 +++- 12 files changed, 43 insertions(+), 48 deletions(-) diff --git a/arch_init.c b/arch_init.c index a6c69c7..8b3b414 100644 --- a/arch_init.c +++ b/arch_init.c @@ -280,7 +280,8 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) addr += TARGET_PAGE_SIZE) { if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) { - cpu_physical_memory_set_dirty(addr); + cpu_physical_memory_range_set_dirty(addr, + TARGET_PAGE_SIZE); } } } diff --git a/cpu-all.h b/cpu-all.h index 42a5fa0..4ed84a1 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -533,9 +533,14 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags; } -static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) +static inline void cpu_physical_memory_range_set_dirty(ram_addr_t start, + ram_addr_t size) { - ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff; + start >>= TARGET_PAGE_BITS; + size = (size | (TARGET_PAGE_SIZE - 1)) + 1; + size >>= TARGET_PAGE_BITS; + + memset(&ram_list.phys_dirty[start], 0xff, size); } static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr, diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index aa8a0e6..846c8f5 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -619,10 +619,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, off_cur = off_begin; off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; off_cur &= TARGET_PAGE_MASK; - while (off_cur < off_cur_end) { - memory_region_set_dirty(&s->vga.vram, off_cur); - off_cur += TARGET_PAGE_SIZE; - } + memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); off_begin += off_pitch; } } @@ -1923,8 +1920,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, val <<= 1; dst++; } - memory_region_set_dirty(&s->vga.vram, offset); - memory_region_set_dirty(&s->vga.vram, offset + 7); + memory_region_set_dirty(&s->vga.vram, offset, 1); + memory_region_set_dirty(&s->vga.vram, offset + 7, 1); } static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, @@ -1948,8 +1945,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, val <<= 1; dst += 2; } - memory_region_set_dirty(&s->vga.vram, offset); - memory_region_set_dirty(&s->vga.vram, offset + 15); + memory_region_set_dirty(&s->vga.vram, offset, 1); + memory_region_set_dirty(&s->vga.vram, offset + 15, 1); } /*************************************** @@ -2039,7 +2036,8 @@ static void cirrus_vga_mem_write(void *opaque, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + bank_offset) = mem_value; - memory_region_set_dirty(&s->vga.vram, bank_offset); + memory_region_set_dirty(&s->vga.vram, bank_offset, + sizeof(mem_value)); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, @@ -2311,7 +2309,7 @@ static void cirrus_linear_write(void *opaque, target_phys_addr_t addr, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + addr) = (uint8_t) val; - memory_region_set_dirty(&s->vga.vram, addr); + memory_region_set_dirty(&s->vga.vram, addr, 1); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val); diff --git a/hw/g364fb.c b/hw/g364fb.c index f00ee27..166839b 100644 --- a/hw/g364fb.c +++ b/hw/g364fb.c @@ -268,12 +268,9 @@ static void g364fb_update_display(void *opaque) static inline void g364fb_invalidate_display(void *opaque) { G364State *s = opaque; - int i; s->blanked = 0; - for (i = 0; i < s->vram_size; i += G364_PAGE_SIZE) { - memory_region_set_dirty(&s->mem_vram, i); - } + memory_region_set_dirty(&s->mem_vram, 0, s->vram_size); } static void g364fb_reset(G364State *s) @@ -385,7 +382,7 @@ static void g364fb_update_depth(G364State *s) static void g364_invalidate_cursor_position(G364State *s) { - int ymin, ymax, start, end, i; + int ymin, ymax, start, end; /* invalidate only near the cursor */ ymin = s->cursor_position & 0xfff; @@ -393,9 +390,7 @@ static void g364_invalidate_cursor_position(G364State *s) start = ymin * ds_get_linesize(s->ds); end = (ymax + 1) * ds_get_linesize(s->ds); - for (i = start; i < end; i += G364_PAGE_SIZE) { - memory_region_set_dirty(&s->mem_vram, i); - } + memory_region_set_dirty(&s->mem_vram, start, end - start); } static void g364fb_ctrl_write(void *opaque, diff --git a/hw/qxl.c b/hw/qxl.c index 03848ed..b1e0d80 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -341,10 +341,7 @@ static void init_qxl_ram(PCIQXLDevice *d) /* can be called from spice server thread context */ static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end) { - while (addr < end) { - memory_region_set_dirty(mr, addr); - addr += TARGET_PAGE_SIZE; - } + memory_region_set_dirty(mr, addr, end - addr); } static void qxl_rom_set_dirty(PCIQXLDevice *qxl) diff --git a/hw/tcx.c b/hw/tcx.c index 309600d..e48c564 100644 --- a/hw/tcx.c +++ b/hw/tcx.c @@ -53,21 +53,13 @@ static void tcx24_screen_dump(void *opaque, const char *filename); static void tcx_set_dirty(TCXState *s) { - unsigned int i; - - for (i = 0; i < MAXX * MAXY; i += TARGET_PAGE_SIZE) { - cpu_physical_memory_set_dirty(s->vram_offset + i); - } + cpu_physical_memory_range_set_dirty(s->vram_offset, MAXX * MAXY); } static void tcx24_set_dirty(TCXState *s) { - unsigned int i; - - for (i = 0; i < MAXX * MAXY * 4; i += TARGET_PAGE_SIZE) { - cpu_physical_memory_set_dirty(s->vram24_offset + i); - cpu_physical_memory_set_dirty(s->cplane_offset + i); - } + cpu_physical_memory_range_set_dirty(s->vram24_offset, MAXX * MAXY * 4); + cpu_physical_memory_range_set_dirty(s->cplane_offset, MAXX * MAXY * 4); } static void update_palette_entries(TCXState *s, int start, int end) diff --git a/hw/vga.c b/hw/vga.c index ca79aa1..85176a6 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -853,7 +853,7 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val) printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr); #endif s->plane_updated |= mask; /* only used to detect font change */ - memory_region_set_dirty(&s->vram, addr); + memory_region_set_dirty(&s->vram, addr, 1); } } else if (s->gr[5] & 0x10) { /* odd/even mode (aka text mode mapping) */ @@ -866,7 +866,7 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val) printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr); #endif s->plane_updated |= mask; /* only used to detect font change */ - memory_region_set_dirty(&s->vram, addr); + memory_region_set_dirty(&s->vram, addr, 1); } } else { /* standard VGA latched access */ @@ -940,7 +940,7 @@ void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val) printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n", addr * 4, write_mask, val); #endif - memory_region_set_dirty(&s->vram, addr << 2); + memory_region_set_dirty(&s->vram, addr << 2, sizeof(uint32_t)); } } diff --git a/hw/vhost.c b/hw/vhost.c index 0870cb7..d96b186 100644 --- a/hw/vhost.c +++ b/hw/vhost.c @@ -50,7 +50,7 @@ static void vhost_dev_sync_region(struct vhost_dev *dev, ram_addr_t ram_addr; bit -= 1; ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE); - cpu_physical_memory_set_dirty(ram_addr); + cpu_physical_memory_range_set_dirty(ram_addr, VHOST_LOG_CHUNK); log &= ~(0x1ull << bit); } addr += VHOST_LOG_CHUNK; diff --git a/kvm-all.c b/kvm-all.c index e7faf5c..104b0d7 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -352,7 +352,8 @@ static int kvm_get_dirty_pages_log_range(unsigned long start_addr, addr1 = page_number * TARGET_PAGE_SIZE; addr = offset + addr1; ram_addr = cpu_get_physical_page_desc(addr); - cpu_physical_memory_set_dirty(ram_addr); + cpu_physical_memory_range_set_dirty(ram_addr, + TARGET_PAGE_SIZE); } while (c != 0); } } @@ -363,8 +364,9 @@ static int kvm_get_dirty_pages_log_range(unsigned long start_addr, /** * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space - * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty(). - * This means all bits are set to dirty. + * This function updates qemu's dirty bitmap using + * cpu_physical_memory_range_set_dirty(). This means all bits are set + * to dirty. * * @start_add: start of logged region. * @end_addr: end of logged region. diff --git a/memory.c b/memory.c index dc5e35d..37a282b 100644 --- a/memory.c +++ b/memory.c @@ -1037,10 +1037,11 @@ bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client); } -void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr) +void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr, + target_phys_addr_t size) { assert(mr->terminates); - return cpu_physical_memory_set_dirty(mr->ram_addr + addr); + return cpu_physical_memory_range_set_dirty(mr->ram_addr + addr, size); } void memory_region_sync_dirty_bitmap(MemoryRegion *mr) diff --git a/memory.h b/memory.h index d5b47da..fcd15b3 100644 --- a/memory.h +++ b/memory.h @@ -310,10 +310,12 @@ bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, * * Marks a page as dirty, after it has been dirtied outside guest code. * - * @mr: the memory region being queried. + * @mr: the memory region being dirtied. * @addr: the address (relative to the start of the region) being dirtied. + * @size: size of the range being dirtied. */ -void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr); +void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr, + target_phys_addr_t size); /** * memory_region_sync_dirty_bitmap: Synchronize a region's dirty bitmap with diff --git a/xen-all.c b/xen-all.c index b5e28ab..c07494b 100644 --- a/xen-all.c +++ b/xen-all.c @@ -422,7 +422,9 @@ static int xen_sync_dirty_bitmap(XenIOState *state, while (map != 0) { j = ffsl(map) - 1; map &= ~(1ul << j); - cpu_physical_memory_set_dirty(vram_offset + (i * width + j) * TARGET_PAGE_SIZE); + cpu_physical_memory_range_set_dirty(vram_offset + (i * width + j) * + TARGET_PAGE_SIZE, + TARGET_PAGE_SIZE); }; } -- 1.7.2.5