From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YbNTO-0006Tm-Rn for qemu-devel@nongnu.org; Fri, 27 Mar 2015 02:10:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YbNTI-0006lb-Jw for qemu-devel@nongnu.org; Fri, 27 Mar 2015 02:10:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42203) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YbNTI-0006lX-Cx for qemu-devel@nongnu.org; Fri, 27 Mar 2015 02:10:20 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2R6AJld011305 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Fri, 27 Mar 2015 02:10:19 -0400 Date: Fri, 27 Mar 2015 14:10:17 +0800 From: Fam Zheng Message-ID: <20150327061017.GB16079@ad.nay.redhat.com> References: <1427391520-29497-1-git-send-email-pbonzini@redhat.com> <1427391520-29497-15-git-send-email-pbonzini@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1427391520-29497-15-git-send-email-pbonzini@redhat.com> Subject: Re: [Qemu-devel] [PATCH 14/22] exec: only check relevant bitmaps for cleanliness List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: qemu-devel@nongnu.org On Thu, 03/26 18:38, Paolo Bonzini wrote: > Most of the time, not all bitmaps have to be marked as dirty; > do not do anything if the interesting ones are already dirty. > Previously, any clean bitmap would have cause all the bitmaps to be > marked dirty. > > In fact, unless running TCG most of the time bitmap operations > are not done at all because memory_region_is_logging returns > zero. In this case, skip cpu_physical_memory_range_includes_clean > as well. > > With this patch, cpu_physical_memory_set_dirty_range is called > unconditionally, so there need not be anymore a separate call to > xen_modified_memory. > > Signed-off-by: Paolo Bonzini > --- > exec.c | 18 +++++++++--------- > include/exec/ram_addr.h | 19 +++++++++++++------ > 2 files changed, 22 insertions(+), 15 deletions(-) > > diff --git a/exec.c b/exec.c > index 94b7644..83c58ff 100644 > --- a/exec.c > +++ b/exec.c > @@ -2236,16 +2236,16 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, > static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr, > hwaddr length) > { > - if (cpu_physical_memory_range_includes_clean(addr, length)) { > - uint8_t dirty_log_mask = memory_region_is_logging(mr); > - if (dirty_log_mask & (1 << DIRTY_MEMORY_CODE)) { > - tb_invalidate_phys_range(addr, addr + length, 0); > - dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); > - } > - cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask); > - } else { > - xen_modified_memory(addr, length); > + uint8_t dirty_log_mask = memory_region_is_logging(mr); > + if (dirty_log_mask && > + !cpu_physical_memory_range_includes_clean(addr, length, dirty_log_mask)) { > + dirty_log_mask = 0; > + } > + if (dirty_log_mask & (1 << DIRTY_MEMORY_CODE)) { > + tb_invalidate_phys_range(addr, addr + length, 0); > + dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); > } > + cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask); > } > > static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) > diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h > index 6c3b74e..b408408 100644 > --- a/include/exec/ram_addr.h > +++ b/include/exec/ram_addr.h > @@ -90,13 +90,20 @@ static inline bool cpu_physical_memory_is_clean(ram_addr_t addr) > } > > static inline bool cpu_physical_memory_range_includes_clean(ram_addr_t start, > - ram_addr_t length) > + ram_addr_t length, > + uint8_t mask) > { > - bool vga = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_VGA); > - bool code = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_CODE); > - bool migration = > - cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_MIGRATION); > - return vga || code || migration; > + bool clean = false; > + if (mask & (1 << DIRTY_MEMORY_VGA)) { > + clean = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_VGA); > + } > + if (!clean && (mask & (1 << DIRTY_MEMORY_CODE))) { > + clean = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_CODE); > + } > + if (!clean && (mask & (1 << DIRTY_MEMORY_MIGRATION))) { > + clean = cpu_physical_memory_get_clean(start, length, DIRTY_MEMORY_MIGRATION); > + } > + return clean; > } Out of curiosity, is it valid that a mask bit is cleared but the corresponding dirty bit is set? > > static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, > -- > 2.3.3 > > >