diff mbox

Move max-bandwidth and downtime-limit into migrate_set_parameter for both hmp and qmp

Message ID 1473097811-13519-1-git-send-email-ashijeetacharya@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ashijeet Acharya Sept. 5, 2016, 5:50 p.m. UTC
Mark old-commands for speed and downtime as deprecated.
Move max-bandwidth and downtime-limit into migrate-set-parameters for
setting maximum migration speed and expected downtime limit parameters
respectively.
Change downtime units to milliseconds and update the query part in both
hmp and qmp qemu control interfaces.

Signed-off-by: Ashijeet Acharya <ashijeetacharya@gmail.com>
---
 hmp-commands.hx               |   8 +--
 hmp.c                         |  29 +++++++++-
 include/migration/migration.h |   1 -
 migration/migration.c         | 122 +++++++++++++++++++++++++++++++-----------
 qapi-schema.json              |  37 ++++++++++---
 qmp-commands.hx               |  21 +++++---
 6 files changed, 169 insertions(+), 49 deletions(-)

Comments

Daniel P. Berrangé Sept. 5, 2016, 5:56 p.m. UTC | #1
On Mon, Sep 05, 2016 at 11:20:11PM +0530, Ashijeet Acharya wrote:
> Mark old-commands for speed and downtime as deprecated.
> Move max-bandwidth and downtime-limit into migrate-set-parameters for
> setting maximum migration speed and expected downtime limit parameters
> respectively.
> Change downtime units to milliseconds and update the query part in both
> hmp and qmp qemu control interfaces.
> 
> Signed-off-by: Ashijeet Acharya <ashijeetacharya@gmail.com>
> ---
>  hmp-commands.hx               |   8 +--
>  hmp.c                         |  29 +++++++++-
>  include/migration/migration.h |   1 -
>  migration/migration.c         | 122 +++++++++++++++++++++++++++++++-----------
>  qapi-schema.json              |  37 ++++++++++---
>  qmp-commands.hx               |  21 +++++---
>  6 files changed, 169 insertions(+), 49 deletions(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 848efee..c7f1ef9 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -980,16 +980,16 @@ ETEXI
>  
>      {
>          .name       = "migrate_set_downtime",
> -        .args_type  = "value:T",
> +        .args_type  = "value:i",
>          .params     = "value",
> -        .help       = "set maximum tolerated downtime (in seconds) for migrations",
> +        .help       = "set maximum tolerated downtime (in milliseconds) for migrations",
>          .mhandler.cmd = hmp_migrate_set_downtime,
>      },
>  
>  STEXI
> -@item migrate_set_downtime @var{second}
> +@item migrate_set_downtime @var{milliseconds}
>  @findex migrate_set_downtime
> -Set maximum tolerated downtime (in seconds) for migration.
> +Set maximum tolerated downtime (in milliseconds) for migration.
>  ETEXI

Sorry, you misunderstood - while we should use 'milliseconds' for
downtime in the 'migrate_set_parameters' command, we cannot
change the existing 'migrate_set_downtime' command. Changing that
would break compatibility with existing apps.


> diff --git a/qapi-schema.json b/qapi-schema.json
> index 5658723..66ed582 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -637,12 +637,19 @@
>  #                hostname must be provided so that the server's x509
>  #                certificate identity can be validated. (Since 2.7)
>  #
> +# @max-bandwidth: to set maximum speed for migration. maximum speed in
> +#                 bytes. (Since 2.8)

s/bytes/bytes per second/  (and elsewhere in this patch)

> +#
> +# @downtime-limit: set maximum tolerated downtime for migration. maximum downtime
> +#                  in milliseconds (Since 2.8)
> +#

Regards,
Daniel
Ashijeet Acharya Sept. 5, 2016, 6:07 p.m. UTC | #2
On Mon, Sep 5, 2016 at 11:26 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
> On Mon, Sep 05, 2016 at 11:20:11PM +0530, Ashijeet Acharya wrote:
>> Mark old-commands for speed and downtime as deprecated.
>> Move max-bandwidth and downtime-limit into migrate-set-parameters for
>> setting maximum migration speed and expected downtime limit parameters
>> respectively.
>> Change downtime units to milliseconds and update the query part in both
>> hmp and qmp qemu control interfaces.
>>
>> Signed-off-by: Ashijeet Acharya <ashijeetacharya@gmail.com>
>> ---
>>  hmp-commands.hx               |   8 +--
>>  hmp.c                         |  29 +++++++++-
>>  include/migration/migration.h |   1 -
>>  migration/migration.c         | 122 +++++++++++++++++++++++++++++++-----------
>>  qapi-schema.json              |  37 ++++++++++---
>>  qmp-commands.hx               |  21 +++++---
>>  6 files changed, 169 insertions(+), 49 deletions(-)
>>
>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>> index 848efee..c7f1ef9 100644
>> --- a/hmp-commands.hx
>> +++ b/hmp-commands.hx
>> @@ -980,16 +980,16 @@ ETEXI
>>
>>      {
>>          .name       = "migrate_set_downtime",
>> -        .args_type  = "value:T",
>> +        .args_type  = "value:i",
>>          .params     = "value",
>> -        .help       = "set maximum tolerated downtime (in seconds) for migrations",
>> +        .help       = "set maximum tolerated downtime (in milliseconds) for migrations",
>>          .mhandler.cmd = hmp_migrate_set_downtime,
>>      },
>>
>>  STEXI
>> -@item migrate_set_downtime @var{second}
>> +@item migrate_set_downtime @var{milliseconds}
>>  @findex migrate_set_downtime
>> -Set maximum tolerated downtime (in seconds) for migration.
>> +Set maximum tolerated downtime (in milliseconds) for migration.
>>  ETEXI
>
> Sorry, you misunderstood - while we should use 'milliseconds' for
> downtime in the 'migrate_set_parameters' command, we cannot
> change the existing 'migrate_set_downtime' command. Changing that
> would break compatibility with existing apps.

Oh, so that means the calculations of downtime for both the parts will
be separate at the moment and i cannot glue them together.
Unfortunately I will only be able send the updated patch by tomorrow
now. It's really late here.

Thanks
Ashijeet
>
>
>> diff --git a/qapi-schema.json b/qapi-schema.json
>> index 5658723..66ed582 100644
>> --- a/qapi-schema.json
>> +++ b/qapi-schema.json
>> @@ -637,12 +637,19 @@
>>  #                hostname must be provided so that the server's x509
>>  #                certificate identity can be validated. (Since 2.7)
>>  #
>> +# @max-bandwidth: to set maximum speed for migration. maximum speed in
>> +#                 bytes. (Since 2.8)
>
> s/bytes/bytes per second/  (and elsewhere in this patch)
>
>> +#
>> +# @downtime-limit: set maximum tolerated downtime for migration. maximum downtime
>> +#                  in milliseconds (Since 2.8)
>> +#
>
> Regards,
> Daniel
> --
> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org              -o-             http://virt-manager.org :|
> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
Ashijeet Acharya Sept. 6, 2016, 6:29 a.m. UTC | #3
On Mon, Sep 5, 2016 at 11:37 PM, Ashijeet Acharya
<ashijeetacharya@gmail.com> wrote:
> On Mon, Sep 5, 2016 at 11:26 PM, Daniel P. Berrange <berrange@redhat.com> wrote:
>> On Mon, Sep 05, 2016 at 11:20:11PM +0530, Ashijeet Acharya wrote:
>>> Mark old-commands for speed and downtime as deprecated.
>>> Move max-bandwidth and downtime-limit into migrate-set-parameters for
>>> setting maximum migration speed and expected downtime limit parameters
>>> respectively.
>>> Change downtime units to milliseconds and update the query part in both
>>> hmp and qmp qemu control interfaces.
>>>
>>> Signed-off-by: Ashijeet Acharya <ashijeetacharya@gmail.com>
>>> ---
>>>  hmp-commands.hx               |   8 +--
>>>  hmp.c                         |  29 +++++++++-
>>>  include/migration/migration.h |   1 -
>>>  migration/migration.c         | 122 +++++++++++++++++++++++++++++++-----------
>>>  qapi-schema.json              |  37 ++++++++++---
>>>  qmp-commands.hx               |  21 +++++---
>>>  6 files changed, 169 insertions(+), 49 deletions(-)
>>>
>>> diff --git a/hmp-commands.hx b/hmp-commands.hx
>>> index 848efee..c7f1ef9 100644
>>> --- a/hmp-commands.hx
>>> +++ b/hmp-commands.hx
>>> @@ -980,16 +980,16 @@ ETEXI
>>>
>>>      {
>>>          .name       = "migrate_set_downtime",
>>> -        .args_type  = "value:T",
>>> +        .args_type  = "value:i",
>>>          .params     = "value",
>>> -        .help       = "set maximum tolerated downtime (in seconds) for migrations",
>>> +        .help       = "set maximum tolerated downtime (in milliseconds) for migrations",
>>>          .mhandler.cmd = hmp_migrate_set_downtime,
>>>      },
>>>
>>>  STEXI
>>> -@item migrate_set_downtime @var{second}
>>> +@item migrate_set_downtime @var{milliseconds}
>>>  @findex migrate_set_downtime
>>> -Set maximum tolerated downtime (in seconds) for migration.
>>> +Set maximum tolerated downtime (in milliseconds) for migration.
>>>  ETEXI
>>
>> Sorry, you misunderstood - while we should use 'milliseconds' for
>> downtime in the 'migrate_set_parameters' command, we cannot
>> change the existing 'migrate_set_downtime' command. Changing that
>> would break compatibility with existing apps.
>
> Oh, so that means the calculations of downtime for both the parts will
> be separate at the moment and i cannot glue them together.
> Unfortunately I will only be able send the updated patch by tomorrow
> now. It's really late here.
>
> Thanks
> Ashijeet

I had one more query since you mentioned the backwards compatibility
issue, regarding the bandwidth part.
Should I drop the rounding of -ve speed values to zero for both or
just the new-commands.

Ashijeet
>>
>>
>>> diff --git a/qapi-schema.json b/qapi-schema.json
>>> index 5658723..66ed582 100644
>>> --- a/qapi-schema.json
>>> +++ b/qapi-schema.json
>>> @@ -637,12 +637,19 @@
>>>  #                hostname must be provided so that the server's x509
>>>  #                certificate identity can be validated. (Since 2.7)
>>>  #
>>> +# @max-bandwidth: to set maximum speed for migration. maximum speed in
>>> +#                 bytes. (Since 2.8)
>>
>> s/bytes/bytes per second/  (and elsewhere in this patch)
>>
>>> +#
>>> +# @downtime-limit: set maximum tolerated downtime for migration. maximum downtime
>>> +#                  in milliseconds (Since 2.8)
>>> +#
>>
>> Regards,
>> Daniel
>> --
>> |: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
>> |: http://libvirt.org              -o-             http://virt-manager.org :|
>> |: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
>> |: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|
diff mbox

Patch

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 848efee..c7f1ef9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -980,16 +980,16 @@  ETEXI
 
     {
         .name       = "migrate_set_downtime",
-        .args_type  = "value:T",
+        .args_type  = "value:i",
         .params     = "value",
-        .help       = "set maximum tolerated downtime (in seconds) for migrations",
+        .help       = "set maximum tolerated downtime (in milliseconds) for migrations",
         .mhandler.cmd = hmp_migrate_set_downtime,
     },
 
 STEXI
-@item migrate_set_downtime @var{second}
+@item migrate_set_downtime @var{milliseconds}
 @findex migrate_set_downtime
-Set maximum tolerated downtime (in seconds) for migration.
+Set maximum tolerated downtime (in milliseconds) for migration.
 ETEXI
 
     {
diff --git a/hmp.c b/hmp.c
index cc2056e..e5effca 100644
--- a/hmp.c
+++ b/hmp.c
@@ -304,6 +304,12 @@  void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict)
         monitor_printf(mon, " %s: '%s'",
             MigrationParameter_lookup[MIGRATION_PARAMETER_TLS_HOSTNAME],
             params->tls_hostname ? : "");
+        monitor_printf(mon, " %s: %" PRId64,
+            MigrationParameter_lookup[MIGRATION_PARAMETER_MAX_BANDWIDTH],
+            params->max_bandwidth);
+        monitor_printf(mon, " %s: %" PRId64,
+            MigrationParameter_lookup[MIGRATION_PARAMETER_DOWNTIME_LIMIT],
+            params->downtime_limit);
         monitor_printf(mon, "\n");
     }
 
