From: Anthony Liguori <anthony@codemonkey.ws>
To: Yoshiaki Tamura <tamura.yoshiaki@lab.ntt.co.jp>
Cc: ohmura.kei@lab.ntt.co.jp, Marcelo Tosatti <mtosatti@redhat.com>,
qemu-devel@nongnu.org, avi@redhat.com
Subject: Re: [Qemu-devel] [PATCH v4 1/4] Modify DIRTY_FLAG value and introduce DIRTY_IDX to use as indexes of bit-based phys_ram_dirty.
Date: Mon, 03 May 2010 15:03:50 -0500 [thread overview]
Message-ID: <4BDF2C26.40406@codemonkey.ws> (raw)
In-Reply-To: <1271734843-24231-2-git-send-email-tamura.yoshiaki@lab.ntt.co.jp>
Hi Yoshi,
Could you rebase this series and resubmit? It conflicts with the latest
HEAD.
Regards,
Anthony Liguori
On 04/19/2010 10:40 PM, Yoshiaki Tamura wrote:
> Replaces byte-based phys_ram_dirty bitmap with four (MASTER, VGA, CODE,
> MIGRATION) bit-based phys_ram_dirty bitmap. On allocation, it sets all bits in
> the bitmap. It uses ffs() to convert DIRTY_FLAG to DIRTY_IDX.
>
> Modifies wrapper functions for byte-based phys_ram_dirty bitmap to bit-based
> phys_ram_dirty bitmap. MASTER works as a buffer, and upon get_diry() or
> get_dirty_flags(), it calls cpu_physical_memory_sync_master() to update VGA and
> MIGRATION.
>
> Signed-off-by: Yoshiaki Tamura<tamura.yoshiaki@lab.ntt.co.jp>
> ---
> cpu-all.h | 127 ++++++++++++++++++++++++++++++++++++++++++++++++---------
> exec.c | 15 +++++--
> qemu-common.h | 3 +
> 3 files changed, 121 insertions(+), 24 deletions(-)
>
> diff --git a/cpu-all.h b/cpu-all.h
> index f8bfa66..b6a2d91 100644
> --- a/cpu-all.h
> +++ b/cpu-all.h
> @@ -37,6 +37,9 @@
>
> #include "softfloat.h"
>
> +/* to use ffs in flag_to_idx() */
> +#include<strings.h>
> +
> #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
> #define BSWAP_NEEDED
> #endif
> @@ -853,7 +856,6 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
> /* memory API */
>
> extern int phys_ram_fd;
> -extern uint8_t *phys_ram_dirty;
> extern ram_addr_t ram_size;
> extern ram_addr_t last_ram_offset;
>
> @@ -878,50 +880,137 @@ extern int mem_prealloc;
> /* Set if TLB entry is an IO callback. */
> #define TLB_MMIO (1<< 5)
>
> -#define VGA_DIRTY_FLAG 0x01
> -#define CODE_DIRTY_FLAG 0x02
> -#define MIGRATION_DIRTY_FLAG 0x08
> +/* Use DIRTY_IDX as indexes of bit-based phys_ram_dirty. */
> +#define MASTER_DIRTY_IDX 0
> +#define VGA_DIRTY_IDX 1
> +#define CODE_DIRTY_IDX 2
> +#define MIGRATION_DIRTY_IDX 3
> +#define NUM_DIRTY_IDX 4
> +
> +#define MASTER_DIRTY_FLAG (1<< MASTER_DIRTY_IDX)
> +#define VGA_DIRTY_FLAG (1<< VGA_DIRTY_IDX)
> +#define CODE_DIRTY_FLAG (1<< CODE_DIRTY_IDX)
> +#define MIGRATION_DIRTY_FLAG (1<< MIGRATION_DIRTY_IDX)
> +
> +extern unsigned long *phys_ram_dirty[NUM_DIRTY_IDX];
> +
> +static inline int dirty_flag_to_idx(int flag)
> +{
> + return ffs(flag) - 1;
> +}
> +
> +static inline int dirty_idx_to_flag(int idx)
> +{
> + return 1<< idx;
> +}
>
> /* read dirty bit (return 0 or 1) */
> static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
> {
> - return phys_ram_dirty[addr>> TARGET_PAGE_BITS] == 0xff;
> + unsigned long mask;
> + ram_addr_t index = (addr>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> + int offset = (addr>> TARGET_PAGE_BITS)& (HOST_LONG_BITS - 1);
> +
> + mask = 1UL<< offset;
> + return (phys_ram_dirty[MASTER_DIRTY_IDX][index]& mask) == mask;
> +}
> +
> +static inline void cpu_physical_memory_sync_master(ram_addr_t index)
> +{
> + if (phys_ram_dirty[MASTER_DIRTY_IDX][index]) {
> + phys_ram_dirty[VGA_DIRTY_IDX][index]
> + |= phys_ram_dirty[MASTER_DIRTY_IDX][index];
> + phys_ram_dirty[MIGRATION_DIRTY_IDX][index]
> + |= phys_ram_dirty[MASTER_DIRTY_IDX][index];
> + phys_ram_dirty[MASTER_DIRTY_IDX][index] = 0UL;
> + }
> }
>
> static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
> {
> - return phys_ram_dirty[addr>> TARGET_PAGE_BITS];
> + unsigned long mask;
> + ram_addr_t index = (addr>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> + int offset = (addr>> TARGET_PAGE_BITS)& (HOST_LONG_BITS - 1);
> + int ret = 0, i;
> +
> + mask = 1UL<< offset;
> + cpu_physical_memory_sync_master(index);
> +
> + for (i = VGA_DIRTY_IDX; i<= MIGRATION_DIRTY_IDX; i++) {
> + if (phys_ram_dirty[i][index]& mask) {
> + ret |= dirty_idx_to_flag(i);
> + }
> + }
> +
> + return ret;
> +}
> +
> +static inline int cpu_physical_memory_get_dirty_idx(ram_addr_t addr,
> + int dirty_idx)
> +{
> + unsigned long mask;
> + ram_addr_t index = (addr>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> + int offset = (addr>> TARGET_PAGE_BITS)& (HOST_LONG_BITS - 1);
> +
> + mask = 1UL<< offset;
> + cpu_physical_memory_sync_master(index);
> + return (phys_ram_dirty[dirty_idx][index]& mask) == mask;
> }
>
> static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
> int dirty_flags)
> {
> - return phys_ram_dirty[addr>> TARGET_PAGE_BITS]& dirty_flags;
> + return cpu_physical_memory_get_dirty_idx(addr,
> + dirty_flag_to_idx(dirty_flags));
> }
>
> static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
> {
> - phys_ram_dirty[addr>> TARGET_PAGE_BITS] = 0xff;
> + unsigned long mask;
> + ram_addr_t index = (addr>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> + int offset = (addr>> TARGET_PAGE_BITS)& (HOST_LONG_BITS - 1);
> +
> + mask = 1UL<< offset;
> + phys_ram_dirty[MASTER_DIRTY_IDX][index] |= mask;
> +}
> +
> +static inline void cpu_physical_memory_set_dirty_range(ram_addr_t addr,
> + unsigned long mask)
> +{
> + ram_addr_t index = (addr>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> +
> + phys_ram_dirty[MASTER_DIRTY_IDX][index] |= mask;
> }
>
> -static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
> - int dirty_flags)
> +static inline void cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
> + int dirty_flags)
> {
> - return phys_ram_dirty[addr>> TARGET_PAGE_BITS] |= dirty_flags;
> + unsigned long mask;
> + ram_addr_t index = (addr>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> + int offset = (addr>> TARGET_PAGE_BITS)& (HOST_LONG_BITS - 1);
> +
> + mask = 1UL<< offset;
> + phys_ram_dirty[MASTER_DIRTY_IDX][index] |= mask;
> +
> + if (dirty_flags& CODE_DIRTY_FLAG) {
> + phys_ram_dirty[CODE_DIRTY_IDX][index] |= mask;
> + }
> }
>
> static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
> - int length,
> + unsigned long length,
> int dirty_flags)
> {
> - int i, mask, len;
> - uint8_t *p;
> + ram_addr_t addr = start, index;
> + unsigned long mask;
> + int offset, i;
>
> - len = length>> TARGET_PAGE_BITS;
> - mask = ~dirty_flags;
> - p = phys_ram_dirty + (start>> TARGET_PAGE_BITS);
> - for (i = 0; i< len; i++)
> - p[i]&= mask;
> + for (i = 0; i< length; i += TARGET_PAGE_SIZE) {
> + index = ((addr + i)>> TARGET_PAGE_BITS) / HOST_LONG_BITS;
> + offset = ((addr + i)>> TARGET_PAGE_BITS)& (HOST_LONG_BITS - 1);
> + mask = ~(1UL<< offset);
> + phys_ram_dirty[dirty_flag_to_idx(dirty_flags)][index]&= mask;
> + }
> }
>
> void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
> diff --git a/exec.c b/exec.c
> index c74b0a4..82b7c32 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -110,7 +110,7 @@ uint8_t *code_gen_ptr;
>
> #if !defined(CONFIG_USER_ONLY)
> int phys_ram_fd;
> -uint8_t *phys_ram_dirty;
> +unsigned long *phys_ram_dirty[NUM_DIRTY_IDX];
> static int in_migration;
>
> typedef struct RAMBlock {
> @@ -2793,6 +2793,7 @@ static void *file_ram_alloc(ram_addr_t memory, const char *path)
> ram_addr_t qemu_ram_alloc(ram_addr_t size)
> {
> RAMBlock *new_block;
> + int i;
>
> size = TARGET_PAGE_ALIGN(size);
> new_block = qemu_malloc(sizeof(*new_block));
> @@ -2825,10 +2826,14 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size)
> new_block->next = ram_blocks;
> ram_blocks = new_block;
>
> - phys_ram_dirty = qemu_realloc(phys_ram_dirty,
> - (last_ram_offset + size)>> TARGET_PAGE_BITS);
> - memset(phys_ram_dirty + (last_ram_offset>> TARGET_PAGE_BITS),
> - 0xff, size>> TARGET_PAGE_BITS);
> + for (i = MASTER_DIRTY_IDX; i< NUM_DIRTY_IDX; i++) {
> + phys_ram_dirty[i]
> + = qemu_realloc(phys_ram_dirty[i],
> + BITMAP_SIZE(last_ram_offset + size));
> + memset((uint8_t *)phys_ram_dirty[i] + BITMAP_SIZE(last_ram_offset),
> + 0xff, BITMAP_SIZE(last_ram_offset + size)
> + - BITMAP_SIZE(last_ram_offset));
> + }
>
> last_ram_offset += size;
>
> diff --git a/qemu-common.h b/qemu-common.h
> index 4ba0cda..efe5b1f 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -285,6 +285,9 @@ static inline uint8_t from_bcd(uint8_t val)
> return ((val>> 4) * 10) + (val& 0x0f);
> }
>
> +#define ALIGN(x, y) (((x)+(y)-1)& ~((y)-1))
> +#define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8)
> +
> #include "module.h"
>
> #endif /* dyngen-exec.h hack */
>
next prev parent reply other threads:[~2010-05-03 20:04 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-20 3:40 [Qemu-devel] [PATCH v4 0/4] Introduce bit-based phys_ram_dirty, and bit-based dirty page checker Yoshiaki Tamura
2010-04-20 3:40 ` [Qemu-devel] [PATCH v4 1/4] Modify DIRTY_FLAG value and introduce DIRTY_IDX to use as indexes of bit-based phys_ram_dirty Yoshiaki Tamura
2010-05-03 20:03 ` Anthony Liguori [this message]
2010-05-04 8:31 ` Yoshiaki Tamura
2010-04-20 3:40 ` [Qemu-devel] [PATCH v4 2/4] Introduce cpu_physical_memory_get_dirty_range() Yoshiaki Tamura
2010-04-20 3:40 ` [Qemu-devel] [PATCH v4 3/4] Use cpu_physical_memory_set_dirty_range() to update phys_ram_dirty Yoshiaki Tamura
2010-04-20 3:40 ` [Qemu-devel] [PATCH v4 4/4] Use cpu_physical_memory_get_dirty_range() to check multiple dirty pages Yoshiaki Tamura
2010-04-21 12:15 ` [Qemu-devel] Re: [PATCH v4 0/4] Introduce bit-based phys_ram_dirty, and bit-based dirty page checker Avi Kivity
2010-04-26 10:43 ` Yoshiaki Tamura
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4BDF2C26.40406@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=avi@redhat.com \
--cc=mtosatti@redhat.com \
--cc=ohmura.kei@lab.ntt.co.jp \
--cc=qemu-devel@nongnu.org \
--cc=tamura.yoshiaki@lab.ntt.co.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.