From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:41982) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rv2AT-0000wZ-Av for qemu-devel@nongnu.org; Wed, 08 Feb 2012 02:42:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rv2AO-0006Qd-Ep for qemu-devel@nongnu.org; Wed, 08 Feb 2012 02:42:17 -0500 Received: from fmmailgate02.web.de ([217.72.192.227]:51872) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rv2AO-0006QW-1U for qemu-devel@nongnu.org; Wed, 08 Feb 2012 02:42:12 -0500 Received: from moweb001.kundenserver.de (moweb001.kundenserver.de [172.19.20.114]) by fmmailgate02.web.de (Postfix) with ESMTP id 2522C1C0B285B for ; Wed, 8 Feb 2012 08:42:10 +0100 (CET) Message-ID: <4F32274A.9070401@web.de> Date: Wed, 08 Feb 2012 08:42:02 +0100 From: Jan Kiszka MIME-Version: 1.0 References: <4F322204.20001@samsung.com> In-Reply-To: <4F322204.20001@samsung.com> Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig2A0040D9363F7BEFB1B6F7A6" Subject: Re: [Qemu-devel] [PATCH 1/6] memory: change dirty getting API to take a size List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Evgeny Voevodin Cc: Blue Swirl , qemu-devel , Dmitry Solodkiy , Avi Kivity This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig2A0040D9363F7BEFB1B6F7A6 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On 2012-02-08 08:19, Evgeny Voevodin wrote: > On 01/29/2012 11:13 PM, Blue Swirl wrote: >> Instead of each device knowing or guessing the guest page size, >> just pass the desired size of dirtied memory area. >> >> Signed-off-by: Blue Swirl >> --- >> arch_init.c | 7 ++++--- >> exec-obsolete.h | 15 +++++++++++++-- >> hw/framebuffer.c | 9 +-------- >> hw/g364fb.c | 3 ++- >> hw/sm501.c | 11 ++++------- >> hw/tcx.c | 19 +++++++++---------- >> hw/vga.c | 17 +++++------------ >> memory.c | 5 +++-- >> memory.h | 9 +++++---- >> 9 files changed, 46 insertions(+), 49 deletions(-) >> >> diff --git a/arch_init.c b/arch_init.c >> index 2366511..699bdd1 100644 >> --- a/arch_init.c >> +++ b/arch_init.c >> @@ -141,7 +141,8 @@ static int ram_save_block(QEMUFile *f) >> >> do { >> mr =3D block->mr; >> - if (memory_region_get_dirty(mr, offset, >> DIRTY_MEMORY_MIGRATION)) { >> + if (memory_region_get_dirty(mr, offset, TARGET_PAGE_SIZE, >> + DIRTY_MEMORY_MIGRATION)) { >> uint8_t *p; >> int cont =3D (block =3D=3D last_block) ? >> RAM_SAVE_FLAG_CONTINUE : 0; >> >> @@ -198,7 +199,7 @@ static ram_addr_t ram_save_remaining(void) >> QLIST_FOREACH(block,&ram_list.blocks, next) { >> ram_addr_t addr; >> for (addr =3D 0; addr< block->length; addr +=3D >> TARGET_PAGE_SIZE) { >> - if (memory_region_get_dirty(block->mr, addr, >> + if (memory_region_get_dirty(block->mr, addr, >> TARGET_PAGE_SIZE, >> DIRTY_MEMORY_MIGRATION)) { >> count++; >> } >> @@ -283,7 +284,7 @@ int ram_save_live(Monitor *mon, QEMUFile *f, int >> stage, void *opaque) >> /* Make sure all dirty bits are set */ >> QLIST_FOREACH(block,&ram_list.blocks, next) { >> for (addr =3D 0; addr< block->length; addr +=3D >> TARGET_PAGE_SIZE) { >> - if (!memory_region_get_dirty(block->mr, addr, >> + if (!memory_region_get_dirty(block->mr, addr, >> TARGET_PAGE_SIZE, >> DIRTY_MEMORY_MIGRATION)= ) { >> memory_region_set_dirty(block->mr, addr, >> TARGET_PAGE_SIZE); >> } >> diff --git a/exec-obsolete.h b/exec-obsolete.h >> index d2749d3..94c23d0 100644 >> --- a/exec-obsolete.h >> +++ b/exec-obsolete.h >> @@ -59,10 +59,21 @@ static inline int >> cpu_physical_memory_get_dirty_flags(ram_addr_t addr) >> return ram_list.phys_dirty[addr>> TARGET_PAGE_BITS]; >> } >> >> -static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, >> +static inline int cpu_physical_memory_get_dirty(ram_addr_t start, >> + ram_addr_t length, >> int dirty_flags) >> { >> - return ram_list.phys_dirty[addr>> TARGET_PAGE_BITS]& dirty_flag= s; >> + int ret =3D 0; >> + uint8_t *p; >> + ram_addr_t addr, end; >> + >> + end =3D TARGET_PAGE_ALIGN(start + length); >> + start&=3D TARGET_PAGE_MASK; >> + p =3D ram_list.phys_dirty + (start>> TARGET_PAGE_BITS); >> + for (addr =3D start; addr< end; addr +=3D TARGET_PAGE_SIZE) { >> + ret |=3D *p++& dirty_flags; >> + } >> + return ret; >> } >> >> static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) >> diff --git a/hw/framebuffer.c b/hw/framebuffer.c >> index 6bf48dc..ea122fb 100644 >> --- a/hw/framebuffer.c >> +++ b/hw/framebuffer.c >> @@ -87,15 +87,8 @@ void framebuffer_update_display( >> dest +=3D i * dest_row_pitch; >> >> for (; i< rows; i++) { >> - target_phys_addr_t dirty_offset; >> - dirty =3D 0; >> - dirty_offset =3D 0; >> - while (addr + dirty_offset< TARGET_PAGE_ALIGN(addr + >> src_width)) { >> - dirty |=3D memory_region_get_dirty(mem, addr + dirty_offs= et, >> + dirty =3D memory_region_get_dirty(mem, addr, addr + src_width= , >> DIRTY_MEMORY_VGA); >> - dirty_offset +=3D TARGET_PAGE_SIZE; >> - } >> - >> if (dirty || invalidate) { >> fn(opaque, dest, src, cols, dest_col_pitch); >> if (first =3D=3D -1) >> diff --git a/hw/g364fb.c b/hw/g364fb.c >> index 82b31f7..fa25033 100644 >> --- a/hw/g364fb.c >> +++ b/hw/g364fb.c >> @@ -62,7 +62,8 @@ typedef struct G364State { >> >> static inline int check_dirty(G364State *s, ram_addr_t page) >> { >> - return memory_region_get_dirty(&s->mem_vram, page, >> DIRTY_MEMORY_VGA); >> + return memory_region_get_dirty(&s->mem_vram, page, G364_PAGE_SIZE= , >> + DIRTY_MEMORY_VGA); >> } >> >> static inline void reset_dirty(G364State *s, >> diff --git a/hw/sm501.c b/hw/sm501.c >> index 09c5894..94c0abf 100644 >> --- a/hw/sm501.c >> +++ b/hw/sm501.c >> @@ -1323,15 +1323,12 @@ static void sm501_draw_crt(SM501State * s) >> for (y =3D 0; y< height; y++) { >> int update_hwc =3D draw_hwc_line ? within_hwc_y_range(s, y, 1) := 0; >> int update =3D full_update || update_hwc; >> - ram_addr_t page0 =3D offset& TARGET_PAGE_MASK; >> - ram_addr_t page1 =3D (offset + width * src_bpp - 1)&=20 >> TARGET_PAGE_MASK; >> - ram_addr_t page; >> + ram_addr_t page0 =3D offset; >> + ram_addr_t page1 =3D offset + width * src_bpp - 1; >> >> /* check dirty flags for each line */ >> - for (page =3D page0; page<=3D page1; page +=3D TARGET_PAGE_SIZE) >> - if (memory_region_get_dirty(&s->local_mem_region, page, >> - DIRTY_MEMORY_VGA)) >> - update =3D 1; >> + update =3D memory_region_get_dirty(&s->local_mem_region, page= 0, >> page1, >> + DIRTY_MEMORY_VGA); >> >> /* draw line and change status */ >> if (update) { >> diff --git a/hw/tcx.c b/hw/tcx.c >> index 7743c05..6054779 100644 >> --- a/hw/tcx.c >> +++ b/hw/tcx.c >> @@ -178,15 +178,13 @@ static inline int check_dirty(TCXState *s, >> ram_addr_t page, ram_addr_t page24, >> ram_addr_t cpage) >> { >> int ret; >> - unsigned int off; >> - >> - ret =3D memory_region_get_dirty(&s->vram_mem, page, DIRTY_MEMORY_= VGA); >> - for (off =3D 0; off< TARGET_PAGE_SIZE * 4; off +=3D TARGET_PAGE_= SIZE) { >> - ret |=3D memory_region_get_dirty(&s->vram_mem, page24 + off, >> - DIRTY_MEMORY_VGA); >> - ret |=3D memory_region_get_dirty(&s->vram_mem, cpage + off, >> - DIRTY_MEMORY_VGA); >> - } >> + >> + ret =3D memory_region_get_dirty(&s->vram_mem, page, TARGET_PAGE_S= IZE, >> + DIRTY_MEMORY_VGA); >> + ret |=3D memory_region_get_dirty(&s->vram_mem, page24, >> TARGET_PAGE_SIZE * 4, >> + DIRTY_MEMORY_VGA); >> + ret |=3D memory_region_get_dirty(&s->vram_mem, cpage, >> TARGET_PAGE_SIZE * 4, >> + DIRTY_MEMORY_VGA); >> return ret; >> } >> >> @@ -245,7 +243,8 @@ static void tcx_update_display(void *opaque) >> } >> >> for(y =3D 0; y< ts->height; y +=3D 4, page +=3D TARGET_PAGE_SIZ= E) { >> - if (memory_region_get_dirty(&ts->vram_mem, page, >> DIRTY_MEMORY_VGA)) { >> + if (memory_region_get_dirty(&ts->vram_mem, page, >> TARGET_PAGE_SIZE, >> + DIRTY_MEMORY_VGA)) { >> if (y_start< 0) >> y_start =3D y; >> if (page< page_min) >> diff --git a/hw/vga.c b/hw/vga.c >> index 4dc2610..cf9b39f 100644 >> --- a/hw/vga.c >> +++ b/hw/vga.c >> @@ -1742,17 +1742,10 @@ static void vga_draw_graphic(VGACommonState >> *s, int full_update) >> if (!(s->cr[0x17]& 2)) { >> addr =3D (addr& ~0x8000) | ((y1& 2)<< 14); >> } >> - page0 =3D addr& TARGET_PAGE_MASK; >> - page1 =3D (addr + bwidth - 1)& TARGET_PAGE_MASK; >> - update =3D full_update | >> - memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA= ) | >> - memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA= ); >> - if ((page1 - page0)> TARGET_PAGE_SIZE) { >> - /* if wide line, can use another page */ >> - update |=3D memory_region_get_dirty(&s->vram, >> - page0 + TARGET_PAGE_SIZ= E, >> - DIRTY_MEMORY_VGA); >> - } >> + page0 =3D addr; >> + page1 =3D addr + bwidth - 1; >> + update =3D memory_region_get_dirty(&s->vram, page0, page1, >> + DIRTY_MEMORY_VGA); >> /* explicit invalidation for the hardware cursor */ >> update |=3D (s->invalidated_y_table[y>> 5]>> (y& 0x1f))& = 1; >> if (update) { >> @@ -1798,7 +1791,7 @@ static void vga_draw_graphic(VGACommonState *s, >> int full_update) >> if (page_max>=3D page_min) { >> memory_region_reset_dirty(&s->vram, >> page_min, >> - page_max + TARGET_PAGE_SIZE - >> page_min, >> + page_max - page_min, >> DIRTY_MEMORY_VGA); >> } >> memset(s->invalidated_y_table, 0, ((height + 31)>> 5) * 4); >> diff --git a/memory.c b/memory.c >> index ee4c98a..5e77d8a 100644 >> --- a/memory.c >> +++ b/memory.c >> @@ -1136,10 +1136,11 @@ void memory_region_set_log(MemoryRegion *mr, >> bool log, unsigned client) >> } >> >> bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t ad= dr, >> - unsigned client) >> + target_phys_addr_t size, unsigned client= ) >> { >> assert(mr->terminates); >> - return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1<<=20 >> client); >> + return cpu_physical_memory_get_dirty(mr->ram_addr + addr, size, >> + 1<< client); >> } >> >> void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t ad= dr, >> diff --git a/memory.h b/memory.h >> index fa45b99..4cf8d2f 100644 >> --- a/memory.h >> +++ b/memory.h >> @@ -380,20 +380,21 @@ void memory_region_set_offset(MemoryRegion *mr, >> target_phys_addr_t offset); >> void memory_region_set_log(MemoryRegion *mr, bool log, unsigned >> client); >> >> /** >> - * memory_region_get_dirty: Check whether a page is dirty for a >> specified >> - * client. >> + * memory_region_get_dirty: Check whether a range of bytes is dirty >> + * for a specified client. >> * >> - * Checks whether a page has been written to since the last >> + * Checks whether a range of bytes has been written to since the last= >> * call to memory_region_reset_dirty() with the same @client. Dirty= >> logging >> * must be enabled. >> * >> * @mr: the memory region being queried. >> * @addr: the address (relative to the start of the region) being >> queried. >> + * @size: the size of the range being queried. >> * @client: the user of the logging information; >> %DIRTY_MEMORY_MIGRATION or >> * %DIRTY_MEMORY_VGA. >> */ >> bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t ad= dr, >> - unsigned client); >> + target_phys_addr_t size, unsigned client= ); >> >> /** >> * memory_region_set_dirty: Mark a range of bytes as dirty in a >> memory region. >=20 > Since this patch was applied to master, my realview-pbx board emulation= > with graphics support started to work about 10 times slower (or even > more, didn't make measures, but I can see it with the naked eye). This > happens as soon as Linux kernel found an XVGA display and started to us= e > frame buffer. >=20 Do [1] or [2] make a difference? Jan [1] http://thread.gmane.org/gmane.comp.emulators.qemu/134958 [2] http://thread.gmane.org/gmane.comp.emulators.qemu/135244 --------------enig2A0040D9363F7BEFB1B6F7A6 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.16 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk8yJ00ACgkQitSsb3rl5xRxHwCdH84u6a3fBNq4xFcvdFS/QjI8 mvEAoN+5VO3PBHwLpJI+3xsHGfvePPEt =5ibL -----END PGP SIGNATURE----- --------------enig2A0040D9363F7BEFB1B6F7A6--