From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40291) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YbBkL-0005ab-Ad for qemu-devel@nongnu.org; Thu, 26 Mar 2015 13:39:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YbBkK-0003cC-2R for qemu-devel@nongnu.org; Thu, 26 Mar 2015 13:39:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38198) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YbBkJ-0003c6-Qn for qemu-devel@nongnu.org; Thu, 26 Mar 2015 13:39:07 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 78908293205 for ; Thu, 26 Mar 2015 17:39:07 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-86.ams2.redhat.com [10.36.112.86]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2QHcflJ025898 for ; Thu, 26 Mar 2015 13:39:06 -0400 From: Paolo Bonzini Date: Thu, 26 Mar 2015 18:38:31 +0100 Message-Id: <1427391520-29497-14-git-send-email-pbonzini@redhat.com> In-Reply-To: <1427391520-29497-1-git-send-email-pbonzini@redhat.com> References: <1427391520-29497-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 13/22] exec: pass client mask to cpu_physical_memory_set_dirty_range List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This cuts in half the cost of bitmap operations (which will become more expensive when made atomic) during migration on non-VRAM regions. Signed-off-by: Paolo Bonzini --- exec.c | 23 +++++++++++++---------- include/exec/ram_addr.h | 33 ++++++++++++++++----------------- memory.c | 3 ++- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/exec.c b/exec.c index ab2468b..94b7644 100644 --- a/exec.c +++ b/exec.c @@ -1356,7 +1356,8 @@ int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp) cpu_physical_memory_clear_dirty_range(block->offset, block->used_length); block->used_length = newsize; - cpu_physical_memory_set_dirty_range(block->offset, block->used_length); + cpu_physical_memory_set_dirty_range(block->offset, block->used_length, + DIRTY_CLIENT_ALL); memory_region_set_size(block->mr, newsize); if (block->resized) { block->resized(block->idstr, newsize, block->host); @@ -1430,7 +1431,8 @@ static ram_addr_t ram_block_add(RAMBlock *new_block, Error **errp) } } cpu_physical_memory_set_dirty_range(new_block->offset, - new_block->used_length); + new_block->used_length, + DIRTY_CLIENT_ALL); if (new_block->host) { qemu_ram_setup_dump(new_block->host, new_block->max_length); @@ -1820,7 +1822,12 @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr, default: abort(); } - cpu_physical_memory_set_dirty_range_nocode(ram_addr, size); + + /* Set both VGA and migration bits for simplicity and to remove + * the notdirty callback faster. + */ + cpu_physical_memory_set_dirty_range(ram_addr, size, + DIRTY_CLIENT_NOCODE); tlb_set_dirty(env, current_cpu->mem_io_vaddr); } @@ -2230,14 +2237,12 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr length) { if (cpu_physical_memory_range_includes_clean(addr, length)) { - dirty_log_mask = memory_region_is_logging(mr); + 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); } - if (dirty_log_mask) { - cpu_physical_memory_set_dirty_range_nocode(addr, length); - } + cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask); } else { xen_modified_memory(addr, length); } @@ -2865,9 +2870,7 @@ void stl_phys_notdirty(AddressSpace *as, hwaddr addr, uint32_t val) tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); } - if (dirty_log_mask) { - cpu_physical_memory_set_dirty_range_nocode(addr1, 4); - } + cpu_physical_memory_set_dirty_range(addr1, 4, dirty_log_mask); } } diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 7f6e928..6c3b74e 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -41,6 +41,9 @@ void qemu_ram_free_from_ptr(ram_addr_t addr); int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp); +#define DIRTY_CLIENT_ALL ((1 << DIRTY_MEMORY_NUM) - 1) +#define DIRTY_CLIENT_NOCODE (DIRTY_CLIENT_ALL & ~ (1 << DIRTY_MEMORY_CODE)) + static inline bool cpu_physical_memory_get_dirty(ram_addr_t start, ram_addr_t length, unsigned client) @@ -103,28 +106,23 @@ static inline void cpu_physical_memory_set_dirty_flag(ram_addr_t addr, set_bit(addr >> TARGET_PAGE_BITS, ram_list.dirty_memory[client]); } -static inline void cpu_physical_memory_set_dirty_range_nocode(ram_addr_t start, - ram_addr_t length) -{ - unsigned long end, page; - - end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS; - page = start >> TARGET_PAGE_BITS; - bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page); - bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page); - xen_modified_memory(start, length); -} - static inline void cpu_physical_memory_set_dirty_range(ram_addr_t start, - ram_addr_t length) + ram_addr_t length, + uint8_t mask) { unsigned long end, page; end = TARGET_PAGE_ALIGN(start + length) >> TARGET_PAGE_BITS; page = start >> TARGET_PAGE_BITS; - bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page); - bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page); - bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page); + if (likely(mask & DIRTY_MEMORY_MIGRATION)) { + bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_MIGRATION], page, end - page); + } + if (unlikely(mask & DIRTY_MEMORY_VGA)) { + bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_VGA], page, end - page); + } + if (unlikely(mask & DIRTY_MEMORY_CODE)) { + bitmap_set(ram_list.dirty_memory[DIRTY_MEMORY_CODE], page, end - page); + } xen_modified_memory(start, length); } @@ -172,7 +170,8 @@ static inline void cpu_physical_memory_set_dirty_lebitmap(unsigned long *bitmap, addr = page_number * TARGET_PAGE_SIZE; ram_addr = start + addr; cpu_physical_memory_set_dirty_range(ram_addr, - TARGET_PAGE_SIZE * hpratio); + TARGET_PAGE_SIZE * hpratio, + DIRTY_CLIENT_ALL); } while (c != 0); } } diff --git a/memory.c b/memory.c index 76da05b..6061b27 100644 --- a/memory.c +++ b/memory.c @@ -1380,7 +1380,8 @@ void memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size) { assert(mr->terminates); - cpu_physical_memory_set_dirty_range(mr->ram_addr + addr, size); + cpu_physical_memory_set_dirty_range(mr->ram_addr + addr, size, + memory_region_is_logging(mr)); } bool memory_region_test_and_clear_dirty(MemoryRegion *mr, hwaddr addr, -- 2.3.3