Revisão | cf2d4aa8a276f8540eef593141b7933487fa32b2 (tree) |
---|---|
Hora | 2022-01-28 23:38:23 |
Autor | Juan Quintela <quintela@redh...> |
Commiter | Juan Quintela |
multifd: Use normal pages array on the recv side
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
Rename num_normal_pages to total_normal_pages (peter)
@@ -225,7 +225,7 @@ static int zlib_recv_pages(MultiFDRecvParams *p, Error **errp) | ||
225 | 225 | uint32_t in_size = p->next_packet_size; |
226 | 226 | /* we measure the change of total_out */ |
227 | 227 | uint32_t out_size = zs->total_out; |
228 | - uint32_t expected_size = p->pages->num * qemu_target_page_size(); | |
228 | + uint32_t expected_size = p->normal_num * page_size; | |
229 | 229 | uint32_t flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK; |
230 | 230 | int ret; |
231 | 231 | int i; |
@@ -244,16 +244,16 @@ static int zlib_recv_pages(MultiFDRecvParams *p, Error **errp) | ||
244 | 244 | zs->avail_in = in_size; |
245 | 245 | zs->next_in = z->zbuff; |
246 | 246 | |
247 | - for (i = 0; i < p->pages->num; i++) { | |
247 | + for (i = 0; i < p->normal_num; i++) { | |
248 | 248 | int flush = Z_NO_FLUSH; |
249 | 249 | unsigned long start = zs->total_out; |
250 | 250 | |
251 | - if (i == p->pages->num - 1) { | |
251 | + if (i == p->normal_num - 1) { | |
252 | 252 | flush = Z_SYNC_FLUSH; |
253 | 253 | } |
254 | 254 | |
255 | 255 | zs->avail_out = page_size; |
256 | - zs->next_out = p->pages->block->host + p->pages->offset[i]; | |
256 | + zs->next_out = p->pages->block->host + p->normal[i]; | |
257 | 257 | |
258 | 258 | /* |
259 | 259 | * Welcome to inflate semantics |
@@ -242,7 +242,7 @@ static int zstd_recv_pages(MultiFDRecvParams *p, Error **errp) | ||
242 | 242 | uint32_t in_size = p->next_packet_size; |
243 | 243 | uint32_t out_size = 0; |
244 | 244 | size_t page_size = qemu_target_page_size(); |
245 | - uint32_t expected_size = p->pages->num * page_size; | |
245 | + uint32_t expected_size = p->normal_num * page_size; | |
246 | 246 | uint32_t flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK; |
247 | 247 | struct zstd_data *z = p->data; |
248 | 248 | int ret; |
@@ -263,8 +263,8 @@ static int zstd_recv_pages(MultiFDRecvParams *p, Error **errp) | ||
263 | 263 | z->in.size = in_size; |
264 | 264 | z->in.pos = 0; |
265 | 265 | |
266 | - for (i = 0; i < p->pages->num; i++) { | |
267 | - z->out.dst = p->pages->block->host + p->pages->offset[i]; | |
266 | + for (i = 0; i < p->normal_num; i++) { | |
267 | + z->out.dst = p->pages->block->host + p->normal[i]; | |
268 | 268 | z->out.size = page_size; |
269 | 269 | z->out.pos = 0; |
270 | 270 |
@@ -146,11 +146,11 @@ static int nocomp_recv_pages(MultiFDRecvParams *p, Error **errp) | ||
146 | 146 | p->id, flags, MULTIFD_FLAG_NOCOMP); |
147 | 147 | return -1; |
148 | 148 | } |
149 | - for (int i = 0; i < p->pages->num; i++) { | |
150 | - p->iov[i].iov_base = p->pages->block->host + p->pages->offset[i]; | |
149 | + for (int i = 0; i < p->normal_num; i++) { | |
150 | + p->iov[i].iov_base = p->pages->block->host + p->normal[i]; | |
151 | 151 | p->iov[i].iov_len = page_size; |
152 | 152 | } |
153 | - return qio_channel_readv_all(p->c, p->iov, p->pages->num, errp); | |
153 | + return qio_channel_readv_all(p->c, p->iov, p->normal_num, errp); | |
154 | 154 | } |
155 | 155 | |
156 | 156 | static MultiFDMethods multifd_nocomp_ops = { |
@@ -282,7 +282,7 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) | ||
282 | 282 | { |
283 | 283 | MultiFDPacket_t *packet = p->packet; |
284 | 284 | size_t page_size = qemu_target_page_size(); |
285 | - uint32_t pages_max = MULTIFD_PACKET_SIZE / page_size; | |
285 | + uint32_t page_count = MULTIFD_PACKET_SIZE / page_size; | |
286 | 286 | RAMBlock *block; |
287 | 287 | int i; |
288 | 288 |
@@ -309,33 +309,25 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) | ||
309 | 309 | * If we received a packet that is 100 times bigger than expected |
310 | 310 | * just stop migration. It is a magic number. |
311 | 311 | */ |
312 | - if (packet->pages_alloc > pages_max * 100) { | |
312 | + if (packet->pages_alloc > page_count) { | |
313 | 313 | error_setg(errp, "multifd: received packet " |
314 | - "with size %u and expected a maximum size of %u", | |
315 | - packet->pages_alloc, pages_max * 100) ; | |
314 | + "with size %u and expected a size of %u", | |
315 | + packet->pages_alloc, page_count) ; | |
316 | 316 | return -1; |
317 | 317 | } |
318 | - /* | |
319 | - * We received a packet that is bigger than expected but inside | |
320 | - * reasonable limits (see previous comment). Just reallocate. | |
321 | - */ | |
322 | - if (packet->pages_alloc > p->pages->allocated) { | |
323 | - multifd_pages_clear(p->pages); | |
324 | - p->pages = multifd_pages_init(packet->pages_alloc); | |
325 | - } | |
326 | 318 | |
327 | - p->pages->num = be32_to_cpu(packet->pages_used); | |
328 | - if (p->pages->num > packet->pages_alloc) { | |
319 | + p->normal_num = be32_to_cpu(packet->pages_used); | |
320 | + if (p->normal_num > packet->pages_alloc) { | |
329 | 321 | error_setg(errp, "multifd: received packet " |
330 | 322 | "with %u pages and expected maximum pages are %u", |
331 | - p->pages->num, packet->pages_alloc) ; | |
323 | + p->normal_num, packet->pages_alloc) ; | |
332 | 324 | return -1; |
333 | 325 | } |
334 | 326 | |
335 | 327 | p->next_packet_size = be32_to_cpu(packet->next_packet_size); |
336 | 328 | p->packet_num = be64_to_cpu(packet->packet_num); |
337 | 329 | |
338 | - if (p->pages->num == 0) { | |
330 | + if (p->normal_num == 0) { | |
339 | 331 | return 0; |
340 | 332 | } |
341 | 333 |
@@ -349,7 +341,7 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) | ||
349 | 341 | } |
350 | 342 | |
351 | 343 | p->pages->block = block; |
352 | - for (i = 0; i < p->pages->num; i++) { | |
344 | + for (i = 0; i < p->normal_num; i++) { | |
353 | 345 | uint64_t offset = be64_to_cpu(packet->offset[i]); |
354 | 346 | |
355 | 347 | if (offset > (block->used_length - page_size)) { |
@@ -358,7 +350,7 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp) | ||
358 | 350 | offset, block->used_length); |
359 | 351 | return -1; |
360 | 352 | } |
361 | - p->pages->offset[i] = offset; | |
353 | + p->normal[i] = offset; | |
362 | 354 | } |
363 | 355 | |
364 | 356 | return 0; |
@@ -1022,6 +1014,8 @@ int multifd_load_cleanup(Error **errp) | ||
1022 | 1014 | p->packet = NULL; |
1023 | 1015 | g_free(p->iov); |
1024 | 1016 | p->iov = NULL; |
1017 | + g_free(p->normal); | |
1018 | + p->normal = NULL; | |
1025 | 1019 | multifd_recv_state->ops->recv_cleanup(p); |
1026 | 1020 | } |
1027 | 1021 | qemu_sem_destroy(&multifd_recv_state->sem_sync); |
@@ -1095,13 +1089,13 @@ static void *multifd_recv_thread(void *opaque) | ||
1095 | 1089 | flags = p->flags; |
1096 | 1090 | /* recv methods don't know how to handle the SYNC flag */ |
1097 | 1091 | p->flags &= ~MULTIFD_FLAG_SYNC; |
1098 | - trace_multifd_recv(p->id, p->packet_num, p->pages->num, flags, | |
1092 | + trace_multifd_recv(p->id, p->packet_num, p->normal_num, flags, | |
1099 | 1093 | p->next_packet_size); |
1100 | 1094 | p->num_packets++; |
1101 | - p->num_pages += p->pages->num; | |
1095 | + p->total_normal_pages += p->normal_num; | |
1102 | 1096 | qemu_mutex_unlock(&p->mutex); |
1103 | 1097 | |
1104 | - if (p->pages->num) { | |
1098 | + if (p->normal_num) { | |
1105 | 1099 | ret = multifd_recv_state->ops->recv_pages(p, &local_err); |
1106 | 1100 | if (ret != 0) { |
1107 | 1101 | break; |
@@ -1123,7 +1117,7 @@ static void *multifd_recv_thread(void *opaque) | ||
1123 | 1117 | qemu_mutex_unlock(&p->mutex); |
1124 | 1118 | |
1125 | 1119 | rcu_unregister_thread(); |
1126 | - trace_multifd_recv_thread_end(p->id, p->num_packets, p->num_pages); | |
1120 | + trace_multifd_recv_thread_end(p->id, p->num_packets, p->total_normal_pages); | |
1127 | 1121 | |
1128 | 1122 | return NULL; |
1129 | 1123 | } |
@@ -1161,6 +1155,7 @@ int multifd_load_setup(Error **errp) | ||
1161 | 1155 | p->packet = g_malloc0(p->packet_len); |
1162 | 1156 | p->name = g_strdup_printf("multifdrecv_%d", i); |
1163 | 1157 | p->iov = g_new0(struct iovec, page_count); |
1158 | + p->normal = g_new0(ram_addr_t, page_count); | |
1164 | 1159 | } |
1165 | 1160 | |
1166 | 1161 | for (i = 0; i < thread_count; i++) { |
@@ -151,12 +151,16 @@ typedef struct { | ||
151 | 151 | uint32_t next_packet_size; |
152 | 152 | /* packets sent through this channel */ |
153 | 153 | uint64_t num_packets; |
154 | - /* pages sent through this channel */ | |
155 | - uint64_t num_pages; | |
154 | + /* non zero pages recv through this channel */ | |
155 | + uint64_t total_normal_pages; | |
156 | 156 | /* syncs main thread and channels */ |
157 | 157 | QemuSemaphore sem_sync; |
158 | 158 | /* buffers to recv */ |
159 | 159 | struct iovec *iov; |
160 | + /* Pages that are not zero */ | |
161 | + ram_addr_t *normal; | |
162 | + /* num of non zero pages */ | |
163 | + uint32_t normal_num; | |
160 | 164 | /* used for de-compression methods */ |
161 | 165 | void *data; |
162 | 166 | } MultiFDRecvParams; |