Message ID | 1374783499-2550-5-git-send-email-lilei@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
On 07/25/2013 04:18 PM, Lei Li wrote: > Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> > --- > arch_init.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 58 insertions(+), 0 deletions(-) > > diff --git a/arch_init.c b/arch_init.c > index a8b91ee..a418071 100644 > --- a/arch_init.c > +++ b/arch_init.c > @@ -699,6 +699,64 @@ static uint64_t ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) > return remaining_size; > } > > +/* This is the last block from where we have sent data for local migration */ > +static RAMBlock *last_block_local; > +static ram_addr_t last_offset_local; > + > +static int ram_page_save(QEMUFile *f) > +{ > + RAMBlock *block = last_block_local; > + ram_addr_t offset = last_offset_local; > + MemoryRegion *mr = block->mr; > + int bytes_sent = 0; > + > + if (!block) { > + block = QTAILQ_FIRST(&ram_list.blocks); > + } > + > + do { > + mr = block->mr; > + uint8_t *p; > + int cont = (block == last_block_local) ? RAM_SAVE_FLAG_CONTINUE : 0; > + > + p = memory_region_get_ram_ptr(mr) + offset; > + > + if (is_zero_page(p)) { > + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS); > + if (!cont) { > + qemu_put_byte(f, strlen(block->idstr)); > + qemu_put_buffer(f, (uint8_t *)block->idstr, > + strlen(block->idstr)); > + } > + qemu_put_byte(f, *p); > + bytes_sent = 1; > + } else { > + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE); > + if (!cont) { > + qemu_put_byte(f, strlen(block->idstr)); > + qemu_put_buffer(f, (uint8_t *)block->idstr, > + strlen(block->idstr)); > + } > + qemu_put_buffer(f, p, TARGET_PAGE_SIZE); > + bytes_sent = TARGET_PAGE_SIZE; > + } > + > + offset += TARGET_PAGE_SIZE; > + if (offset >= block->length) { > + offset = 0; > + block = QTAILQ_NEXT(block, next); > + if (!block) { > + block = QTAILQ_FIRST(&ram_list.blocks); > + } > + } > + } while (block != last_block_local || offset != last_offset_local); > + > + last_block_local = block; > + last_offset_local = offset; > + > + return bytes_sent; > +} > + > static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) > { > int ret, rc = 0; Seems like there's a lot of duplicate code. We have new hooks to override the way memory is saved in arch_init.c See the QEMUFileOps......... save_page() / before_ram_iterate() / after_ram_iterate() You might need to introduce a new "load_page()" pointer in QEMUFileOps. Then all this code can be private to migration-local.c - Michael
On 08/03/2013 03:40 AM, Michael R. Hines wrote: > On 07/25/2013 04:18 PM, Lei Li wrote: >> Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> >> --- >> arch_init.c | 58 >> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 files changed, 58 insertions(+), 0 deletions(-) >> >> diff --git a/arch_init.c b/arch_init.c >> index a8b91ee..a418071 100644 >> --- a/arch_init.c >> +++ b/arch_init.c >> @@ -699,6 +699,64 @@ static uint64_t ram_save_pending(QEMUFile *f, >> void *opaque, uint64_t max_size) >> return remaining_size; >> } >> >> +/* This is the last block from where we have sent data for local >> migration */ >> +static RAMBlock *last_block_local; >> +static ram_addr_t last_offset_local; >> + >> +static int ram_page_save(QEMUFile *f) >> +{ >> + RAMBlock *block = last_block_local; >> + ram_addr_t offset = last_offset_local; >> + MemoryRegion *mr = block->mr; >> + int bytes_sent = 0; >> + >> + if (!block) { >> + block = QTAILQ_FIRST(&ram_list.blocks); >> + } >> + >> + do { >> + mr = block->mr; >> + uint8_t *p; >> + int cont = (block == last_block_local) ? >> RAM_SAVE_FLAG_CONTINUE : 0; >> + >> + p = memory_region_get_ram_ptr(mr) + offset; >> + >> + if (is_zero_page(p)) { >> + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS); >> + if (!cont) { >> + qemu_put_byte(f, strlen(block->idstr)); >> + qemu_put_buffer(f, (uint8_t *)block->idstr, >> + strlen(block->idstr)); >> + } >> + qemu_put_byte(f, *p); >> + bytes_sent = 1; >> + } else { >> + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE); >> + if (!cont) { >> + qemu_put_byte(f, strlen(block->idstr)); >> + qemu_put_buffer(f, (uint8_t *)block->idstr, >> + strlen(block->idstr)); >> + } >> + qemu_put_buffer(f, p, TARGET_PAGE_SIZE); >> + bytes_sent = TARGET_PAGE_SIZE; >> + } >> + >> + offset += TARGET_PAGE_SIZE; >> + if (offset >= block->length) { >> + offset = 0; >> + block = QTAILQ_NEXT(block, next); >> + if (!block) { >> + block = QTAILQ_FIRST(&ram_list.blocks); >> + } >> + } >> + } while (block != last_block_local || offset != last_offset_local); >> + >> + last_block_local = block; >> + last_offset_local = offset; >> + >> + return bytes_sent; >> +} >> + >> static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) >> { >> int ret, rc = 0; > > Seems like there's a lot of duplicate code. > > We have new hooks to override the way memory is saved in arch_init.c > > See the QEMUFileOps......... save_page() / before_ram_iterate() / > after_ram_iterate() > > You might need to introduce a new "load_page()" pointer in QEMUFileOps. > > Then all this code can be private to migration-local.c Hi Michael, This implementation was based on the tree that rdma migration you added have not been merged... Yes, Paolo also suggested that reuses the rdma hooks and I am trying to figure it out. Your comments really helps, thanks for your suggestions! > > - Michael > > >
diff --git a/arch_init.c b/arch_init.c index a8b91ee..a418071 100644 --- a/arch_init.c +++ b/arch_init.c @@ -699,6 +699,64 @@ static uint64_t ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) return remaining_size; } +/* This is the last block from where we have sent data for local migration */ +static RAMBlock *last_block_local; +static ram_addr_t last_offset_local; + +static int ram_page_save(QEMUFile *f) +{ + RAMBlock *block = last_block_local; + ram_addr_t offset = last_offset_local; + MemoryRegion *mr = block->mr; + int bytes_sent = 0; + + if (!block) { + block = QTAILQ_FIRST(&ram_list.blocks); + } + + do { + mr = block->mr; + uint8_t *p; + int cont = (block == last_block_local) ? RAM_SAVE_FLAG_CONTINUE : 0; + + p = memory_region_get_ram_ptr(mr) + offset; + + if (is_zero_page(p)) { + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_COMPRESS); + if (!cont) { + qemu_put_byte(f, strlen(block->idstr)); + qemu_put_buffer(f, (uint8_t *)block->idstr, + strlen(block->idstr)); + } + qemu_put_byte(f, *p); + bytes_sent = 1; + } else { + qemu_put_be64(f, offset | cont | RAM_SAVE_FLAG_PAGE); + if (!cont) { + qemu_put_byte(f, strlen(block->idstr)); + qemu_put_buffer(f, (uint8_t *)block->idstr, + strlen(block->idstr)); + } + qemu_put_buffer(f, p, TARGET_PAGE_SIZE); + bytes_sent = TARGET_PAGE_SIZE; + } + + offset += TARGET_PAGE_SIZE; + if (offset >= block->length) { + offset = 0; + block = QTAILQ_NEXT(block, next); + if (!block) { + block = QTAILQ_FIRST(&ram_list.blocks); + } + } + } while (block != last_block_local || offset != last_offset_local); + + last_block_local = block; + last_offset_local = offset; + + return bytes_sent; +} + static int load_xbzrle(QEMUFile *f, ram_addr_t addr, void *host) { int ret, rc = 0;
Signed-off-by: Lei Li <lilei@linux.vnet.ibm.com> --- arch_init.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 58 insertions(+), 0 deletions(-)