@@ -1193,9 +1199,10 @@  void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, &err);
 }
 
+/* Kept for old-commands compatibility */
 void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
 {
-    double value = qdict_get_double(qdict, "value");
+    int64_t value = qdict_get_int(qdict, "value");
     qmp_migrate_set_downtime(value, NULL);
 }
 
@@ -1211,6 +1218,7 @@  void hmp_migrate_set_cache_size(Monitor *mon, const QDict *qdict)
     }
 }
 
+/* Kept for old-commands compatibility */
 void hmp_migrate_set_speed(Monitor *mon, const QDict *qdict)
 {
     int64_t value = qdict_get_int(qdict, "value");
@@ -1251,7 +1259,9 @@  void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
 {
     const char *param = qdict_get_str(qdict, "parameter");
     const char *valuestr = qdict_get_str(qdict, "value");
+    int64_t valuebw = 0;
     long valueint = 0;
+    char *endp;
     Error *err = NULL;
     bool has_compress_level = false;
     bool has_compress_threads = false;
@@ -1260,6 +1270,8 @@  void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
     bool has_cpu_throttle_increment = false;
     bool has_tls_creds = false;
     bool has_tls_hostname = false;
+    bool has_max_bandwidth = false;
+    bool has_downtime_limit = false;
     bool use_int_value = false;
     int i;
 
@@ -1291,6 +1303,19 @@  void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
             case MIGRATION_PARAMETER_TLS_HOSTNAME:
                 has_tls_hostname = true;
                 break;
+            case MIGRATION_PARAMETER_MAX_BANDWIDTH:
+                has_max_bandwidth = true;
+                valuebw = qemu_strtosz(valuestr, &endp);
+                if (valuebw < 0 || (size_t)valuebw != valuebw || *endp != '\0'
+                    || !is_power_of_2(valuebw)) {
+                    error_setg(&err, "Invalid size %s", valuestr);
+                    goto cleanup;
+                }
+                break;
+            case MIGRATION_PARAMETER_DOWNTIME_LIMIT:
+                has_downtime_limit = true;
+                use_int_value = true;
+                break;
             }
 
             if (use_int_value) {
@@ -1308,6 +1333,8 @@  void hmp_migrate_set_parameter(Monitor *mon, const QDict *qdict)
                                        has_cpu_throttle_increment, valueint,
                                        has_tls_creds, valuestr,
                                        has_tls_hostname, valuestr,
+                                       has_max_bandwidth, valuebw,
+                                       has_downtime_limit, valueint,
                                        &err);
             break;
         }
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 3c96623..a5429ee 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -129,7 +129,6 @@  struct MigrationSrcPageRequest {
 
 struct MigrationState
 {
-    int64_t bandwidth_limit;
     size_t bytes_xfer;
     size_t xfer_limit;
     QemuThread thread;
diff --git a/migration/migration.c b/migration/migration.c
index 955d5ee..832335d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -44,6 +44,9 @@ 
 #define BUFFER_DELAY     100
 #define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)
 
+/* Amount of nanoseconds we are willing to wait for migration to be down. */
+#define DEFAULT_MIGRATE_SET_DOWNTIME 300000000
+
 /* Default compression thread count */
 #define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
 /* Default decompression thread count, usually decompression is at
@@ -80,7 +83,6 @@  MigrationState *migrate_get_current(void)
     static bool once;
     static MigrationState current_migration = {
         .state = MIGRATION_STATUS_NONE,
-        .bandwidth_limit = MAX_THROTTLE,
         .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
         .mbps = -1,
         .parameters = {
@@ -89,6 +91,8 @@  MigrationState *migrate_get_current(void)
             .decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
             .cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,
             .cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,
+            .max_bandwidth = MAX_THROTTLE,
+            .downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME,
         },
     };
 
@@ -566,6 +570,8 @@  MigrationParameters *qmp_query_migrate_parameters(Error **errp)
     params->cpu_throttle_increment = s->parameters.cpu_throttle_increment;
     params->tls_creds = g_strdup(s->parameters.tls_creds);
     params->tls_hostname = g_strdup(s->parameters.tls_hostname);
+    params->max_bandwidth = s->parameters.max_bandwidth;
+    params->downtime_limit = s->parameters.downtime_limit / 1000000;
 
     return params;
 }
@@ -642,7 +648,7 @@  MigrationInfo *qmp_query_migrate(Error **errp)
         info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
             - s->total_time;
         info->has_expected_downtime = true;
-        info->expected_downtime = s->expected_downtime;
+        info->expected_downtime = s->expected_downtime / 1000;
         info->has_setup_time = true;
         info->setup_time = s->setup_time;
 
@@ -670,7 +676,7 @@  MigrationInfo *qmp_query_migrate(Error **errp)
         info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
             - s->total_time;
         info->has_expected_downtime = true;
-        info->expected_downtime = s->expected_downtime;
+        info->expected_downtime = s->expected_downtime / 1000;
         info->has_setup_time = true;
         info->setup_time = s->setup_time;
 
@@ -773,6 +779,10 @@  void qmp_migrate_set_parameters(bool has_compress_level,
                                 const char *tls_creds,
                                 bool has_tls_hostname,
                                 const char *tls_hostname,
+                                bool has_max_bandwidth,
+                                int64_t max_bandwidth,
+                                bool has_downtime_limit,
+                                int64_t downtime_limit,
                                 Error **errp)
 {
     MigrationState *s = migrate_get_current();
@@ -808,6 +818,12 @@  void qmp_migrate_set_parameters(bool has_compress_level,
                    "cpu_throttle_increment",
                    "an integer in the range of 1 to 99");
     }
+    if (has_max_bandwidth &&
+            (max_bandwidth < 0 || max_bandwidth > SIZE_MAX)) {
+        error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+                   "max_bandwidth",
+                   "invalid value");
+    }
 
     if (has_compress_level) {
         s->parameters.compress_level = compress_level;
@@ -832,6 +848,22 @@  void qmp_migrate_set_parameters(bool has_compress_level,
         g_free(s->parameters.tls_hostname);
         s->parameters.tls_hostname = g_strdup(tls_hostname);
     }
+    if (has_max_bandwidth) {
+        s->parameters.max_bandwidth = max_bandwidth;
+        if (s->to_dst_file) {
+            qemu_file_set_rate_limit(s->to_dst_file,
+                                s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
+        }
+    }
+    if (has_downtime_limit) {
+        downtime_limit *= 1e6;
+        downtime_limit = MAX(0, MIN(INT64_MAX, downtime_limit));
+
+        s = migrate_get_current();
+
+        max_downtime = downtime_limit;
+        s->parameters.downtime_limit = max_downtime;
+    }
 }
 
 
@@ -1163,30 +1195,60 @@  int64_t qmp_query_migrate_cache_size(Error **errp)
     return migrate_xbzrle_cache_size();
 }
 
-void qmp_migrate_set_speed(int64_t value, Error **errp)
-{
-    MigrationState *s;
-
-    if (value < 0) {
-        value = 0;
-    }
-    if (value > SIZE_MAX) {
-        value = SIZE_MAX;
-    }
-
-    s = migrate_get_current();
-    s->bandwidth_limit = value;
-    if (s->to_dst_file) {
-        qemu_file_set_rate_limit(s->to_dst_file,
-                                 s->bandwidth_limit / XFER_LIMIT_RATIO);
-    }
-}
-
-void qmp_migrate_set_downtime(double value, Error **errp)
-{
-    value *= 1e9;
-    value = MAX(0, MIN(UINT64_MAX, value));
-    max_downtime = (uint64_t)value;
+void qmp_migrate_set_speed(int64_t valuebw, Error **errp)
+{
+    bool has_compress_level = false;
+    bool has_compress_threads = false;
+    bool has_decompress_threads = false;
+    bool has_cpu_throttle_initial = false;
+    bool has_cpu_throttle_increment = false;
+    bool has_tls_creds = false;
+    bool has_tls_hostname = false;
+    bool has_max_bandwidth = true;
+    bool has_downtime_limit = false;
+    const char *valuestr = NULL;
+    long valueint = 0;
+    Error *err = NULL;
+
+    qmp_migrate_set_parameters(has_compress_level, valueint,
+                               has_compress_threads, valueint,
+                               has_decompress_threads, valueint,
+                               has_cpu_throttle_initial, valueint,
+                               has_cpu_throttle_increment, valueint,
+                               has_tls_creds, valuestr,
+                               has_tls_hostname, valuestr,
+                               has_max_bandwidth, valuebw,
+                               has_downtime_limit, valueint,
+                               &err);
+
+}
+
+void qmp_migrate_set_downtime(int64_t valuedowntime, Error **errp)
+{
+    bool has_compress_level = false;
+    bool has_compress_threads = false;
+    bool has_decompress_threads = false;
+    bool has_cpu_throttle_initial = false;
+    bool has_cpu_throttle_increment = false;
+    bool has_tls_creds = false;
+    bool has_tls_hostname = false;
+    bool has_max_bandwidth = false;
+    bool has_downtime_limit = true;
+    const char *valuestr = NULL;
+    long valueint = 0;
+    int64_t valuebw = 0;
+    Error *err = NULL;
+
+    qmp_migrate_set_parameters(has_compress_level, valueint,
+                               has_compress_threads, valueint,
+                               has_decompress_threads, valueint,
+                               has_cpu_throttle_initial, valueint,
+                               has_cpu_throttle_increment, valueint,
+                               has_tls_creds, valuestr,
+                               has_tls_hostname, valuestr,
+                               has_max_bandwidth, valuebw,
+                               has_downtime_limit, valuedowntime,
+                               &err);
 }
 
 bool migrate_postcopy_ram(void)
@@ -1793,7 +1855,7 @@  static void *migration_thread(void *opaque)
                                          initial_bytes;
             uint64_t time_spent = current_time - initial_time;
             double bandwidth = (double)transferred_bytes / time_spent;
-            max_size = bandwidth * migrate_max_downtime() / 1000000;
+            max_size = bandwidth * migrate_max_downtime() / 1000;
 
             s->mbps = (((double) transferred_bytes * 8.0) /
                     ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
@@ -1853,12 +1915,12 @@  static void *migration_thread(void *opaque)
 void migrate_fd_connect(MigrationState *s)
 {
     /* This is a best 1st approximation. ns to ms */
-    s->expected_downtime = max_downtime/1000000;
+    s->expected_downtime = max_downtime / 1000;
     s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
 
     qemu_file_set_blocking(s->to_dst_file, true);
     qemu_file_set_rate_limit(s->to_dst_file,
-                             s->bandwidth_limit / XFER_LIMIT_RATIO);
+                             s->parameters.max_bandwidth / XFER_LIMIT_RATIO);
 
     /* Notify before starting migration thread */
     notifier_list_notify(&migration_state_notifiers, s);
diff --git a/qapi-schema.json b/qapi-schema.json
index 5658723..66ed582 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -637,12 +637,19 @@ 
 #                hostname must be provided so that the server's x509
 #                certificate identity can be validated. (Since 2.7)
 #
+# @max-bandwidth: to set maximum speed for migration. maximum speed in
+#                 bytes. (Since 2.8)
+#
+# @downtime-limit: set maximum tolerated downtime for migration. maximum downtime
+#                  in milliseconds (Since 2.8)
+#
 # Since: 2.4
 ##
 { 'enum': 'MigrationParameter',
   'data': ['compress-level', 'compress-threads', 'decompress-threads',
            'cpu-throttle-initial', 'cpu-throttle-increment',
-           'tls-creds', 'tls-hostname'] }
+           'tls-creds', 'tls-hostname', 'max-bandwidth',
+           'downtime-limit'] }
 
 #
 # @migrate-set-parameters
