ram: Move src_page_req* to RAMState

This are the last postcopy fields still at MigrationState.  Once there
Move MigrationSrcPageRequest to ram.c and remove MigrationState
parameters where appropiate.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Peter Xu <peterx@redhat.com>
This commit is contained in:
Juan Quintela 2017-03-20 22:12:40 +01:00
parent 68a098f386
commit ec481c6c57
3 changed files with 40 additions and 43 deletions

View File

@ -128,18 +128,6 @@ struct MigrationIncomingState {
MigrationIncomingState *migration_incoming_get_current(void); MigrationIncomingState *migration_incoming_get_current(void);
void migration_incoming_state_destroy(void); void migration_incoming_state_destroy(void);
/*
* An outstanding page request, on the source, having been received
* and queued
*/
struct MigrationSrcPageRequest {
RAMBlock *rb;
hwaddr offset;
hwaddr len;
QSIMPLEQ_ENTRY(MigrationSrcPageRequest) next_req;
};
struct MigrationState struct MigrationState
{ {
size_t bytes_xfer; size_t bytes_xfer;
@ -186,9 +174,6 @@ struct MigrationState
/* Flag set once the migration thread called bdrv_inactivate_all */ /* Flag set once the migration thread called bdrv_inactivate_all */
bool block_inactive; bool block_inactive;
/* Queue of outstanding page requests from the destination */
QemuMutex src_page_req_mutex;
QSIMPLEQ_HEAD(src_page_requests, MigrationSrcPageRequest) src_page_requests;
/* The semaphore is used to notify COLO thread that failover is finished */ /* The semaphore is used to notify COLO thread that failover is finished */
QemuSemaphore colo_exit_sem; QemuSemaphore colo_exit_sem;
@ -371,7 +356,7 @@ void savevm_skip_configuration(void);
int global_state_store(void); int global_state_store(void);
void global_state_store_running(void); void global_state_store_running(void);
void migration_page_queue_free(MigrationState *ms); void migration_page_queue_free(void);
int ram_save_queue_pages(MigrationState *ms, const char *rbname, int ram_save_queue_pages(MigrationState *ms, const char *rbname,
ram_addr_t start, ram_addr_t len); ram_addr_t start, ram_addr_t len);
uint64_t ram_pagesize_summary(void); uint64_t ram_pagesize_summary(void);

View File

@ -109,7 +109,6 @@ MigrationState *migrate_get_current(void)
}; };
if (!once) { if (!once) {
qemu_mutex_init(&current_migration.src_page_req_mutex);
current_migration.parameters.tls_creds = g_strdup(""); current_migration.parameters.tls_creds = g_strdup("");
current_migration.parameters.tls_hostname = g_strdup(""); current_migration.parameters.tls_hostname = g_strdup("");
once = true; once = true;
@ -957,7 +956,7 @@ static void migrate_fd_cleanup(void *opaque)
qemu_bh_delete(s->cleanup_bh); qemu_bh_delete(s->cleanup_bh);
s->cleanup_bh = NULL; s->cleanup_bh = NULL;
migration_page_queue_free(s); migration_page_queue_free();
if (s->to_dst_file) { if (s->to_dst_file) {
trace_migrate_fd_cleanup(); trace_migrate_fd_cleanup();
@ -1131,8 +1130,6 @@ MigrationState *migrate_init(const MigrationParams *params)
migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP); migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP);
QSIMPLEQ_INIT(&s->src_page_requests);
s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
return s; return s;
} }

View File

@ -151,6 +151,18 @@ struct RAMBitmap {
}; };
typedef struct RAMBitmap RAMBitmap; typedef struct RAMBitmap RAMBitmap;
/*
* An outstanding page request, on the source, having been received
* and queued
*/
struct RAMSrcPageRequest {
RAMBlock *rb;
hwaddr offset;
hwaddr len;
QSIMPLEQ_ENTRY(RAMSrcPageRequest) next_req;
};
/* State of RAM for migration */ /* State of RAM for migration */
struct RAMState { struct RAMState {
/* Last block that we have visited searching for dirty pages */ /* Last block that we have visited searching for dirty pages */
@ -206,6 +218,9 @@ struct RAMState {
RAMBitmap *ram_bitmap; RAMBitmap *ram_bitmap;
/* The RAMBlock used in the last src_page_requests */ /* The RAMBlock used in the last src_page_requests */
RAMBlock *last_req_rb; RAMBlock *last_req_rb;
/* Queue of outstanding page requests from the destination */
QemuMutex src_page_req_mutex;
QSIMPLEQ_HEAD(src_page_requests, RAMSrcPageRequest) src_page_requests;
}; };
typedef struct RAMState RAMState; typedef struct RAMState RAMState;
@ -1085,20 +1100,20 @@ static bool find_dirty_block(RAMState *rs, QEMUFile *f, PageSearchStatus *pss,
* *
* Returns the block of the page (or NULL if none available) * Returns the block of the page (or NULL if none available)
* *
* @ms: current migration state * @rs: current RAM state
* @offset: used to return the offset within the RAMBlock * @offset: used to return the offset within the RAMBlock
* @ram_addr_abs: pointer into which to store the address of the dirty page * @ram_addr_abs: pointer into which to store the address of the dirty page
* within the global ram_addr space * within the global ram_addr space
*/ */
static RAMBlock *unqueue_page(MigrationState *ms, ram_addr_t *offset, static RAMBlock *unqueue_page(RAMState *rs, ram_addr_t *offset,
ram_addr_t *ram_addr_abs) ram_addr_t *ram_addr_abs)
{ {
RAMBlock *block = NULL; RAMBlock *block = NULL;
qemu_mutex_lock(&ms->src_page_req_mutex); qemu_mutex_lock(&rs->src_page_req_mutex);
if (!QSIMPLEQ_EMPTY(&ms->src_page_requests)) { if (!QSIMPLEQ_EMPTY(&rs->src_page_requests)) {
struct MigrationSrcPageRequest *entry = struct RAMSrcPageRequest *entry =
QSIMPLEQ_FIRST(&ms->src_page_requests); QSIMPLEQ_FIRST(&rs->src_page_requests);
block = entry->rb; block = entry->rb;
*offset = entry->offset; *offset = entry->offset;
*ram_addr_abs = (entry->offset + entry->rb->offset) & *ram_addr_abs = (entry->offset + entry->rb->offset) &
@ -1109,11 +1124,11 @@ static RAMBlock *unqueue_page(MigrationState *ms, ram_addr_t *offset,
entry->offset += TARGET_PAGE_SIZE; entry->offset += TARGET_PAGE_SIZE;
} else { } else {
memory_region_unref(block->mr); memory_region_unref(block->mr);
QSIMPLEQ_REMOVE_HEAD(&ms->src_page_requests, next_req); QSIMPLEQ_REMOVE_HEAD(&rs->src_page_requests, next_req);
g_free(entry); g_free(entry);
} }
} }
qemu_mutex_unlock(&ms->src_page_req_mutex); qemu_mutex_unlock(&rs->src_page_req_mutex);
return block; return block;
} }
@ -1126,13 +1141,11 @@ static RAMBlock *unqueue_page(MigrationState *ms, ram_addr_t *offset,
* Returns if a queued page is found * Returns if a queued page is found
* *
* @rs: current RAM state * @rs: current RAM state
* @ms: current migration state
* @pss: data about the state of the current dirty page scan * @pss: data about the state of the current dirty page scan
* @ram_addr_abs: pointer into which to store the address of the dirty page * @ram_addr_abs: pointer into which to store the address of the dirty page
* within the global ram_addr space * within the global ram_addr space
*/ */
static bool get_queued_page(RAMState *rs, MigrationState *ms, static bool get_queued_page(RAMState *rs, PageSearchStatus *pss,
PageSearchStatus *pss,
ram_addr_t *ram_addr_abs) ram_addr_t *ram_addr_abs)
{ {
RAMBlock *block; RAMBlock *block;
@ -1140,7 +1153,7 @@ static bool get_queued_page(RAMState *rs, MigrationState *ms,
bool dirty; bool dirty;
do { do {
block = unqueue_page(ms, &offset, ram_addr_abs); block = unqueue_page(rs, &offset, ram_addr_abs);
/* /*
* We're sending this page, and since it's postcopy nothing else * We're sending this page, and since it's postcopy nothing else
* will dirty it, and we must make sure it doesn't get sent again * will dirty it, and we must make sure it doesn't get sent again
@ -1194,18 +1207,18 @@ static bool get_queued_page(RAMState *rs, MigrationState *ms,
* It should be empty at the end anyway, but in error cases there may * It should be empty at the end anyway, but in error cases there may
* be some left. in case that there is any page left, we drop it. * be some left. in case that there is any page left, we drop it.
* *
* @ms: current migration state
*/ */
void migration_page_queue_free(MigrationState *ms) void migration_page_queue_free(void)
{ {
struct MigrationSrcPageRequest *mspr, *next_mspr; struct RAMSrcPageRequest *mspr, *next_mspr;
RAMState *rs = &ram_state;
/* This queue generally should be empty - but in the case of a failed /* This queue generally should be empty - but in the case of a failed
* migration might have some droppings in. * migration might have some droppings in.
*/ */
rcu_read_lock(); rcu_read_lock();
QSIMPLEQ_FOREACH_SAFE(mspr, &ms->src_page_requests, next_req, next_mspr) { QSIMPLEQ_FOREACH_SAFE(mspr, &rs->src_page_requests, next_req, next_mspr) {
memory_region_unref(mspr->rb->mr); memory_region_unref(mspr->rb->mr);
QSIMPLEQ_REMOVE_HEAD(&ms->src_page_requests, next_req); QSIMPLEQ_REMOVE_HEAD(&rs->src_page_requests, next_req);
g_free(mspr); g_free(mspr);
} }
rcu_read_unlock(); rcu_read_unlock();
@ -1262,16 +1275,16 @@ int ram_save_queue_pages(MigrationState *ms, const char *rbname,
goto err; goto err;
} }
struct MigrationSrcPageRequest *new_entry = struct RAMSrcPageRequest *new_entry =
g_malloc0(sizeof(struct MigrationSrcPageRequest)); g_malloc0(sizeof(struct RAMSrcPageRequest));
new_entry->rb = ramblock; new_entry->rb = ramblock;
new_entry->offset = start; new_entry->offset = start;
new_entry->len = len; new_entry->len = len;
memory_region_ref(ramblock->mr); memory_region_ref(ramblock->mr);
qemu_mutex_lock(&ms->src_page_req_mutex); qemu_mutex_lock(&rs->src_page_req_mutex);
QSIMPLEQ_INSERT_TAIL(&ms->src_page_requests, new_entry, next_req); QSIMPLEQ_INSERT_TAIL(&rs->src_page_requests, new_entry, next_req);
qemu_mutex_unlock(&ms->src_page_req_mutex); qemu_mutex_unlock(&rs->src_page_req_mutex);
rcu_read_unlock(); rcu_read_unlock();
return 0; return 0;
@ -1410,7 +1423,7 @@ static int ram_find_and_save_block(RAMState *rs, QEMUFile *f, bool last_stage)
do { do {
again = true; again = true;
found = get_queued_page(rs, ms, &pss, &dirty_ram_abs); found = get_queued_page(rs, &pss, &dirty_ram_abs);
if (!found) { if (!found) {
/* priority queue empty, so just search for something dirty */ /* priority queue empty, so just search for something dirty */
@ -1970,6 +1983,8 @@ static int ram_state_init(RAMState *rs)
memset(rs, 0, sizeof(*rs)); memset(rs, 0, sizeof(*rs));
qemu_mutex_init(&rs->bitmap_mutex); qemu_mutex_init(&rs->bitmap_mutex);
qemu_mutex_init(&rs->src_page_req_mutex);
QSIMPLEQ_INIT(&rs->src_page_requests);
if (migrate_use_xbzrle()) { if (migrate_use_xbzrle()) {
XBZRLE_cache_lock(); XBZRLE_cache_lock();