Lines Matching +full:- +full:p
4 * Copyright (c) 2019-2020 Red Hat Inc
10 * See the COPYING file in the top-level directory.
17 #include "migration-stats.h"
23 #include "qemu/error-report.h"
25 #include "qemu-file.h"
31 pages->offset = g_new0(ram_addr_t, multifd_ram_page_count()); in multifd_ram_payload_alloc()
36 g_clear_pointer(&pages->offset, g_free); in multifd_ram_payload_free()
49 static void multifd_set_file_bitmap(MultiFDSendParams *p) in multifd_set_file_bitmap() argument
51 MultiFDPages_t *pages = &p->data->u.ram; in multifd_set_file_bitmap()
53 assert(pages->block); in multifd_set_file_bitmap()
55 for (int i = 0; i < pages->normal_num; i++) { in multifd_set_file_bitmap()
56 ramblock_set_file_bmap_atomic(pages->block, pages->offset[i], true); in multifd_set_file_bitmap()
59 for (int i = pages->normal_num; i < pages->num; i++) { in multifd_set_file_bitmap()
60 ramblock_set_file_bmap_atomic(pages->block, pages->offset[i], false); in multifd_set_file_bitmap()
64 static int multifd_nocomp_send_setup(MultiFDSendParams *p, Error **errp) in multifd_nocomp_send_setup() argument
69 p->write_flags |= QIO_CHANNEL_WRITE_FLAG_ZERO_COPY; in multifd_nocomp_send_setup()
74 p->iov = g_new0(struct iovec, page_count + 1); in multifd_nocomp_send_setup()
76 p->iov = g_new0(struct iovec, page_count); in multifd_nocomp_send_setup()
82 static void multifd_nocomp_send_cleanup(MultiFDSendParams *p, Error **errp) in multifd_nocomp_send_cleanup() argument
84 g_free(p->iov); in multifd_nocomp_send_cleanup()
85 p->iov = NULL; in multifd_nocomp_send_cleanup()
88 static void multifd_ram_prepare_header(MultiFDSendParams *p) in multifd_ram_prepare_header() argument
90 p->iov[0].iov_len = p->packet_len; in multifd_ram_prepare_header()
91 p->iov[0].iov_base = p->packet; in multifd_ram_prepare_header()
92 p->iovs_num++; in multifd_ram_prepare_header()
95 static void multifd_send_prepare_iovs(MultiFDSendParams *p) in multifd_send_prepare_iovs() argument
97 MultiFDPages_t *pages = &p->data->u.ram; in multifd_send_prepare_iovs()
100 for (int i = 0; i < pages->normal_num; i++) { in multifd_send_prepare_iovs()
101 p->iov[p->iovs_num].iov_base = pages->block->host + pages->offset[i]; in multifd_send_prepare_iovs()
102 p->iov[p->iovs_num].iov_len = page_size; in multifd_send_prepare_iovs()
103 p->iovs_num++; in multifd_send_prepare_iovs()
106 p->next_packet_size = pages->normal_num * page_size; in multifd_send_prepare_iovs()
109 static int multifd_nocomp_send_prepare(MultiFDSendParams *p, Error **errp) in multifd_nocomp_send_prepare() argument
114 multifd_send_zero_page_detect(p); in multifd_nocomp_send_prepare()
117 multifd_send_prepare_iovs(p); in multifd_nocomp_send_prepare()
118 multifd_set_file_bitmap(p); in multifd_nocomp_send_prepare()
128 multifd_ram_prepare_header(p); in multifd_nocomp_send_prepare()
131 multifd_send_prepare_iovs(p); in multifd_nocomp_send_prepare()
132 p->flags |= MULTIFD_FLAG_NOCOMP; in multifd_nocomp_send_prepare()
134 multifd_send_fill_packet(p); in multifd_nocomp_send_prepare()
138 ret = qio_channel_write_all(p->c, (void *)p->packet, in multifd_nocomp_send_prepare()
139 p->packet_len, errp); in multifd_nocomp_send_prepare()
141 return -1; in multifd_nocomp_send_prepare()
144 stat64_add(&mig_stats.multifd_bytes, p->packet_len); in multifd_nocomp_send_prepare()
150 static int multifd_nocomp_recv_setup(MultiFDRecvParams *p, Error **errp) in multifd_nocomp_recv_setup() argument
152 p->iov = g_new0(struct iovec, multifd_ram_page_count()); in multifd_nocomp_recv_setup()
156 static void multifd_nocomp_recv_cleanup(MultiFDRecvParams *p) in multifd_nocomp_recv_cleanup() argument
158 g_free(p->iov); in multifd_nocomp_recv_cleanup()
159 p->iov = NULL; in multifd_nocomp_recv_cleanup()
162 static int multifd_nocomp_recv(MultiFDRecvParams *p, Error **errp) in multifd_nocomp_recv() argument
167 return multifd_file_recv_data(p, errp); in multifd_nocomp_recv()
170 flags = p->flags & MULTIFD_FLAG_COMPRESSION_MASK; in multifd_nocomp_recv()
174 p->id, flags, MULTIFD_FLAG_NOCOMP); in multifd_nocomp_recv()
175 return -1; in multifd_nocomp_recv()
178 multifd_recv_zero_page_process(p); in multifd_nocomp_recv()
180 if (!p->normal_num) { in multifd_nocomp_recv()
184 for (int i = 0; i < p->normal_num; i++) { in multifd_nocomp_recv()
185 p->iov[i].iov_base = p->host + p->normal[i]; in multifd_nocomp_recv()
186 p->iov[i].iov_len = multifd_ram_page_size(); in multifd_nocomp_recv()
187 ramblock_recv_bitmap_set_offset(p->block, p->normal[i]); in multifd_nocomp_recv()
189 return qio_channel_readv_all(p->c, p->iov, p->normal_num, errp); in multifd_nocomp_recv()
198 pages->num = 0; in multifd_pages_reset()
199 pages->normal_num = 0; in multifd_pages_reset()
200 pages->block = NULL; in multifd_pages_reset()
203 void multifd_ram_fill_packet(MultiFDSendParams *p) in multifd_ram_fill_packet() argument
205 MultiFDPacket_t *packet = p->packet; in multifd_ram_fill_packet()
206 MultiFDPages_t *pages = &p->data->u.ram; in multifd_ram_fill_packet()
207 uint32_t zero_num = pages->num - pages->normal_num; in multifd_ram_fill_packet()
209 packet->pages_alloc = cpu_to_be32(multifd_ram_page_count()); in multifd_ram_fill_packet()
210 packet->normal_pages = cpu_to_be32(pages->normal_num); in multifd_ram_fill_packet()
211 packet->zero_pages = cpu_to_be32(zero_num); in multifd_ram_fill_packet()
213 if (pages->block) { in multifd_ram_fill_packet()
214 pstrcpy(packet->ramblock, sizeof(packet->ramblock), in multifd_ram_fill_packet()
215 pages->block->idstr); in multifd_ram_fill_packet()
218 for (int i = 0; i < pages->num; i++) { in multifd_ram_fill_packet()
220 uint64_t temp = pages->offset[i]; in multifd_ram_fill_packet()
222 packet->offset[i] = cpu_to_be64(temp); in multifd_ram_fill_packet()
225 trace_multifd_send_ram_fill(p->id, pages->normal_num, in multifd_ram_fill_packet()
229 int multifd_ram_unfill_packet(MultiFDRecvParams *p, Error **errp) in multifd_ram_unfill_packet() argument
231 MultiFDPacket_t *packet = p->packet; in multifd_ram_unfill_packet()
234 uint32_t pages_per_packet = be32_to_cpu(packet->pages_alloc); in multifd_ram_unfill_packet()
240 return -1; in multifd_ram_unfill_packet()
243 p->normal_num = be32_to_cpu(packet->normal_pages); in multifd_ram_unfill_packet()
244 if (p->normal_num > pages_per_packet) { in multifd_ram_unfill_packet()
245 error_setg(errp, "multifd: received packet with %u non-zero pages, " in multifd_ram_unfill_packet()
247 p->normal_num, pages_per_packet); in multifd_ram_unfill_packet()
248 return -1; in multifd_ram_unfill_packet()
251 p->zero_num = be32_to_cpu(packet->zero_pages); in multifd_ram_unfill_packet()
252 if (p->zero_num > pages_per_packet - p->normal_num) { in multifd_ram_unfill_packet()
255 p->zero_num, pages_per_packet - p->normal_num); in multifd_ram_unfill_packet()
256 return -1; in multifd_ram_unfill_packet()
259 if (p->normal_num == 0 && p->zero_num == 0) { in multifd_ram_unfill_packet()
264 packet->ramblock[255] = 0; in multifd_ram_unfill_packet()
265 p->block = qemu_ram_block_by_name(packet->ramblock); in multifd_ram_unfill_packet()
266 if (!p->block) { in multifd_ram_unfill_packet()
268 packet->ramblock); in multifd_ram_unfill_packet()
269 return -1; in multifd_ram_unfill_packet()
272 p->host = p->block->host; in multifd_ram_unfill_packet()
273 for (i = 0; i < p->normal_num; i++) { in multifd_ram_unfill_packet()
274 uint64_t offset = be64_to_cpu(packet->offset[i]); in multifd_ram_unfill_packet()
276 if (offset > (p->block->used_length - page_size)) { in multifd_ram_unfill_packet()
279 offset, p->block->used_length); in multifd_ram_unfill_packet()
280 return -1; in multifd_ram_unfill_packet()
282 p->normal[i] = offset; in multifd_ram_unfill_packet()
285 for (i = 0; i < p->zero_num; i++) { in multifd_ram_unfill_packet()
286 uint64_t offset = be64_to_cpu(packet->offset[p->normal_num + i]); in multifd_ram_unfill_packet()
288 if (offset > (p->block->used_length - page_size)) { in multifd_ram_unfill_packet()
291 offset, p->block->used_length); in multifd_ram_unfill_packet()
292 return -1; in multifd_ram_unfill_packet()
294 p->zero[i] = offset; in multifd_ram_unfill_packet()
302 return pages->num == 0; in multifd_queue_empty()
307 return pages->num == multifd_ram_page_count(); in multifd_queue_full()
312 pages->offset[pages->num++] = offset; in multifd_enqueue()
321 pages = &multifd_ram_send->u.ram; in multifd_queue_page()
330 pages->block = block; in multifd_queue_page()
343 if (pages->block != block || multifd_queue_full(pages)) { in multifd_queue_page()
358 * - Per-section mode: this is the legacy way to flush, it requires one
361 * - Per-round mode: this is the modern way to flush, it requires one
366 * One thing to mention is mapped-ram always use the modern way to sync.
369 /* Do we need a per-section multifd flush (legacy way)? */
383 /* Do we need a per-round multifd flush (modern way)? */
409 return -1; in multifd_ram_flush_and_sync()
440 bool multifd_send_prepare_common(MultiFDSendParams *p) in multifd_send_prepare_common() argument
442 MultiFDPages_t *pages = &p->data->u.ram; in multifd_send_prepare_common()
443 multifd_ram_prepare_header(p); in multifd_send_prepare_common()
444 multifd_send_zero_page_detect(p); in multifd_send_prepare_common()
446 if (!pages->normal_num) { in multifd_send_prepare_common()
447 p->next_packet_size = 0; in multifd_send_prepare_common()