44
44
#define BUFFER_DELAY 100
45
45
#define XFER_LIMIT_RATIO (1000 / BUFFER_DELAY)
46
46
47
+ /* Time in milliseconds we are allowed to stop the source,
48
+ * for sending the last part */
49
+ #define DEFAULT_MIGRATE_SET_DOWNTIME 300
50
+
47
51
/* Default compression thread count */
48
52
#define DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT 8
49
53
/* Default decompression thread count, usually decompression is at
@@ -80,7 +84,6 @@ MigrationState *migrate_get_current(void)
80
84
static bool once ;
81
85
static MigrationState current_migration = {
82
86
.state = MIGRATION_STATUS_NONE ,
83
- .bandwidth_limit = MAX_THROTTLE ,
84
87
.xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE ,
85
88
.mbps = -1 ,
86
89
.parameters = {
@@ -89,6 +92,8 @@ MigrationState *migrate_get_current(void)
89
92
.decompress_threads = DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT ,
90
93
.cpu_throttle_initial = DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL ,
91
94
.cpu_throttle_increment = DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT ,
95
+ .max_bandwidth = MAX_THROTTLE ,
96
+ .downtime_limit = DEFAULT_MIGRATE_SET_DOWNTIME ,
92
97
},
93
98
};
94
99
@@ -517,17 +522,6 @@ void migrate_send_rp_pong(MigrationIncomingState *mis,
517
522
migrate_send_rp_message (mis , MIG_RP_MSG_PONG , sizeof (buf ), & buf );
518
523
}
519
524
520
- /* amount of nanoseconds we are willing to wait for migration to be down.
521
- * the choice of nanoseconds is because it is the maximum resolution that
522
- * get_clock() can achieve. It is an internal measure. All user-visible
523
- * units must be in seconds */
524
- static uint64_t max_downtime = 300000000 ;
525
-
526
- uint64_t migrate_max_downtime (void )
527
- {
528
- return max_downtime ;
529
- }
530
-
531
525
MigrationCapabilityStatusList * qmp_query_migrate_capabilities (Error * * errp )
532
526
{
533
527
MigrationCapabilityStatusList * head = NULL ;
@@ -573,6 +567,10 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
573
567
params -> tls_creds = g_strdup (s -> parameters .tls_creds );
574
568
params -> has_tls_hostname = !!s -> parameters .tls_hostname ;
575
569
params -> tls_hostname = g_strdup (s -> parameters .tls_hostname );
570
+ params -> has_max_bandwidth = true;
571
+ params -> max_bandwidth = s -> parameters .max_bandwidth ;
572
+ params -> has_downtime_limit = true;
573
+ params -> downtime_limit = s -> parameters .downtime_limit ;
576
574
577
575
return params ;
578
576
}
@@ -806,6 +804,19 @@ void qmp_migrate_set_parameters(MigrationParameters *params, Error **errp)
806
804
"an integer in the range of 1 to 99" );
807
805
return ;
808
806
}
807
+ if (params -> has_max_bandwidth &&
808
+ (params -> max_bandwidth < 0 || params -> max_bandwidth > SIZE_MAX )) {
809
+ error_setg (errp , "Parameter 'max_bandwidth' expects an integer in the"
810
+ " range of 0 to %zu bytes/second" , SIZE_MAX );
811
+ return ;
812
+ }
813
+ if (params -> has_downtime_limit &&
814
+ (params -> downtime_limit < 0 || params -> downtime_limit > 2000000 )) {
815
+ error_setg (errp , QERR_INVALID_PARAMETER_VALUE ,
816
+ "downtime_limit" ,
817
+ "an integer in the range of 0 to 2000000 milliseconds" );
818
+ return ;
819
+ }
809
820
810
821
if (params -> has_compress_level ) {
811
822
s -> parameters .compress_level = params -> compress_level ;
@@ -830,6 +841,16 @@ void qmp_migrate_set_parameters(MigrationParameters *params, Error **errp)
830
841
g_free (s -> parameters .tls_hostname );
831
842
s -> parameters .tls_hostname = g_strdup (params -> tls_hostname );
832
843
}
844
+ if (params -> has_max_bandwidth ) {
845
+ s -> parameters .max_bandwidth = params -> max_bandwidth ;
846
+ if (s -> to_dst_file ) {
847
+ qemu_file_set_rate_limit (s -> to_dst_file ,
848
+ s -> parameters .max_bandwidth / XFER_LIMIT_RATIO );
849
+ }
850
+ }
851
+ if (params -> has_downtime_limit ) {
852
+ s -> parameters .downtime_limit = params -> downtime_limit ;
853
+ }
833
854
}
834
855
835
856
@@ -1163,28 +1184,25 @@ int64_t qmp_query_migrate_cache_size(Error **errp)
1163
1184
1164
1185
void qmp_migrate_set_speed (int64_t value , Error * * errp )
1165
1186
{
1166
- MigrationState * s ;
1167
-
1168
- if (value < 0 ) {
1169
- value = 0 ;
1170
- }
1171
- if (value > SIZE_MAX ) {
1172
- value = SIZE_MAX ;
1173
- }
1187
+ MigrationParameters p = {
1188
+ .has_max_bandwidth = true,
1189
+ .max_bandwidth = value ,
1190
+ };
1174
1191
1175
- s = migrate_get_current ();
1176
- s -> bandwidth_limit = value ;
1177
- if (s -> to_dst_file ) {
1178
- qemu_file_set_rate_limit (s -> to_dst_file ,
1179
- s -> bandwidth_limit / XFER_LIMIT_RATIO );
1180
- }
1192
+ qmp_migrate_set_parameters (& p , errp );
1181
1193
}
1182
1194
1183
1195
void qmp_migrate_set_downtime (double value , Error * * errp )
1184
1196
{
1185
- value *= 1e9 ;
1186
- value = MAX (0 , MIN (UINT64_MAX , value ));
1187
- max_downtime = (uint64_t )value ;
1197
+ value *= 1000 ; /* Convert to milliseconds */
1198
+ value = MAX (0 , MIN (INT64_MAX , value ));
1199
+
1200
+ MigrationParameters p = {
1201
+ .has_downtime_limit = true,
1202
+ .downtime_limit = value ,
1203
+ };
1204
+
1205
+ qmp_migrate_set_parameters (& p , errp );
1188
1206
}
1189
1207
1190
1208
bool migrate_postcopy_ram (void )
@@ -1791,7 +1809,7 @@ static void *migration_thread(void *opaque)
1791
1809
initial_bytes ;
1792
1810
uint64_t time_spent = current_time - initial_time ;
1793
1811
double bandwidth = (double )transferred_bytes / time_spent ;
1794
- max_size = bandwidth * migrate_max_downtime () / 1000000 ;
1812
+ max_size = bandwidth * s -> parameters . downtime_limit ;
1795
1813
1796
1814
s -> mbps = (((double ) transferred_bytes * 8.0 ) /
1797
1815
((double ) time_spent / 1000.0 )) / 1000.0 / 1000.0 ;
@@ -1850,13 +1868,12 @@ static void *migration_thread(void *opaque)
1850
1868
1851
1869
void migrate_fd_connect (MigrationState * s )
1852
1870
{
1853
- /* This is a best 1st approximation. ns to ms */
1854
- s -> expected_downtime = max_downtime /1000000 ;
1871
+ s -> expected_downtime = s -> parameters .downtime_limit ;
1855
1872
s -> cleanup_bh = qemu_bh_new (migrate_fd_cleanup , s );
1856
1873
1857
1874
qemu_file_set_blocking (s -> to_dst_file , true);
1858
1875
qemu_file_set_rate_limit (s -> to_dst_file ,
1859
- s -> bandwidth_limit / XFER_LIMIT_RATIO );
1876
+ s -> parameters . max_bandwidth / XFER_LIMIT_RATIO );
1860
1877
1861
1878
/* Notify before starting migration thread */
1862
1879
notifier_list_notify (& migration_state_notifiers , s );
0 commit comments