@@ -678,6 +685,12 @@ 
 #                hostname must be provided so that the server's x509
 #                certificate identity can be validated. (Since 2.7)
 #
+# @max-bandwidth: to set maximum speed for migration. maximum speed in
+#                 bytes. (Since 2.8)
+#
+# @downtime-limit: set maximum tolerated downtime for migration. maximum downtime
+#                  in milliseconds (Since 2.8)
+#
 # Since: 2.4
 ##
 { 'command': 'migrate-set-parameters',
@@ -687,7 +700,9 @@ 
             '*cpu-throttle-initial': 'int',
             '*cpu-throttle-increment': 'int',
             '*tls-creds': 'str',
-            '*tls-hostname': 'str'} }
+            '*tls-hostname': 'str',
+            '*max-bandwidth': 'int',
+            '*downtime-limit': 'int'} }
 
 #
 # @MigrationParameters
@@ -721,6 +736,12 @@ 
 #                hostname must be provided so that the server's x509
 #                certificate identity can be validated. (Since 2.7)
 #
+# @max-bandwidth: to set maximum speed for migration. maximum speed in
+#                 bytes. (Since 2.8)
+#
+# @downtime-limit: set maximum tolerated downtime for migration. maximum downtime
+#                  in milliseconds (Since 2.8)
+#
 # Since: 2.4
 ##
 { 'struct': 'MigrationParameters',
@@ -730,7 +751,9 @@ 
             'cpu-throttle-initial': 'int',
             'cpu-throttle-increment': 'int',
             'tls-creds': 'str',
-            'tls-hostname': 'str'} }
+            'tls-hostname': 'str',
+            'max-bandwidth': 'int',
+            'downtime-limit': 'int'} }
 ##
 # @query-migrate-parameters
 #
