• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

修訂cfd66f30fb0f735df06ff4220e5000290a43dad3 (tree)
時間2022-01-28 23:38:23
作者Peter Xu <peterx@redh...>
CommiterJuan Quintela

Log Message

migration: Simplify unqueue_page()

This patch simplifies unqueue_page() on both sides of it (itself, and caller).

Firstly, due to the fact that right after unqueue_page() returned true, we'll
definitely send a huge page (see ram_save_huge_page() call - it will _never_
exit before finish sending that huge page), so unqueue_page() does not need to
jump in small page size if huge page is enabled on the ramblock. IOW, it's
destined that only the 1st 4K page will be valid, when unqueue the 2nd+ time
we'll notice the whole huge page has already been sent anyway. Switching to
operating on huge page reduces a lot of the loops of redundant unqueue_page().

Meanwhile, drop the dirty check. It's not helpful to call test_bit() every
time to jump over clean pages, as ram_save_host_page() has already done so,
while in a faster way (see commit ba1b7c812c ("migration/ram: Optimize
ram_save_host_page()", 2021-05-13)). So that's not necessary too.

Drop the two tracepoints along the way - based on above analysis it's very
possible that no one is really using it..

Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>

Change Summary

差異

--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1547,6 +1547,7 @@ static RAMBlock *unqueue_page(RAMState *rs, ram_addr_t *offset)
15471547 {
15481548 struct RAMSrcPageRequest *entry;
15491549 RAMBlock *block = NULL;
1550+ size_t page_size;
15501551
15511552 if (!postcopy_has_request(rs)) {
15521553 return NULL;
@@ -1563,10 +1564,13 @@ static RAMBlock *unqueue_page(RAMState *rs, ram_addr_t *offset)
15631564 entry = QSIMPLEQ_FIRST(&rs->src_page_requests);
15641565 block = entry->rb;
15651566 *offset = entry->offset;
1567+ page_size = qemu_ram_pagesize(block);
1568+ /* Each page request should only be multiple page size of the ramblock */
1569+ assert((entry->len % page_size) == 0);
15661570
1567- if (entry->len > TARGET_PAGE_SIZE) {
1568- entry->len -= TARGET_PAGE_SIZE;
1569- entry->offset += TARGET_PAGE_SIZE;
1571+ if (entry->len > page_size) {
1572+ entry->len -= page_size;
1573+ entry->offset += page_size;
15701574 } else {
15711575 memory_region_unref(block->mr);
15721576 QSIMPLEQ_REMOVE_HEAD(&rs->src_page_requests, next_req);
@@ -1574,6 +1578,9 @@ static RAMBlock *unqueue_page(RAMState *rs, ram_addr_t *offset)
15741578 migration_consume_urgent_request();
15751579 }
15761580
1581+ trace_unqueue_page(block->idstr, *offset,
1582+ test_bit((*offset >> TARGET_PAGE_BITS), block->bmap));
1583+
15771584 return block;
15781585 }
15791586
@@ -1948,30 +1955,8 @@ static bool get_queued_page(RAMState *rs, PageSearchStatus *pss)
19481955 {
19491956 RAMBlock *block;
19501957 ram_addr_t offset;
1951- bool dirty;
1952-
1953- do {
1954- block = unqueue_page(rs, &offset);
1955- /*
1956- * We're sending this page, and since it's postcopy nothing else
1957- * will dirty it, and we must make sure it doesn't get sent again
1958- * even if this queue request was received after the background
1959- * search already sent it.
1960- */
1961- if (block) {
1962- unsigned long page;
1963-
1964- page = offset >> TARGET_PAGE_BITS;
1965- dirty = test_bit(page, block->bmap);
1966- if (!dirty) {
1967- trace_get_queued_page_not_dirty(block->idstr, (uint64_t)offset,
1968- page);
1969- } else {
1970- trace_get_queued_page(block->idstr, (uint64_t)offset, page);
1971- }
1972- }
19731958
1974- } while (block && !dirty);
1959+ block = unqueue_page(rs, &offset);
19751960
19761961 if (!block) {
19771962 /*
--- a/migration/trace-events
+++ b/migration/trace-events
@@ -86,8 +86,6 @@ put_qlist_end(const char *field_name, const char *vmsd_name) "%s(%s)"
8686 qemu_file_fclose(void) ""
8787
8888 # ram.c
89-get_queued_page(const char *block_name, uint64_t tmp_offset, unsigned long page_abs) "%s/0x%" PRIx64 " page_abs=0x%lx"
90-get_queued_page_not_dirty(const char *block_name, uint64_t tmp_offset, unsigned long page_abs) "%s/0x%" PRIx64 " page_abs=0x%lx"
9189 migration_bitmap_sync_start(void) ""
9290 migration_bitmap_sync_end(uint64_t dirty_pages) "dirty_pages %" PRIu64
9391 migration_bitmap_clear_dirty(char *str, uint64_t start, uint64_t size, unsigned long page) "rb %s start 0x%"PRIx64" size 0x%"PRIx64" page 0x%lx"
@@ -113,6 +111,7 @@ ram_save_iterate_big_wait(uint64_t milliconds, int iterations) "big wait: %" PRI
113111 ram_load_complete(int ret, uint64_t seq_iter) "exit_code %d seq iteration %" PRIu64
114112 ram_write_tracking_ramblock_start(const char *block_id, size_t page_size, void *addr, size_t length) "%s: page_size: %zu addr: %p length: %zu"
115113 ram_write_tracking_ramblock_stop(const char *block_id, size_t page_size, void *addr, size_t length) "%s: page_size: %zu addr: %p length: %zu"
114+unqueue_page(char *block, uint64_t offset, bool dirty) "ramblock '%s' offset 0x%"PRIx64" dirty %d"
116115
117116 # multifd.c
118117 multifd_new_send_channel_async(uint8_t id) "channel %u"