Rework ram_control_load_hook to hook during block load

We need the names of RAMBlocks as they're loaded for RDMA,
reuse a slightly modified ram_control_load_hook:
  a) Pass a 'data' parameter to use for the name in the block-reg
     case
  b) Only some hook types now require the presence of a hook function.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
Dr. David Alan Gilbert 2015-06-11 18:17:23 +01:00 committed by Juan Quintela
parent b12f777798
commit 632e3a5cd8
6 changed files with 47 additions and 19 deletions

View file

@ -179,7 +179,7 @@ int migrate_decompress_threads(void);
void ram_control_before_iterate(QEMUFile *f, uint64_t flags);
void ram_control_after_iterate(QEMUFile *f, uint64_t flags);
void ram_control_load_hook(QEMUFile *f, uint64_t flags);
void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data);
/* Whenever this is found in the data stream, the flags
* will be passed to ram_control_load_hook in the incoming-migration

View file

@ -63,16 +63,20 @@ typedef ssize_t (QEMUFileWritevBufferFunc)(void *opaque, struct iovec *iov,
/*
* This function provides hooks around different
* stages of RAM migration.
* 'opaque' is the backend specific data in QEMUFile
* 'data' is call specific data associated with the 'flags' value
*/
typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags);
typedef int (QEMURamHookFunc)(QEMUFile *f, void *opaque, uint64_t flags,
void *data);
/*
* Constants used by ram_control_* hooks
*/
#define RAM_CONTROL_SETUP 0
#define RAM_CONTROL_ROUND 1
#define RAM_CONTROL_HOOK 2
#define RAM_CONTROL_FINISH 3
#define RAM_CONTROL_SETUP 0
#define RAM_CONTROL_ROUND 1
#define RAM_CONTROL_HOOK 2
#define RAM_CONTROL_FINISH 3
#define RAM_CONTROL_BLOCK_REG 4
/*
* This function allows override of where the RAM page

View file

@ -129,7 +129,7 @@ void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
int ret = 0;
if (f->ops->before_ram_iterate) {
ret = f->ops->before_ram_iterate(f, f->opaque, flags);
ret = f->ops->before_ram_iterate(f, f->opaque, flags, NULL);
if (ret < 0) {
qemu_file_set_error(f, ret);
}
@ -141,24 +141,30 @@ void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
int ret = 0;
if (f->ops->after_ram_iterate) {
ret = f->ops->after_ram_iterate(f, f->opaque, flags);
ret = f->ops->after_ram_iterate(f, f->opaque, flags, NULL);
if (ret < 0) {
qemu_file_set_error(f, ret);
}
}
}
void ram_control_load_hook(QEMUFile *f, uint64_t flags)
void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data)
{
int ret = -EINVAL;
if (f->ops->hook_ram_load) {
ret = f->ops->hook_ram_load(f, f->opaque, flags);
ret = f->ops->hook_ram_load(f, f->opaque, flags, data);
if (ret < 0) {
qemu_file_set_error(f, ret);
}
} else {
qemu_file_set_error(f, ret);
/*
* Hook is a hook specifically requested by the source sending a flag
* that expects there to be a hook on the destination.
*/
if (flags == RAM_CONTROL_HOOK) {
qemu_file_set_error(f, ret);
}
}
}

View file

@ -1477,6 +1477,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
error_report_err(local_err);
}
}
ram_control_load_hook(f, RAM_CONTROL_BLOCK_REG,
block->idstr);
break;
}
}
@ -1545,7 +1547,7 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
break;
default:
if (flags & RAM_SAVE_FLAG_HOOK) {
ram_control_load_hook(f, flags);
ram_control_load_hook(f, RAM_CONTROL_HOOK, NULL);
} else {
error_report("Unknown combination of migration flags: %#x",
flags);

View file

@ -2913,8 +2913,7 @@ err_rdma_dest_wait:
*
* Keep doing this until the source tells us to stop.
*/
static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque,
uint64_t flags)
static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque)
{
RDMAControlHeader reg_resp = { .len = sizeof(RDMARegisterResult),
.type = RDMA_CONTROL_REGISTER_RESULT,
@ -2944,7 +2943,7 @@ static int qemu_rdma_registration_handle(QEMUFile *f, void *opaque,
CHECK_ERROR_STATE();
do {
trace_qemu_rdma_registration_handle_wait(flags);
trace_qemu_rdma_registration_handle_wait();
ret = qemu_rdma_exchange_recv(rdma, &head, RDMA_CONTROL_NONE);
@ -3132,8 +3131,25 @@ out:
return ret;
}
static int rdma_load_hook(QEMUFile *f, void *opaque, uint64_t flags, void *data)
{
switch (flags) {
case RAM_CONTROL_BLOCK_REG:
/* TODO A later patch */
return 0;
break;
case RAM_CONTROL_HOOK:
return qemu_rdma_registration_handle(f, opaque);
default:
/* Shouldn't be called with any other values */
abort();
}
}
static int qemu_rdma_registration_start(QEMUFile *f, void *opaque,
uint64_t flags)
uint64_t flags, void *data)
{
QEMUFileRDMA *rfile = opaque;
RDMAContext *rdma = rfile->rdma;
@ -3152,7 +3168,7 @@ static int qemu_rdma_registration_start(QEMUFile *f, void *opaque,
* First, flush writes, if any.
*/
static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
uint64_t flags)
uint64_t flags, void *data)
{
Error *local_err = NULL, **errp = &local_err;
QEMUFileRDMA *rfile = opaque;
@ -3274,7 +3290,7 @@ static const QEMUFileOps rdma_read_ops = {
.get_buffer = qemu_rdma_get_buffer,
.get_fd = qemu_rdma_get_fd,
.close = qemu_rdma_close,
.hook_ram_load = qemu_rdma_registration_handle,
.hook_ram_load = rdma_load_hook,
};
static const QEMUFileOps rdma_write_ops = {

View file

@ -1439,7 +1439,7 @@ qemu_rdma_registration_handle_register_rkey(int rkey) "%x"
qemu_rdma_registration_handle_unregister(int requests) "%d requests"
qemu_rdma_registration_handle_unregister_loop(int count, int index, uint64_t chunk) "Unregistration request (%d): index %d, chunk %" PRIu64
qemu_rdma_registration_handle_unregister_success(uint64_t chunk) "%" PRIu64
qemu_rdma_registration_handle_wait(uint64_t flags) "Waiting for next request %" PRIu64
qemu_rdma_registration_handle_wait(void) ""
qemu_rdma_registration_start(uint64_t flags) "%" PRIu64
qemu_rdma_registration_stop(uint64_t flags) "%" PRIu64
qemu_rdma_registration_stop_ram(void) ""