]> Git Repo - qemu.git/blob - migration/postcopy-ram.c
postcopy: Mask fault addresses to huge page boundary
[qemu.git] / migration / postcopy-ram.c
1 /*
2  * Postcopy migration for RAM
3  *
4  * Copyright 2013-2015 Red Hat, Inc. and/or its affiliates
5  *
6  * Authors:
7  *  Dave Gilbert  <[email protected]>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  */
13
14 /*
15  * Postcopy is a migration technique where the execution flips from the
16  * source to the destination before all the data has been copied.
17  */
18
19 #include "qemu/osdep.h"
20
21 #include "qemu-common.h"
22 #include "migration/migration.h"
23 #include "migration/postcopy-ram.h"
24 #include "sysemu/sysemu.h"
25 #include "sysemu/balloon.h"
26 #include "qemu/error-report.h"
27 #include "trace.h"
28
29 /* Arbitrary limit on size of each discard command,
30  * keeps them around ~200 bytes
31  */
32 #define MAX_DISCARDS_PER_COMMAND 12
33
34 struct PostcopyDiscardState {
35     const char *ramblock_name;
36     uint64_t offset; /* Bitmap entry for the 1st bit of this RAMBlock */
37     uint16_t cur_entry;
38     /*
39      * Start and length of a discard range (bytes)
40      */
41     uint64_t start_list[MAX_DISCARDS_PER_COMMAND];
42     uint64_t length_list[MAX_DISCARDS_PER_COMMAND];
43     unsigned int nsentwords;
44     unsigned int nsentcmds;
45 };
46
47 /* Postcopy needs to detect accesses to pages that haven't yet been copied
48  * across, and efficiently map new pages in, the techniques for doing this
49  * are target OS specific.
50  */
51 #if defined(__linux__)
52
53 #include <poll.h>
54 #include <sys/ioctl.h>
55 #include <sys/syscall.h>
56 #include <asm/types.h> /* for __u64 */
57 #endif
58
59 #if defined(__linux__) && defined(__NR_userfaultfd) && defined(CONFIG_EVENTFD)
60 #include <sys/eventfd.h>
61 #include <linux/userfaultfd.h>
62
63 static bool ufd_version_check(int ufd)
64 {
65     struct uffdio_api api_struct;
66     uint64_t ioctl_mask;
67
68     api_struct.api = UFFD_API;
69     api_struct.features = 0;
70     if (ioctl(ufd, UFFDIO_API, &api_struct)) {
71         error_report("postcopy_ram_supported_by_host: UFFDIO_API failed: %s",
72                      strerror(errno));
73         return false;
74     }
75
76     ioctl_mask = (__u64)1 << _UFFDIO_REGISTER |
77                  (__u64)1 << _UFFDIO_UNREGISTER;
78     if ((api_struct.ioctls & ioctl_mask) != ioctl_mask) {
79         error_report("Missing userfault features: %" PRIx64,
80                      (uint64_t)(~api_struct.ioctls & ioctl_mask));
81         return false;
82     }
83
84     return true;
85 }
86
87 /*
88  * Check for things that postcopy won't support; returns 0 if the block
89  * is fine.
90  */
91 static int check_range(const char *block_name, void *host_addr,
92                       ram_addr_t offset, ram_addr_t length, void *opaque)
93 {
94     RAMBlock *rb = qemu_ram_block_by_name(block_name);
95
96     if (qemu_ram_pagesize(rb) > getpagesize()) {
97         error_report("Postcopy doesn't support large page sizes yet (%s)",
98                      block_name);
99         return -E2BIG;
100     }
101
102     return 0;
103 }
104
105 /*
106  * Note: This has the side effect of munlock'ing all of RAM, that's
107  * normally fine since if the postcopy succeeds it gets turned back on at the
108  * end.
109  */
110 bool postcopy_ram_supported_by_host(void)
111 {
112     long pagesize = getpagesize();
113     int ufd = -1;
114     bool ret = false; /* Error unless we change it */
115     void *testarea = NULL;
116     struct uffdio_register reg_struct;
117     struct uffdio_range range_struct;
118     uint64_t feature_mask;
119
120     if ((1ul << qemu_target_page_bits()) > pagesize) {
121         error_report("Target page size bigger than host page size");
122         goto out;
123     }
124
125     /* Check for anything about the RAMBlocks we don't support */
126     if (qemu_ram_foreach_block(check_range, NULL)) {
127         /* check_range will have printed its own error */
128         goto out;
129     }
130
131     ufd = syscall(__NR_userfaultfd, O_CLOEXEC);
132     if (ufd == -1) {
133         error_report("%s: userfaultfd not available: %s", __func__,
134                      strerror(errno));
135         goto out;
136     }
137
138     /* Version and features check */
139     if (!ufd_version_check(ufd)) {
140         goto out;
141     }
142
143     /*
144      * userfault and mlock don't go together; we'll put it back later if
145      * it was enabled.
146      */
147     if (munlockall()) {
148         error_report("%s: munlockall: %s", __func__,  strerror(errno));
149         return -1;
150     }
151
152     /*
153      *  We need to check that the ops we need are supported on anon memory
154      *  To do that we need to register a chunk and see the flags that
155      *  are returned.
156      */
157     testarea = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE |
158                                     MAP_ANONYMOUS, -1, 0);
159     if (testarea == MAP_FAILED) {
160         error_report("%s: Failed to map test area: %s", __func__,
161                      strerror(errno));
162         goto out;
163     }
164     g_assert(((size_t)testarea & (pagesize-1)) == 0);
165
166     reg_struct.range.start = (uintptr_t)testarea;
167     reg_struct.range.len = pagesize;
168     reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;
169
170     if (ioctl(ufd, UFFDIO_REGISTER, &reg_struct)) {
171         error_report("%s userfault register: %s", __func__, strerror(errno));
172         goto out;
173     }
174
175     range_struct.start = (uintptr_t)testarea;
176     range_struct.len = pagesize;
177     if (ioctl(ufd, UFFDIO_UNREGISTER, &range_struct)) {
178         error_report("%s userfault unregister: %s", __func__, strerror(errno));
179         goto out;
180     }
181
182     feature_mask = (__u64)1 << _UFFDIO_WAKE |
183                    (__u64)1 << _UFFDIO_COPY |
184                    (__u64)1 << _UFFDIO_ZEROPAGE;
185     if ((reg_struct.ioctls & feature_mask) != feature_mask) {
186         error_report("Missing userfault map features: %" PRIx64,
187                      (uint64_t)(~reg_struct.ioctls & feature_mask));
188         goto out;
189     }
190
191     /* Success! */
192     ret = true;
193 out:
194     if (testarea) {
195         munmap(testarea, pagesize);
196     }
197     if (ufd != -1) {
198         close(ufd);
199     }
200     return ret;
201 }
202
203 /*
204  * Setup an area of RAM so that it *can* be used for postcopy later; this
205  * must be done right at the start prior to pre-copy.
206  * opaque should be the MIS.
207  */
208 static int init_range(const char *block_name, void *host_addr,
209                       ram_addr_t offset, ram_addr_t length, void *opaque)
210 {
211     MigrationIncomingState *mis = opaque;
212
213     trace_postcopy_init_range(block_name, host_addr, offset, length);
214
215     /*
216      * We need the whole of RAM to be truly empty for postcopy, so things
217      * like ROMs and any data tables built during init must be zero'd
218      * - we're going to get the copy from the source anyway.
219      * (Precopy will just overwrite this data, so doesn't need the discard)
220      */
221     if (ram_discard_range(mis, block_name, 0, length)) {
222         return -1;
223     }
224
225     return 0;
226 }
227
228 /*
229  * At the end of migration, undo the effects of init_range
230  * opaque should be the MIS.
231  */
232 static int cleanup_range(const char *block_name, void *host_addr,
233                         ram_addr_t offset, ram_addr_t length, void *opaque)
234 {
235     MigrationIncomingState *mis = opaque;
236     struct uffdio_range range_struct;
237     trace_postcopy_cleanup_range(block_name, host_addr, offset, length);
238
239     /*
240      * We turned off hugepage for the precopy stage with postcopy enabled
241      * we can turn it back on now.
242      */
243     qemu_madvise(host_addr, length, QEMU_MADV_HUGEPAGE);
244
245     /*
246      * We can also turn off userfault now since we should have all the
247      * pages.   It can be useful to leave it on to debug postcopy
248      * if you're not sure it's always getting every page.
249      */
250     range_struct.start = (uintptr_t)host_addr;
251     range_struct.len = length;
252
253     if (ioctl(mis->userfault_fd, UFFDIO_UNREGISTER, &range_struct)) {
254         error_report("%s: userfault unregister %s", __func__, strerror(errno));
255
256         return -1;
257     }
258
259     return 0;
260 }
261
262 /*
263  * Initialise postcopy-ram, setting the RAM to a state where we can go into
264  * postcopy later; must be called prior to any precopy.
265  * called from arch_init's similarly named ram_postcopy_incoming_init
266  */
267 int postcopy_ram_incoming_init(MigrationIncomingState *mis, size_t ram_pages)
268 {
269     if (qemu_ram_foreach_block(init_range, mis)) {
270         return -1;
271     }
272
273     return 0;
274 }
275
276 /*
277  * At the end of a migration where postcopy_ram_incoming_init was called.
278  */
279 int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
280 {
281     trace_postcopy_ram_incoming_cleanup_entry();
282
283     if (mis->have_fault_thread) {
284         uint64_t tmp64;
285
286         if (qemu_ram_foreach_block(cleanup_range, mis)) {
287             return -1;
288         }
289         /*
290          * Tell the fault_thread to exit, it's an eventfd that should
291          * currently be at 0, we're going to increment it to 1
292          */
293         tmp64 = 1;
294         if (write(mis->userfault_quit_fd, &tmp64, 8) == 8) {
295             trace_postcopy_ram_incoming_cleanup_join();
296             qemu_thread_join(&mis->fault_thread);
297         } else {
298             /* Not much we can do here, but may as well report it */
299             error_report("%s: incrementing userfault_quit_fd: %s", __func__,
300                          strerror(errno));
301         }
302         trace_postcopy_ram_incoming_cleanup_closeuf();
303         close(mis->userfault_fd);
304         close(mis->userfault_quit_fd);
305         mis->have_fault_thread = false;
306     }
307
308     qemu_balloon_inhibit(false);
309
310     if (enable_mlock) {
311         if (os_mlock() < 0) {
312             error_report("mlock: %s", strerror(errno));
313             /*
314              * It doesn't feel right to fail at this point, we have a valid
315              * VM state.
316              */
317         }
318     }
319
320     postcopy_state_set(POSTCOPY_INCOMING_END);
321     migrate_send_rp_shut(mis, qemu_file_get_error(mis->from_src_file) != 0);
322
323     if (mis->postcopy_tmp_page) {
324         munmap(mis->postcopy_tmp_page, mis->largest_page_size);
325         mis->postcopy_tmp_page = NULL;
326     }
327     if (mis->postcopy_tmp_zero_page) {
328         munmap(mis->postcopy_tmp_zero_page, mis->largest_page_size);
329         mis->postcopy_tmp_zero_page = NULL;
330     }
331     trace_postcopy_ram_incoming_cleanup_exit();
332     return 0;
333 }
334
335 /*
336  * Disable huge pages on an area
337  */
338 static int nhp_range(const char *block_name, void *host_addr,
339                     ram_addr_t offset, ram_addr_t length, void *opaque)
340 {
341     trace_postcopy_nhp_range(block_name, host_addr, offset, length);
342
343     /*
344      * Before we do discards we need to ensure those discards really
345      * do delete areas of the page, even if THP thinks a hugepage would
346      * be a good idea, so force hugepages off.
347      */
348     qemu_madvise(host_addr, length, QEMU_MADV_NOHUGEPAGE);
349
350     return 0;
351 }
352
353 /*
354  * Userfault requires us to mark RAM as NOHUGEPAGE prior to discard
355  * however leaving it until after precopy means that most of the precopy
356  * data is still THPd
357  */
358 int postcopy_ram_prepare_discard(MigrationIncomingState *mis)
359 {
360     if (qemu_ram_foreach_block(nhp_range, mis)) {
361         return -1;
362     }
363
364     postcopy_state_set(POSTCOPY_INCOMING_DISCARD);
365
366     return 0;
367 }
368
369 /*
370  * Mark the given area of RAM as requiring notification to unwritten areas
371  * Used as a  callback on qemu_ram_foreach_block.
372  *   host_addr: Base of area to mark
373  *   offset: Offset in the whole ram arena
374  *   length: Length of the section
375  *   opaque: MigrationIncomingState pointer
376  * Returns 0 on success
377  */
378 static int ram_block_enable_notify(const char *block_name, void *host_addr,
379                                    ram_addr_t offset, ram_addr_t length,
380                                    void *opaque)
381 {
382     MigrationIncomingState *mis = opaque;
383     struct uffdio_register reg_struct;
384
385     reg_struct.range.start = (uintptr_t)host_addr;
386     reg_struct.range.len = length;
387     reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;
388
389     /* Now tell our userfault_fd that it's responsible for this area */
390     if (ioctl(mis->userfault_fd, UFFDIO_REGISTER, &reg_struct)) {
391         error_report("%s userfault register: %s", __func__, strerror(errno));
392         return -1;
393     }
394
395     return 0;
396 }
397
398 /*
399  * Handle faults detected by the USERFAULT markings
400  */
401 static void *postcopy_ram_fault_thread(void *opaque)
402 {
403     MigrationIncomingState *mis = opaque;
404     struct uffd_msg msg;
405     int ret;
406     RAMBlock *rb = NULL;
407     RAMBlock *last_rb = NULL; /* last RAMBlock we sent part of */
408
409     trace_postcopy_ram_fault_thread_entry();
410     qemu_sem_post(&mis->fault_thread_sem);
411
412     while (true) {
413         ram_addr_t rb_offset;
414         struct pollfd pfd[2];
415
416         /*
417          * We're mainly waiting for the kernel to give us a faulting HVA,
418          * however we can be told to quit via userfault_quit_fd which is
419          * an eventfd
420          */
421         pfd[0].fd = mis->userfault_fd;
422         pfd[0].events = POLLIN;
423         pfd[0].revents = 0;
424         pfd[1].fd = mis->userfault_quit_fd;
425         pfd[1].events = POLLIN; /* Waiting for eventfd to go positive */
426         pfd[1].revents = 0;
427
428         if (poll(pfd, 2, -1 /* Wait forever */) == -1) {
429             error_report("%s: userfault poll: %s", __func__, strerror(errno));
430             break;
431         }
432
433         if (pfd[1].revents) {
434             trace_postcopy_ram_fault_thread_quit();
435             break;
436         }
437
438         ret = read(mis->userfault_fd, &msg, sizeof(msg));
439         if (ret != sizeof(msg)) {
440             if (errno == EAGAIN) {
441                 /*
442                  * if a wake up happens on the other thread just after
443                  * the poll, there is nothing to read.
444                  */
445                 continue;
446             }
447             if (ret < 0) {
448                 error_report("%s: Failed to read full userfault message: %s",
449                              __func__, strerror(errno));
450                 break;
451             } else {
452                 error_report("%s: Read %d bytes from userfaultfd expected %zd",
453                              __func__, ret, sizeof(msg));
454                 break; /* Lost alignment, don't know what we'd read next */
455             }
456         }
457         if (msg.event != UFFD_EVENT_PAGEFAULT) {
458             error_report("%s: Read unexpected event %ud from userfaultfd",
459                          __func__, msg.event);
460             continue; /* It's not a page fault, shouldn't happen */
461         }
462
463         rb = qemu_ram_block_from_host(
464                  (void *)(uintptr_t)msg.arg.pagefault.address,
465                  true, &rb_offset);
466         if (!rb) {
467             error_report("postcopy_ram_fault_thread: Fault outside guest: %"
468                          PRIx64, (uint64_t)msg.arg.pagefault.address);
469             break;
470         }
471
472         rb_offset &= ~(qemu_ram_pagesize(rb) - 1);
473         trace_postcopy_ram_fault_thread_request(msg.arg.pagefault.address,
474                                                 qemu_ram_get_idstr(rb),
475                                                 rb_offset);
476
477         /*
478          * Send the request to the source - we want to request one
479          * of our host page sizes (which is >= TPS)
480          */
481         if (rb != last_rb) {
482             last_rb = rb;
483             migrate_send_rp_req_pages(mis, qemu_ram_get_idstr(rb),
484                                      rb_offset, qemu_ram_pagesize(rb));
485         } else {
486             /* Save some space */
487             migrate_send_rp_req_pages(mis, NULL,
488                                      rb_offset, qemu_ram_pagesize(rb));
489         }
490     }
491     trace_postcopy_ram_fault_thread_exit();
492     return NULL;
493 }
494
495 int postcopy_ram_enable_notify(MigrationIncomingState *mis)
496 {
497     /* Open the fd for the kernel to give us userfaults */
498     mis->userfault_fd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
499     if (mis->userfault_fd == -1) {
500         error_report("%s: Failed to open userfault fd: %s", __func__,
501                      strerror(errno));
502         return -1;
503     }
504
505     /*
506      * Although the host check already tested the API, we need to
507      * do the check again as an ABI handshake on the new fd.
508      */
509     if (!ufd_version_check(mis->userfault_fd)) {
510         return -1;
511     }
512
513     /* Now an eventfd we use to tell the fault-thread to quit */
514     mis->userfault_quit_fd = eventfd(0, EFD_CLOEXEC);
515     if (mis->userfault_quit_fd == -1) {
516         error_report("%s: Opening userfault_quit_fd: %s", __func__,
517                      strerror(errno));
518         close(mis->userfault_fd);
519         return -1;
520     }
521
522     qemu_sem_init(&mis->fault_thread_sem, 0);
523     qemu_thread_create(&mis->fault_thread, "postcopy/fault",
524                        postcopy_ram_fault_thread, mis, QEMU_THREAD_JOINABLE);
525     qemu_sem_wait(&mis->fault_thread_sem);
526     qemu_sem_destroy(&mis->fault_thread_sem);
527     mis->have_fault_thread = true;
528
529     /* Mark so that we get notified of accesses to unwritten areas */
530     if (qemu_ram_foreach_block(ram_block_enable_notify, mis)) {
531         return -1;
532     }
533
534     /*
535      * Ballooning can mark pages as absent while we're postcopying
536      * that would cause false userfaults.
537      */
538     qemu_balloon_inhibit(true);
539
540     trace_postcopy_ram_enable_notify();
541
542     return 0;
543 }
544
545 /*
546  * Place a host page (from) at (host) atomically
547  * returns 0 on success
548  */
549 int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
550                         size_t pagesize)
551 {
552     struct uffdio_copy copy_struct;
553
554     copy_struct.dst = (uint64_t)(uintptr_t)host;
555     copy_struct.src = (uint64_t)(uintptr_t)from;
556     copy_struct.len = pagesize;
557     copy_struct.mode = 0;
558
559     /* copy also acks to the kernel waking the stalled thread up
560      * TODO: We can inhibit that ack and only do it if it was requested
561      * which would be slightly cheaper, but we'd have to be careful
562      * of the order of updating our page state.
563      */
564     if (ioctl(mis->userfault_fd, UFFDIO_COPY, &copy_struct)) {
565         int e = errno;
566         error_report("%s: %s copy host: %p from: %p (size: %zd)",
567                      __func__, strerror(e), host, from, pagesize);
568
569         return -e;
570     }
571
572     trace_postcopy_place_page(host);
573     return 0;
574 }
575
576 /*
577  * Place a zero page at (host) atomically
578  * returns 0 on success
579  */
580 int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
581                              size_t pagesize)
582 {
583     trace_postcopy_place_page_zero(host);
584
585     if (pagesize == getpagesize()) {
586         struct uffdio_zeropage zero_struct;
587         zero_struct.range.start = (uint64_t)(uintptr_t)host;
588         zero_struct.range.len = getpagesize();
589         zero_struct.mode = 0;
590
591         if (ioctl(mis->userfault_fd, UFFDIO_ZEROPAGE, &zero_struct)) {
592             int e = errno;
593             error_report("%s: %s zero host: %p",
594                          __func__, strerror(e), host);
595
596             return -e;
597         }
598     } else {
599         /* The kernel can't use UFFDIO_ZEROPAGE for hugepages */
600         if (!mis->postcopy_tmp_zero_page) {
601             mis->postcopy_tmp_zero_page = mmap(NULL, mis->largest_page_size,
602                                                PROT_READ | PROT_WRITE,
603                                                MAP_PRIVATE | MAP_ANONYMOUS,
604                                                -1, 0);
605             if (mis->postcopy_tmp_zero_page == MAP_FAILED) {
606                 int e = errno;
607                 mis->postcopy_tmp_zero_page = NULL;
608                 error_report("%s: %s mapping large zero page",
609                              __func__, strerror(e));
610                 return -e;
611             }
612             memset(mis->postcopy_tmp_zero_page, '\0', mis->largest_page_size);
613         }
614         return postcopy_place_page(mis, host, mis->postcopy_tmp_zero_page,
615                                    pagesize);
616     }
617
618     return 0;
619 }
620
621 /*
622  * Returns a target page of memory that can be mapped at a later point in time
623  * using postcopy_place_page
624  * The same address is used repeatedly, postcopy_place_page just takes the
625  * backing page away.
626  * Returns: Pointer to allocated page
627  *
628  */
629 void *postcopy_get_tmp_page(MigrationIncomingState *mis)
630 {
631     if (!mis->postcopy_tmp_page) {
632         mis->postcopy_tmp_page = mmap(NULL, mis->largest_page_size,
633                              PROT_READ | PROT_WRITE, MAP_PRIVATE |
634                              MAP_ANONYMOUS, -1, 0);
635         if (mis->postcopy_tmp_page == MAP_FAILED) {
636             mis->postcopy_tmp_page = NULL;
637             error_report("%s: %s", __func__, strerror(errno));
638             return NULL;
639         }
640     }
641
642     return mis->postcopy_tmp_page;
643 }
644
645 #else
646 /* No target OS support, stubs just fail */
647 bool postcopy_ram_supported_by_host(void)
648 {
649     error_report("%s: No OS support", __func__);
650     return false;
651 }
652
653 int postcopy_ram_incoming_init(MigrationIncomingState *mis, size_t ram_pages)
654 {
655     error_report("postcopy_ram_incoming_init: No OS support");
656     return -1;
657 }
658
659 int postcopy_ram_incoming_cleanup(MigrationIncomingState *mis)
660 {
661     assert(0);
662     return -1;
663 }
664
665 int postcopy_ram_prepare_discard(MigrationIncomingState *mis)
666 {
667     assert(0);
668     return -1;
669 }
670
671 int postcopy_ram_enable_notify(MigrationIncomingState *mis)
672 {
673     assert(0);
674     return -1;
675 }
676
677 int postcopy_place_page(MigrationIncomingState *mis, void *host, void *from,
678                         size_t pagesize)
679 {
680     assert(0);
681     return -1;
682 }
683
684 int postcopy_place_page_zero(MigrationIncomingState *mis, void *host,
685                         size_t pagesize)
686 {
687     assert(0);
688     return -1;
689 }
690
691 void *postcopy_get_tmp_page(MigrationIncomingState *mis)
692 {
693     assert(0);
694     return NULL;
695 }
696
697 #endif
698
699 /* ------------------------------------------------------------------------- */
700
701 /**
702  * postcopy_discard_send_init: Called at the start of each RAMBlock before
703  *   asking to discard individual ranges.
704  *
705  * @ms: The current migration state.
706  * @offset: the bitmap offset of the named RAMBlock in the migration
707  *   bitmap.
708  * @name: RAMBlock that discards will operate on.
709  *
710  * returns: a new PDS.
711  */
712 PostcopyDiscardState *postcopy_discard_send_init(MigrationState *ms,
713                                                  unsigned long offset,
714                                                  const char *name)
715 {
716     PostcopyDiscardState *res = g_malloc0(sizeof(PostcopyDiscardState));
717
718     if (res) {
719         res->ramblock_name = name;
720         res->offset = offset;
721     }
722
723     return res;
724 }
725
726 /**
727  * postcopy_discard_send_range: Called by the bitmap code for each chunk to
728  *   discard. May send a discard message, may just leave it queued to
729  *   be sent later.
730  *
731  * @ms: Current migration state.
732  * @pds: Structure initialised by postcopy_discard_send_init().
733  * @start,@length: a range of pages in the migration bitmap in the
734  *   RAM block passed to postcopy_discard_send_init() (length=1 is one page)
735  */
736 void postcopy_discard_send_range(MigrationState *ms, PostcopyDiscardState *pds,
737                                 unsigned long start, unsigned long length)
738 {
739     size_t tp_bits = qemu_target_page_bits();
740     /* Convert to byte offsets within the RAM block */
741     pds->start_list[pds->cur_entry] = (start - pds->offset) << tp_bits;
742     pds->length_list[pds->cur_entry] = length << tp_bits;
743     trace_postcopy_discard_send_range(pds->ramblock_name, start, length);
744     pds->cur_entry++;
745     pds->nsentwords++;
746
747     if (pds->cur_entry == MAX_DISCARDS_PER_COMMAND) {
748         /* Full set, ship it! */
749         qemu_savevm_send_postcopy_ram_discard(ms->to_dst_file,
750                                               pds->ramblock_name,
751                                               pds->cur_entry,
752                                               pds->start_list,
753                                               pds->length_list);
754         pds->nsentcmds++;
755         pds->cur_entry = 0;
756     }
757 }
758
759 /**
760  * postcopy_discard_send_finish: Called at the end of each RAMBlock by the
761  * bitmap code. Sends any outstanding discard messages, frees the PDS
762  *
763  * @ms: Current migration state.
764  * @pds: Structure initialised by postcopy_discard_send_init().
765  */
766 void postcopy_discard_send_finish(MigrationState *ms, PostcopyDiscardState *pds)
767 {
768     /* Anything unsent? */
769     if (pds->cur_entry) {
770         qemu_savevm_send_postcopy_ram_discard(ms->to_dst_file,
771                                               pds->ramblock_name,
772                                               pds->cur_entry,
773                                               pds->start_list,
774                                               pds->length_list);
775         pds->nsentcmds++;
776     }
777
778     trace_postcopy_discard_send_finish(pds->ramblock_name, pds->nsentwords,
779                                        pds->nsentcmds);
780
781     g_free(pds);
782 }
This page took 0.065566 seconds and 4 git commands to generate.