Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migration: add capability to bypass the shared memory #2

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions migration/migration.c
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,20 @@ bool migrate_release_ram(void)
return s->enabled_capabilities[MIGRATION_CAPABILITY_RELEASE_RAM];
}

bool migrate_bypass_shared_memory(void)
{
MigrationState *s;

/* it is not workable with postcopy yet. */
if (migrate_postcopy_ram()) {
return false;
}

s = migrate_get_current();

return s->enabled_capabilities[MIGRATION_CAPABILITY_BYPASS_SHARED_MEMORY];
}

bool migrate_postcopy_ram(void)
{
MigrationState *s;
Expand Down
1 change: 1 addition & 0 deletions migration/migration.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ MigrationState *migrate_get_current(void);

bool migrate_postcopy(void);

bool migrate_bypass_shared_memory(void);
bool migrate_release_ram(void);
bool migrate_postcopy_ram(void);
bool migrate_zero_blocks(void);
Expand Down
27 changes: 18 additions & 9 deletions migration/ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,11 @@ unsigned long migration_bitmap_find_dirty(RAMState *rs, RAMBlock *rb,
unsigned long *bitmap = rb->bmap;
unsigned long next;

/* when this ramblock is requested bypassing */
if (!bitmap) {
return size;
}

if (rs->ram_bulk_stage && start > 0) {
next = start + 1;
} else {
Expand Down Expand Up @@ -842,7 +847,9 @@ static void migration_bitmap_sync(RAMState *rs)
qemu_mutex_lock(&rs->bitmap_mutex);
rcu_read_lock();
RAMBLOCK_FOREACH(block) {
migration_bitmap_sync_range(rs, block, 0, block->used_length);
if (!migrate_bypass_shared_memory() || !qemu_ram_is_shared(block)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I though migrate_bypass_shared_memory was enough

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even when migrate_bypass_shared_memory is set, ram can be set private instead of being shared. The only case we can skip syncing is migrate_bypass_shared_memory && ram_is_shared.

migration_bitmap_sync_range(rs, block, 0, block->used_length);
}
}
rcu_read_unlock();
qemu_mutex_unlock(&rs->bitmap_mutex);
Expand Down Expand Up @@ -2123,28 +2130,30 @@ static int ram_state_init(RAMState **rsp)
qemu_mutex_init(&(*rsp)->src_page_req_mutex);
QSIMPLEQ_INIT(&(*rsp)->src_page_requests);

/*
* Count the total number of pages used by ram blocks not including any
* gaps due to alignment or unplugs.
*/
(*rsp)->migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;

ram_state_reset(*rsp);

return 0;
}

static void ram_list_init_bitmaps(void)
static void ram_list_init_bitmaps(RAMState *rs)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if rs is NULL

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
RAMBlock *block;
unsigned long pages;

/* Skip setting bitmap if there is no RAM */
if (ram_bytes_total()) {
QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
if (migrate_bypass_shared_memory() && qemu_ram_is_shared(block)) {
continue;
}
pages = block->max_length >> TARGET_PAGE_BITS;
block->bmap = bitmap_new(pages);
bitmap_set(block->bmap, 0, pages);
/*
* Count the total number of pages used by ram blocks not
* including any gaps due to alignment or unplugs.
*/
rs->migration_dirty_pages += pages;
if (migrate_postcopy_ram()) {
block->unsentmap = bitmap_new(pages);
bitmap_set(block->unsentmap, 0, pages);
Expand All @@ -2160,7 +2169,7 @@ static void ram_init_bitmaps(RAMState *rs)
qemu_mutex_lock_ramlist();
rcu_read_lock();

ram_list_init_bitmaps();
ram_list_init_bitmaps(rs);
memory_global_dirty_log_start();
migration_bitmap_sync(rs);

Expand Down
8 changes: 7 additions & 1 deletion qapi/migration.json
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,17 @@
#
# @x-multifd: Use more than one fd for migration (since 2.11)
#
# @bypass-shared-memory: the shared memory region will be bypassed on migration.
# This feature allows the memory region to be reused by new qemu(s)
# or be migrated separately. (since 2.12)
#
# Since: 1.2
##
{ 'enum': 'MigrationCapability',
'data': ['xbzrle', 'rdma-pin-all', 'auto-converge', 'zero-blocks',
'compress', 'events', 'postcopy-ram', 'x-colo', 'release-ram',
'block', 'return-path', 'pause-before-switchover', 'x-multifd' ] }
'block', 'return-path', 'pause-before-switchover', 'x-multifd',
'bypass-shared-memory'] }

##
# @MigrationCapabilityStatus:
Expand Down Expand Up @@ -412,6 +417,7 @@
# {"state": true, "capability": "events"},
# {"state": false, "capability": "postcopy-ram"},
# {"state": false, "capability": "x-colo"}
# {"state": false, "capability": "bypass-shared-memory"}
# ]}
#
##
Expand Down