Skip to content

Commit

Permalink
migration/ram: Simplify host page handling in ram_load_postcopy()
Browse files Browse the repository at this point in the history
Add two new helper functions. This will come in come handy once we want to
handle ram block resizes while postcopy is active.

Note that ram_block_from_stream() will already print proper errors.

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20210429112708.12291-8-david@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
  dgilbert: Added brackets in host_page_from_ram_block_offset
     to cause uintptr_t to cast the sum, to fix armhf-cross build
  • Loading branch information
davidhildenbrand authored and dagrh committed May 13, 2021
1 parent cc61c70 commit 6a23f63
Showing 1 changed file with 32 additions and 23 deletions.
55 changes: 32 additions & 23 deletions migration/ram.c
Expand Up @@ -3085,6 +3085,20 @@ static inline void *host_from_ram_block_offset(RAMBlock *block,
return block->host + offset;
}

static void *host_page_from_ram_block_offset(RAMBlock *block,
ram_addr_t offset)
{
/* Note: Explicitly no check against offset_in_ramblock(). */
return (void *)QEMU_ALIGN_DOWN((uintptr_t)(block->host + offset),
block->page_size);
}

static ram_addr_t host_page_offset_from_ram_block_offset(RAMBlock *block,
ram_addr_t offset)
{
return ((uintptr_t)block->host + offset) & (block->page_size - 1);
}

static inline void *colo_cache_from_block_offset(RAMBlock *block,
ram_addr_t offset, bool record_bitmap)
{
Expand Down Expand Up @@ -3481,13 +3495,12 @@ static int ram_load_postcopy(QEMUFile *f)
MigrationIncomingState *mis = migration_incoming_get_current();
/* Temporary page that is later 'placed' */
void *postcopy_host_page = mis->postcopy_tmp_page;
void *this_host = NULL;
void *host_page = NULL;
bool all_zero = true;
int target_pages = 0;

while (!ret && !(flags & RAM_SAVE_FLAG_EOS)) {
ram_addr_t addr;
void *host = NULL;
void *page_buffer = NULL;
void *place_source = NULL;
RAMBlock *block = NULL;
Expand All @@ -3512,9 +3525,12 @@ static int ram_load_postcopy(QEMUFile *f)
if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE)) {
block = ram_block_from_stream(f, flags);
if (!block) {
ret = -EINVAL;
break;
}

host = host_from_ram_block_offset(block, addr);
if (!host) {
if (!offset_in_ramblock(block, addr)) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
break;
Expand All @@ -3532,19 +3548,17 @@ static int ram_load_postcopy(QEMUFile *f)
* of a host page in one chunk.
*/
page_buffer = postcopy_host_page +
((uintptr_t)host & (block->page_size - 1));
host_page_offset_from_ram_block_offset(block, addr);
/* If all TP are zero then we can optimise the place */
if (target_pages == 1) {
this_host = (void *)QEMU_ALIGN_DOWN((uintptr_t)host,
block->page_size);
} else {
host_page = host_page_from_ram_block_offset(block, addr);
} else if (host_page != host_page_from_ram_block_offset(block,
addr)) {
/* not the 1st TP within the HP */
if (QEMU_ALIGN_DOWN((uintptr_t)host, block->page_size) !=
(uintptr_t)this_host) {
error_report("Non-same host page %p/%p",
host, this_host);
ret = -EINVAL;
break;
}
error_report("Non-same host page %p/%p", host_page,
host_page_from_ram_block_offset(block, addr));
ret = -EINVAL;
break;
}

/*
Expand Down Expand Up @@ -3623,16 +3637,11 @@ static int ram_load_postcopy(QEMUFile *f)
}

if (!ret && place_needed) {
/* This gets called at the last target page in the host page */
void *place_dest = (void *)QEMU_ALIGN_DOWN((uintptr_t)host,
block->page_size);

if (all_zero) {
ret = postcopy_place_page_zero(mis, place_dest,
block);
ret = postcopy_place_page_zero(mis, host_page, block);
} else {
ret = postcopy_place_page(mis, place_dest,
place_source, block);
ret = postcopy_place_page(mis, host_page, place_source,
block);
}
place_needed = false;
target_pages = 0;
Expand Down

0 comments on commit 6a23f63

Please sign in to comment.