qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael R. Hines" <mrhines@linux.vnet.ibm.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: aliguori@us.ibm.com, mst@redhat.com, qemu-devel@nongnu.org,
	owasserm@redhat.com, abali@us.ibm.com, mrhines@us.ibm.com,
	gokul@us.ibm.com
Subject: Re: [Qemu-devel] [RFC PATCH RDMA support v6: 3/7] Introduce QEMURamControlOps
Date: Wed, 10 Apr 2013 08:38:19 -0400	[thread overview]
Message-ID: <51655D3B.2040308@linux.vnet.ibm.com> (raw)
In-Reply-To: <51651A29.8030809@redhat.com>

Acknowledged.

On 04/10/2013 03:52 AM, Paolo Bonzini wrote:
> Il 10/04/2013 06:29, mrhines@linux.vnet.ibm.com ha scritto:
>> From: "Michael R. Hines" <mrhines@us.ibm.com>
>>
>> RDMA requires hooks before and after each iteration round
>> in order to coordinate the new dynamic page registration support.
>> This is done now by introducing a new set of function pointers
>> which are only used by arch_init.c.
>>
>> Pointers include:
>> 1. save_ram_page (which can be defined by anyone, not just RDMA)
>> 2. hook after each iteration
>> 3. hook before each iteration
>>
>> The pointers are then installed in savevm.c because they
>> need visibility into QEMUFile.
>>
>> Now that we have a proper set of pointers, we no longer need
>> specific checks anymore to determine whether or not RDMA
>> is enabled.
>>
>> Signed-off-by: Michael R. Hines <mrhines@us.ibm.com>
>> ---
>>   include/migration/migration.h |   52 +++++++++++++++++++++
>>   savevm.c                      |  104 +++++++++++++++++++++++++++++++++++++----
>>   2 files changed, 146 insertions(+), 10 deletions(-)
>>
>> diff --git a/include/migration/migration.h b/include/migration/migration.h
>> index e2acec6..0287321 100644
>> --- a/include/migration/migration.h
>> +++ b/include/migration/migration.h
>> @@ -21,6 +21,7 @@
>>   #include "qapi/error.h"
>>   #include "migration/vmstate.h"
>>   #include "qapi-types.h"
>> +#include "exec/cpu-common.h"
>>   
>>   struct MigrationParams {
>>       bool blk;
>> @@ -75,6 +76,10 @@ void fd_start_incoming_migration(const char *path, Error **errp);
>>   
>>   void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp);
>>   
>> +void rdma_start_outgoing_migration(void *opaque, const char *host_port, Error **errp);
>> +
>> +void rdma_start_incoming_migration(const char * host_port, Error **errp);
>> +
>>   void migrate_fd_error(MigrationState *s);
>>   
>>   void migrate_fd_connect(MigrationState *s);
>> @@ -127,4 +132,51 @@ int migrate_use_xbzrle(void);
>>   int64_t migrate_xbzrle_cache_size(void);
>>   
>>   int64_t xbzrle_cache_resize(int64_t new_size);
>> +
>> +bool migrate_check_for_zero(void);
>> +bool migrate_chunk_register_destination(void);
>> +
>> +/*
>> + * Hooks before and after each iteration round to perform special functions.
>> + * In the case of RDMA, this is to handle dynamic server registration.
>> + */
>> +#define RAM_CONTROL_SETUP    0
>> +#define RAM_CONTROL_ROUND    1
>> +#define RAM_CONTROL_REGISTER 2
>> +#define RAM_CONTROL_FINISH   3
>> +
>> +typedef void (RAMFunc)(QEMUFile *f, void *opaque, int section);
>> +
>> +struct QEMURamControlOps {
>> +    RAMFunc *before_ram_iterate;
>> +    RAMFunc *after_ram_iterate;
>> +    RAMFunc *register_ram_iterate;
>> +    size_t (*save_page)(QEMUFile *f,
>> +               void *opaque, ram_addr_t block_offset,
>> +               ram_addr_t offset, int cont, size_t size,
>> +               bool zero);
>> +};
>> +
>> +const QEMURamControlOps *qemu_savevm_get_control(QEMUFile *f);
>> +
>> +void ram_control_before_iterate(QEMUFile *f, int section);
>> +void ram_control_after_iterate(QEMUFile *f, int section);
>> +void ram_control_register_iterate(QEMUFile *f, int section);
>> +size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
>> +                                    ram_addr_t offset, int cont,
>> +                                    size_t size, bool zero);
>> +
>> +#ifdef CONFIG_RDMA
>> +extern const QEMURamControlOps qemu_rdma_control;
>> +
>> +size_t qemu_rdma_save_page(QEMUFile *f, void *opaque,
>> +                           ram_addr_t block_offset,
>> +                           ram_addr_t offset, int cont,
>> +                           size_t size, bool zero);
>> +
>> +void qemu_rdma_registration_stop(QEMUFile *f, void *opaque, int section);
>> +void qemu_rdma_registration_handle(QEMUFile *f, void *opaque, int section);
>> +void qemu_ram_registration_start(QEMUFile *f, void *opaque, int section);
>> +#endif
>> +
>>   #endif
>> diff --git a/savevm.c b/savevm.c
>> index b1d8988..26eabb3 100644
>> --- a/savevm.c
>> +++ b/savevm.c
>> @@ -409,16 +409,24 @@ static const QEMUFileOps socket_write_ops = {
>>       .close =      socket_close
>>   };
>>   
>> -QEMUFile *qemu_fopen_socket(int fd, const char *mode)
>> +bool qemu_file_mode_is_not_valid(const char * mode)
>>   {
>> -    QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
>> -
>>       if (mode == NULL ||
>>           (mode[0] != 'r' && mode[0] != 'w') ||
>>           mode[1] != 'b' || mode[2] != 0) {
>>           fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
>> -        return NULL;
>> +        return true;
>>       }
>> +
>> +    return false;
>> +}
>> +
>> +QEMUFile *qemu_fopen_socket(int fd, const char *mode)
>> +{
>> +    QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
>> +
>> +    if(qemu_file_mode_is_not_valid(mode))
>> +	return NULL;
>>   
>>       s->fd = fd;
>>       if (mode[0] == 'w') {
>> @@ -430,16 +438,44 @@ QEMUFile *qemu_fopen_socket(int fd, const char *mode)
>>       return s->file;
>>   }
>>   
>> +#ifdef CONFIG_RDMA
>> +const QEMURamControlOps qemu_rdma_write_control = {
>> +    .before_ram_iterate = qemu_ram_registration_start,
>> +    .after_ram_iterate = qemu_rdma_registration_stop,
>> +    .register_ram_iterate = qemu_rdma_registration_handle,
>> +    .save_page = qemu_rdma_save_page,
>> +};
>> +
>> +const QEMURamControlOps qemu_rdma_read_control = {
>> +    .register_ram_iterate = qemu_rdma_registration_handle,
>> +};
>> +
>> +const QEMUFileOps rdma_read_ops = {
>> +    .get_buffer  = qemu_rdma_get_buffer,
>> +    .close       = qemu_rdma_close,
>> +    .get_fd      = qemu_rdma_get_fd,
>> +    .ram_control = &qemu_rdma_read_control,
>> +};
>> +
>> +const QEMUFileOps rdma_write_ops = {
>> +    .put_buffer  = qemu_rdma_put_buffer,
>> +    .close       = qemu_rdma_close,
>> +    .get_fd      = qemu_rdma_get_fd,
>> +    .ram_control = &qemu_rdma_write_control,
>> +};
>> +#endif
>> +
>> +const QEMURamControlOps *qemu_savevm_get_control(QEMUFile *f)
>> +{
>> +    return f->ops->ram_control;
>> +}
> This function is not needed (BTW, again you do not need the new struct).
>
>>   QEMUFile *qemu_fopen(const char *filename, const char *mode)
>>   {
>>       QEMUFileStdio *s;
>>   
>> -    if (mode == NULL ||
>> -	(mode[0] != 'r' && mode[0] != 'w') ||
>> -	mode[1] != 'b' || mode[2] != 0) {
>> -        fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
>> +    if(qemu_file_mode_is_not_valid(mode))
>>           return NULL;
>> -    }
>>   
>>       s = g_malloc0(sizeof(QEMUFileStdio));
>>   
>> @@ -509,7 +545,7 @@ int qemu_file_get_error(QEMUFile *f)
>>       return f->last_error;
>>   }
>>   
>> -static void qemu_file_set_error(QEMUFile *f, int ret)
>> +void qemu_file_set_error(QEMUFile *f, int ret)
>>   {
>>       if (f->last_error == 0) {
>>           f->last_error = ret;
>> @@ -554,6 +590,54 @@ static void qemu_fflush(QEMUFile *f)
>>       }
>>   }
>>   
>> +void ram_control_before_iterate(QEMUFile *f, int section)
>> +{
>> +    const QEMURamControlOps * control = qemu_savevm_get_control(f);
>> +
>> +    if(control && control->before_ram_iterate) {
>> +        qemu_fflush(f);
>> +        control->before_ram_iterate(f, f->opaque, section);
> Please make these return an int, and set the error here.  You do not
> need to make qemu_file_set_error public.
>
>> +    }
>> +}
>> +
>> +void ram_control_after_iterate(QEMUFile *f, int section)
>> +{
>> +    const QEMURamControlOps * control = qemu_savevm_get_control(f);
>> +
>> +    if(control && control->after_ram_iterate) {
>> +        qemu_fflush(f);
>> +        control->after_ram_iterate(f, f->opaque, section);
>> +    }
>> +}
>> +
>> +void ram_control_register_iterate(QEMUFile *f, int section)
>> +{
>> +    const QEMURamControlOps * control = qemu_savevm_get_control(f);
>> +
>> +    if(control && control->register_ram_iterate) {
>> +        qemu_fflush(f);
>> +        control->register_ram_iterate(f, f->opaque, section);
>> +    }
>> +}
>> +
>> +size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
>> +                                    ram_addr_t offset, int cont,
>> +                                    size_t size, bool zero)
>> +{
>> +    const QEMURamControlOps * control = qemu_savevm_get_control(f);
>> +
>> +    if(control && control->save_page) {
>> +        size_t bytes;
>> +        qemu_fflush(f);
>> +        bytes = control->save_page(f, f->opaque, block_offset, offset, cont, size, zero);
>> +        if(bytes > 0)
>> +            f->pos += bytes;
>> +        return bytes;
>> +    }
>> +
>> +    return -ENOTSUP;
>> +}
>> +
>>   static void qemu_fill_buffer(QEMUFile *f)
>>   {
>>       int len;
>>

  reply	other threads:[~2013-04-10 12:38 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-10  4:29 [Qemu-devel] [RFC PATCH RDMA support v6: 0/7] additional cleanup and consolidation mrhines
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 1/7] ./configure and Makefile mrhines
2013-04-10  7:52   ` Paolo Bonzini
2013-04-10 12:37     ` Michael R. Hines
2013-04-10 12:42       ` Paolo Bonzini
2013-04-10 13:11         ` Michael R. Hines
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 2/7] documentation (docs/rdma.txt) mrhines
2013-04-10  5:35   ` Michael S. Tsirkin
2013-04-10 12:19     ` Michael R. Hines
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 3/7] Introduce QEMURamControlOps mrhines
2013-04-10  7:52   ` Paolo Bonzini
2013-04-10 12:38     ` Michael R. Hines [this message]
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 4/7] Introduce two new capabilities mrhines
2013-04-10  7:50   ` Paolo Bonzini
2013-04-10 12:34     ` Michael R. Hines
2013-04-10 12:40       ` Paolo Bonzini
2013-04-10 13:10         ` Michael R. Hines
2013-04-10 13:13           ` Paolo Bonzini
2013-04-10 14:03             ` Michael R. Hines
2013-04-10 12:47   ` Orit Wasserman
2013-04-10 13:13     ` Michael R. Hines
2013-04-10 13:20       ` Orit Wasserman
2013-04-10 15:52         ` Michael R. Hines
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 5/7] core RDMA logic mrhines
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 6/7] send pc.ram over RDMA mrhines
2013-04-10  7:57   ` Paolo Bonzini
2013-04-10 12:38     ` Michael R. Hines
2013-04-10  4:29 ` [Qemu-devel] [RFC PATCH RDMA support v6: 7/7] introduce qemu_ram_foreach_block() mrhines
2013-04-10  7:47   ` Paolo Bonzini
2013-04-10 12:36     ` Michael R. Hines

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51655D3B.2040308@linux.vnet.ibm.com \
    --to=mrhines@linux.vnet.ibm.com \
    --cc=abali@us.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=gokul@us.ibm.com \
    --cc=mrhines@us.ibm.com \
    --cc=mst@redhat.com \
    --cc=owasserm@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).