@@ -1808,13 +1831,15 @@ 
 #
 # Set maximum tolerated downtime for migration.
 #
-# @value: maximum downtime in seconds
+# @value: maximum downtime in milliseconds
 #
 # Returns: nothing on success
 #
+# Notes: This command is deprecated in favour of 'migrate-set-parameters'
+#
 # Since: 0.14.0
 ##
-{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }
+{ 'command': 'migrate_set_downtime', 'data': {'value': 'int'} }
 
 ##
 # @migrate_set_speed
@@ -1825,7 +1850,7 @@ 
 #
 # Returns: nothing on success
 #
-# Notes: A value lesser than zero will be automatically round up to zero.
+# Notes: This command is deprecated in favour of 'migrate-set-parameters'
 #
 # Since: 0.14.0
 ##
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 6866264..8416674 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -808,7 +808,7 @@  EQMP
 
     {
         .name       = "migrate_set_downtime",
-        .args_type  = "value:T",
+        .args_type  = "value:i",
         .mhandler.cmd_new = qmp_marshal_migrate_set_downtime,
     },
 
@@ -816,15 +816,15 @@  SQMP
 migrate_set_downtime
 --------------------
 
-Set maximum tolerated downtime (in seconds) for migrations.
+Set maximum tolerated downtime (in milliseconds) for migrations.
 
 Arguments:
 
