On Fri, Jul 29, 2011 at 04:57:26PM -0400, Umesh Deshpande wrote: > This patch creates a separate dirty bitmap for each slot. Currently dirty bitmap > is created for addresses ranging from 0 to the end address of the last memory > slot. Since the memslots are not necessarily contiguous, current bitmap might > contain empty region or holes that doesn't represent any VM pages. This patch > reduces the size of the dirty bitmap by allocating per memslot dirty bitmaps. > > Signed-off-by: Umesh Deshpande <udeshpan@xxxxxxxxxx> > --- > cpu-all.h | 40 +++++++++++++++++++++++++++++++++------- > exec.c | 38 +++++++++++++++++++++++--------------- > xen-all.c | 6 ++---- > 3 files changed, 58 insertions(+), 26 deletions(-) > > diff --git a/cpu-all.h b/cpu-all.h > index e839100..9517a9b 100644 > --- a/cpu-all.h > +++ b/cpu-all.h > @@ -920,6 +920,7 @@ extern ram_addr_t ram_size; > > typedef struct RAMBlock { > uint8_t *host; > + uint8_t *phys_dirty; > ram_addr_t offset; > ram_addr_t length; > uint32_t flags; > @@ -931,7 +932,6 @@ typedef struct RAMBlock { > } RAMBlock; > > typedef struct RAMList { > - uint8_t *phys_dirty; > QLIST_HEAD(ram, RAMBlock) blocks; > } RAMList; > extern RAMList ram_list; > @@ -961,32 +961,55 @@ extern int mem_prealloc; > #define CODE_DIRTY_FLAG 0x02 > #define MIGRATION_DIRTY_FLAG 0x08 > > +RAMBlock *qemu_addr_to_ramblock(ram_addr_t); > + > +static inline int get_page_nr(ram_addr_t addr, RAMBlock **block) > +{ > + int page_nr; > + *block = qemu_addr_to_ramblock(addr); > + > + page_nr = addr - (*block)->offset; > + page_nr = page_nr >> TARGET_PAGE_BITS; > + > + return page_nr; > +} > + > /* read dirty bit (return 0 or 1) */ > static inline int cpu_physical_memory_is_dirty(ram_addr_t addr) > { > - return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] == 0xff; > + RAMBlock *block; > + int page_nr = get_page_nr(addr, &block); > + return block->phys_dirty[page_nr] == 0xff; > } > > static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr) > { > - return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS]; > + RAMBlock *block; > + int page_nr = get_page_nr(addr, &block); > + return block->phys_dirty[page_nr]; > } > > static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, > int dirty_flags) > { > - return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags; > + RAMBlock *block; > + int page_nr = get_page_nr(addr, &block); > + return block->phys_dirty[page_nr] & dirty_flags; > } > > static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) > { > - ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff; > + RAMBlock *block; > + int page_nr = get_page_nr(addr, &block); > + block->phys_dirty[page_nr] = 0xff; > } > > static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr, > int dirty_flags) > { > - return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags; > + RAMBlock *block; > + int page_nr = get_page_nr(addr, &block); > + return block->phys_dirty[page_nr] |= dirty_flags; > } > > static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, > @@ -995,10 +1018,13 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, > { > int i, mask, len; > uint8_t *p; > + RAMBlock *block; > + int page_nr = get_page_nr(start, &block); > > len = length >> TARGET_PAGE_BITS; > mask = ~dirty_flags; > - p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS); > + > + p = block->phys_dirty + page_nr; > p[i] &= mask; > } > diff --git a/exec.c b/exec.c > index 0e2ce57..6312550 100644 > --- a/exec.c > +++ b/exec.c > @@ -2106,6 +2106,10 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, > abort(); > } > > + if (kvm_enabled()) { > + return; > + } > + This belongs to a separate patch. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html