migration/ram.c: add a notifier chain for precopy
This patch adds a notifier chain for the memory precopy. This enables various precopy optimizations to be invoked at specific places. Signed-off-by: Wei Wang <wei.w.wang@intel.com> CC: Dr. David Alan Gilbert <dgilbert@redhat.com> CC: Juan Quintela <quintela@redhat.com> CC: Michael S. Tsirkin <mst@redhat.com> CC: Peter Xu <peterx@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Message-Id: <1544516693-5395-6-git-send-email-wei.w.wang@intel.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
parent
6bcb05fc42
commit
bd2270608f
@ -20,6 +20,25 @@
|
|||||||
|
|
||||||
/* migration/ram.c */
|
/* migration/ram.c */
|
||||||
|
|
||||||
|
typedef enum PrecopyNotifyReason {
|
||||||
|
PRECOPY_NOTIFY_SETUP = 0,
|
||||||
|
PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC = 1,
|
||||||
|
PRECOPY_NOTIFY_AFTER_BITMAP_SYNC = 2,
|
||||||
|
PRECOPY_NOTIFY_COMPLETE = 3,
|
||||||
|
PRECOPY_NOTIFY_CLEANUP = 4,
|
||||||
|
PRECOPY_NOTIFY_MAX = 5,
|
||||||
|
} PrecopyNotifyReason;
|
||||||
|
|
||||||
|
typedef struct PrecopyNotifyData {
|
||||||
|
enum PrecopyNotifyReason reason;
|
||||||
|
Error **errp;
|
||||||
|
} PrecopyNotifyData;
|
||||||
|
|
||||||
|
void precopy_infrastructure_init(void);
|
||||||
|
void precopy_add_notifier(NotifierWithReturn *n);
|
||||||
|
void precopy_remove_notifier(NotifierWithReturn *n);
|
||||||
|
int precopy_notify(PrecopyNotifyReason reason, Error **errp);
|
||||||
|
|
||||||
void ram_mig_init(void);
|
void ram_mig_init(void);
|
||||||
void qemu_guest_free_page_hint(void *addr, size_t len);
|
void qemu_guest_free_page_hint(void *addr, size_t len);
|
||||||
|
|
||||||
|
@ -354,6 +354,32 @@ typedef struct RAMState RAMState;
|
|||||||
|
|
||||||
static RAMState *ram_state;
|
static RAMState *ram_state;
|
||||||
|
|
||||||
|
static NotifierWithReturnList precopy_notifier_list;
|
||||||
|
|
||||||
|
void precopy_infrastructure_init(void)
|
||||||
|
{
|
||||||
|
notifier_with_return_list_init(&precopy_notifier_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
void precopy_add_notifier(NotifierWithReturn *n)
|
||||||
|
{
|
||||||
|
notifier_with_return_list_add(&precopy_notifier_list, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void precopy_remove_notifier(NotifierWithReturn *n)
|
||||||
|
{
|
||||||
|
notifier_with_return_remove(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
int precopy_notify(PrecopyNotifyReason reason, Error **errp)
|
||||||
|
{
|
||||||
|
PrecopyNotifyData pnd;
|
||||||
|
pnd.reason = reason;
|
||||||
|
pnd.errp = errp;
|
||||||
|
|
||||||
|
return notifier_with_return_list_notify(&precopy_notifier_list, &pnd);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t ram_bytes_remaining(void)
|
uint64_t ram_bytes_remaining(void)
|
||||||
{
|
{
|
||||||
return ram_state ? (ram_state->migration_dirty_pages * TARGET_PAGE_SIZE) :
|
return ram_state ? (ram_state->migration_dirty_pages * TARGET_PAGE_SIZE) :
|
||||||
@ -1741,6 +1767,25 @@ static void migration_bitmap_sync(RAMState *rs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void migration_bitmap_sync_precopy(RAMState *rs)
|
||||||
|
{
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The current notifier usage is just an optimization to migration, so we
|
||||||
|
* don't stop the normal migration process in the error case.
|
||||||
|
*/
|
||||||
|
if (precopy_notify(PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC, &local_err)) {
|
||||||
|
error_report_err(local_err);
|
||||||
|
}
|
||||||
|
|
||||||
|
migration_bitmap_sync(rs);
|
||||||
|
|
||||||
|
if (precopy_notify(PRECOPY_NOTIFY_AFTER_BITMAP_SYNC, &local_err)) {
|
||||||
|
error_report_err(local_err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* save_zero_page_to_file: send the zero page to the file
|
* save_zero_page_to_file: send the zero page to the file
|
||||||
*
|
*
|
||||||
@ -3123,7 +3168,7 @@ static void ram_init_bitmaps(RAMState *rs)
|
|||||||
|
|
||||||
ram_list_init_bitmaps();
|
ram_list_init_bitmaps();
|
||||||
memory_global_dirty_log_start();
|
memory_global_dirty_log_start();
|
||||||
migration_bitmap_sync(rs);
|
migration_bitmap_sync_precopy(rs);
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
qemu_mutex_unlock_ramlist();
|
qemu_mutex_unlock_ramlist();
|
||||||
@ -3403,7 +3448,7 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
|
|||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
if (!migration_in_postcopy()) {
|
if (!migration_in_postcopy()) {
|
||||||
migration_bitmap_sync(rs);
|
migration_bitmap_sync_precopy(rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ram_control_before_iterate(f, RAM_CONTROL_FINISH);
|
ram_control_before_iterate(f, RAM_CONTROL_FINISH);
|
||||||
@ -3452,7 +3497,7 @@ static void ram_save_pending(QEMUFile *f, void *opaque, uint64_t max_size,
|
|||||||
remaining_size < max_size) {
|
remaining_size < max_size) {
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
migration_bitmap_sync(rs);
|
migration_bitmap_sync_precopy(rs);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
remaining_size = rs->migration_dirty_pages * TARGET_PAGE_SIZE;
|
remaining_size = rs->migration_dirty_pages * TARGET_PAGE_SIZE;
|
||||||
|
@ -1088,6 +1088,7 @@ void qemu_savevm_state_header(QEMUFile *f)
|
|||||||
void qemu_savevm_state_setup(QEMUFile *f)
|
void qemu_savevm_state_setup(QEMUFile *f)
|
||||||
{
|
{
|
||||||
SaveStateEntry *se;
|
SaveStateEntry *se;
|
||||||
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
trace_savevm_state_setup();
|
trace_savevm_state_setup();
|
||||||
@ -1109,6 +1110,10 @@ void qemu_savevm_state_setup(QEMUFile *f)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (precopy_notify(PRECOPY_NOTIFY_SETUP, &local_err)) {
|
||||||
|
error_report_err(local_err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_savevm_state_resume_prepare(MigrationState *s)
|
int qemu_savevm_state_resume_prepare(MigrationState *s)
|
||||||
@ -1251,6 +1256,11 @@ int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
|
|||||||
SaveStateEntry *se;
|
SaveStateEntry *se;
|
||||||
int ret;
|
int ret;
|
||||||
bool in_postcopy = migration_in_postcopy();
|
bool in_postcopy = migration_in_postcopy();
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
if (precopy_notify(PRECOPY_NOTIFY_COMPLETE, &local_err)) {
|
||||||
|
error_report_err(local_err);
|
||||||
|
}
|
||||||
|
|
||||||
trace_savevm_state_complete_precopy();
|
trace_savevm_state_complete_precopy();
|
||||||
|
|
||||||
@ -1383,6 +1393,11 @@ void qemu_savevm_state_pending(QEMUFile *f, uint64_t threshold_size,
|
|||||||
void qemu_savevm_state_cleanup(void)
|
void qemu_savevm_state_cleanup(void)
|
||||||
{
|
{
|
||||||
SaveStateEntry *se;
|
SaveStateEntry *se;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
if (precopy_notify(PRECOPY_NOTIFY_CLEANUP, &local_err)) {
|
||||||
|
error_report_err(local_err);
|
||||||
|
}
|
||||||
|
|
||||||
trace_savevm_state_cleanup();
|
trace_savevm_state_cleanup();
|
||||||
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
|
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
|
||||||
|
1
vl.c
1
vl.c
@ -3039,6 +3039,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
module_call_init(MODULE_INIT_OPTS);
|
module_call_init(MODULE_INIT_OPTS);
|
||||||
|
|
||||||
runstate_init();
|
runstate_init();
|
||||||
|
precopy_infrastructure_init();
|
||||||
postcopy_infrastructure_init();
|
postcopy_infrastructure_init();
|
||||||
monitor_init_globals();
|
monitor_init_globals();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user