From patchwork Mon Feb 8 10:22:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: OHMURA Kei X-Patchwork-Id: 44772 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3DCD6B7CEC for ; Mon, 8 Feb 2010 21:36:44 +1100 (EST) Received: from localhost ([127.0.0.1]:46240 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NeQrb-0004aw-LB for incoming@patchwork.ozlabs.org; Mon, 08 Feb 2010 05:29:07 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NeQm6-0003kS-Tj for qemu-devel@nongnu.org; Mon, 08 Feb 2010 05:23:26 -0500 Received: from [199.232.76.173] (port=36983 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NeQm6-0003kI-HR for qemu-devel@nongnu.org; Mon, 08 Feb 2010 05:23:26 -0500 Received: from Debian-exim by monty-python.gnu.org with spam-scanned (Exim 4.60) (envelope-from ) id 1NeQlz-0000F7-IW for qemu-devel@nongnu.org; Mon, 08 Feb 2010 05:23:26 -0500 Received: from tama500.ecl.ntt.co.jp ([129.60.39.148]:41685) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NeQlx-0000Dc-N7 for qemu-devel@nongnu.org; Mon, 08 Feb 2010 05:23:18 -0500 Received: from mfs6.rdh.ecl.ntt.co.jp (mfs6.rdh.ecl.ntt.co.jp [129.60.39.149]) by tama500.ecl.ntt.co.jp (8.14.3/8.14.3) with ESMTP id o18ANDaq026960; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from mfs6.rdh.ecl.ntt.co.jp (localhost [127.0.0.1]) by mfs6.rdh.ecl.ntt.co.jp (Postfix) with ESMTP id 974925E64; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from dmailsv1.y.ecl.ntt.co.jp (dmailsv1.y.ecl.ntt.co.jp [129.60.53.14]) by mfs6.rdh.ecl.ntt.co.jp (Postfix) with ESMTP id 8DA5B5C66; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from mailsv02.y.ecl.ntt.co.jp by dmailsv1.y.ecl.ntt.co.jp (8.14.3/dmailsv1-2.1) with ESMTP id o18ANDwM001699; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from localhost by mailsv02.y.ecl.ntt.co.jp (8.14.3/Lab-1.7) with ESMTP id o18ANCxb000444; Mon, 8 Feb 2010 19:23:12 +0900 (JST) Message-ID: <4B6FE5DA.6000502@lab.ntt.co.jp> Date: Mon, 08 Feb 2010 19:22:18 +0900 From: OHMURA Kei User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: kvm@vger.kernel.org, qemu-devel@nongnu.org X-detected-operating-system: by monty-python.gnu.org: Solaris 10 (beta) Cc: Jan Kiszka , ohmura.kei@lab.ntt.co.jp, avi@redhat.com Subject: [Qemu-devel] [PATCH 1/3] qemu-kvm: Wrap phys_ram_dirty with additional inline functions. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org We think access phys_ram_dirty through inline functions is better than directly for encoupseling reason. We devided the ram in a 64 pages block. Each block has a counter, which is stored in phys_ram_dirty_by_word. It shows the number of dirty pages. We will find the 64 pages block is dirty or non-dirty using phys_ram_dirty_by_word. Signed-off-by: OHMURA Kei --- cpu-all.h | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cpu-defs.h | 1 + 2 files changed, 75 insertions(+), 0 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 8ed76c7..2251f14 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -168,6 +168,33 @@ typedef union { } CPU_QuadU; #endif +static inline unsigned long unroll_flags_to_ul(int flags) +{ + unsigned long ret = 0, flags_ul = (unsigned long)flags; + +#if TARGET_LONG_SIZE == 4 + ret |= flags_ul << 0; + ret |= flags_ul << 8; + ret |= flags_ul << 16; + ret |= flags_ul << 24; +#elif TARGET_LONG_SIZE == 8 + ret |= flags_ul << 0; + ret |= flags_ul << 8; + ret |= flags_ul << 16; + ret |= flags_ul << 24; + ret |= flags_ul << 32; + ret |= flags_ul << 40; + ret |= flags_ul << 48; + ret |= flags_ul << 56; +#else + int i; + for (i = 0; i < sizeof(unsigned long); i++) + ret |= flags_ul << (i * 8); +#endif + + return ret; +} + /* CPU memory access without any memory or io remapping */ /* @@ -847,6 +874,7 @@ int cpu_str_to_log_mask(const char *str); extern int phys_ram_fd; extern uint8_t *phys_ram_dirty; +extern int *phys_ram_dirty_by_word; extern ram_addr_t ram_size; extern ram_addr_t last_ram_offset; extern uint8_t *bios_mem; @@ -882,6 +910,11 @@ static inline int cpu_physical_memory_is_dirty(ram_addr_t addr) return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff; } +static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr) +{ + return phys_ram_dirty[addr >> TARGET_PAGE_BITS]; +} + static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, int dirty_flags) { @@ -890,9 +923,50 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) { + if (phys_ram_dirty[addr >> TARGET_PAGE_BITS] != 0xff) + ++phys_ram_dirty_by_word[(addr >> TARGET_PAGE_BITS) / + TARGET_LONG_BITS]; + phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff; } +static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr, + int dirty_flags) +{ + if ((phys_ram_dirty[addr >> TARGET_PAGE_BITS] != 0xff) && + ((phys_ram_dirty[addr >> TARGET_PAGE_BITS] | dirty_flags) == 0xff)) + ++phys_ram_dirty_by_word[(addr >> TARGET_PAGE_BITS) / + TARGET_LONG_BITS]; + + return phys_ram_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags; +} + +static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, + int length, + int dirty_flags) +{ + int i, mask, len, *pw; + uint8_t *p; + + len = length >> TARGET_PAGE_BITS; + mask = ~dirty_flags; + p = phys_ram_dirty + (start >> TARGET_PAGE_BITS); + pw = phys_ram_dirty_by_word + (start >> TARGET_PAGE_BITS) / + TARGET_LONG_BITS; + + for (i = 0; i < len; i++) { + if (p[i] == 0xff) + --pw[i / TARGET_LONG_BITS]; + p[i] &= mask; + } +} + +int cpu_physical_memory_get_dirty_range(ram_addr_t start, ram_addr_t end, + int dirty_flags); + +int cpu_physical_memory_get_non_dirty_range(ram_addr_t start, ram_addr_t end, + int dirty_flags); + void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, int dirty_flags); void cpu_tlb_update_dirty(CPUState *env); diff --git a/cpu-defs.h b/cpu-defs.h index cf502e9..8e89e96 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -37,6 +37,7 @@ #endif #define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8) +#define TARGET_LONG_ALIGN(addr) (((addr) + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS) /* target_ulong is the type of a virtual address */ #if TARGET_LONG_SIZE == 4