-- "value": maximum downtime (json-number)
+- "value": maximum downtime (json-int)
 
 Example:
 
--> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } }
+-> { "execute": "migrate_set_downtime", "arguments": { "value": 100 } }
 <- { "return": {} }
 
 EQMP
@@ -3790,7 +3790,9 @@  Set migration parameters
                           throttled for auto-converge (json-int)
 - "cpu-throttle-increment": set throttle increasing percentage for
                             auto-converge (json-int)
-
+- "max-bandwidth": set maximum speed for migrations (in bytes) (json-int)
+- "downtime-limit": set maximum tolerated downtime (in milliseconds) for
+                          migrations (json-int)
 Arguments:
 
 Example:
@@ -3803,7 +3805,7 @@  EQMP
     {
         .name       = "migrate-set-parameters",
         .args_type  =
-            "compress-level:i?,compress-threads:i?,decompress-threads:i?,cpu-throttle-initial:i?,cpu-throttle-increment:i?",
+            "compress-level:i?,compress-threads:i?,decompress-threads:i?,cpu-throttle-initial:i?,cpu-throttle-increment:i?,max-bandwidth:i?,downtime-limit:i?",
         .mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
     },
 SQMP
@@ -3820,6 +3822,9 @@  Query current migration parameters
                                     throttled (json-int)
          - "cpu-throttle-increment" : throttle increasing percentage for
                                       auto-converge (json-int)
+         - "max-bandwidth" : maximium migration speed (json-int)
+         - "downtime-limit" : maximum tolerated downtime of migration
+                                      (json-int)
 
 Arguments:
 
@@ -3832,7 +3837,9 @@  Example:
          "cpu-throttle-increment": 10,
          "compress-threads": 8,
          "compress-level": 1,
-         "cpu-throttle-initial": 20
+         "cpu-throttle-initial": 20,
+         "max-downtime": 33554432,
+         "downtime-limit": 300
       }
    }