[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH RFC] migrate/ram: remove "ram_bulk_stage" and "fpo_enabled"
From: |
Dr. David Alan Gilbert |
Subject: |
Re: [PATCH RFC] migrate/ram: remove "ram_bulk_stage" and "fpo_enabled" |
Date: |
Mon, 10 May 2021 19:58:15 +0100 |
User-agent: |
Mutt/2.0.6 (2021-03-06) |
* David Hildenbrand (david@redhat.com) wrote:
> The bulk stage is kind of weird: migration_bitmap_find_dirty() will
> indicate a dirty page, however, ram_save_host_page() will never save it, as
> migration_bitmap_clear_dirty() detects that it is not dirty.
>
> We already fill the bitmap in ram_list_init_bitmaps() with ones, marking
> everything dirty - it didn't used to be that way, which is why we needed
> an explicit first bulk stage.
>
> Let's simplify: make the bitmap the single source of thuth. Explicitly
> handle the "xbzrle_enabled after first round" case.
I think you're right here, so (at long last) queued.
I did read the comments on 6eeb63f which added the FPO flag, and I still
think you're right.
> Regarding XBZRLE (implicitly handled via "ram_bulk_stage = false" right
> now), there is now a slight change in behavior:
> - Colo: When starting, it will be disabled (was implicitly enabled)
> until the first round actually finishes.
Was it or did they see a bulk stage again?
I can imagine that XBZRLE might be useful for COLO if subsequent rounds
of synchornisation finds pages that change but not much.
> - Free page hinting: When starting, XBZRLE will be disabled (was implicitly
> enabled) until the first round actually finished.
But the XBZRLE cache would be empty anyway on that first round?
> - Snapshots: When starting, XBZRLE will be disabled. We essentially only
> do a single run, so I guess it will never actually get disabled.
>
> Postcopy seems to indirectly disable it in ram_save_page(), so there
> shouldn't be really any change.
>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Juan Quintela <quintela@redhat.com>
> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> Cc: Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
> Cc: Peter Xu <peterx@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>
> Our dirty bitmap handling is right now a little confusing due to the bulk
> stage. Am i missing something important? Can someone comment on the
> expected XBZRLE handling? It all is a little bit too intertwined for my
> taste.
I think it's mostly due to there being no benefit (and a lot of cost) in
doing xbzrle during the first round.
Dave
> ---
> hw/virtio/virtio-balloon.c | 4 +-
> hw/virtio/virtio-mem.c | 3 --
> include/migration/misc.h | 1 -
> migration/ram.c | 78 +++++++++-----------------------------
> 4 files changed, 18 insertions(+), 68 deletions(-)
>
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index e770955176..d162b89603 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -659,9 +659,6 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn
> *n, void *data)
> }
>
> switch (pnd->reason) {
> - case PRECOPY_NOTIFY_SETUP:
> - precopy_enable_free_page_optimization();
> - break;
> case PRECOPY_NOTIFY_BEFORE_BITMAP_SYNC:
> virtio_balloon_free_page_stop(dev);
> break;
> @@ -681,6 +678,7 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn
> *n, void *data)
> */
> virtio_balloon_free_page_done(dev);
> break;
> + case PRECOPY_NOTIFY_SETUP:
> case PRECOPY_NOTIFY_COMPLETE:
> break;
> default:
> diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c
> index 99d0712195..c7d261ffe7 100644
> --- a/hw/virtio/virtio-mem.c
> +++ b/hw/virtio/virtio-mem.c
> @@ -1063,9 +1063,6 @@ static int virtio_mem_precopy_notify(NotifierWithReturn
> *n, void *data)
> PrecopyNotifyData *pnd = data;
>
> switch (pnd->reason) {
> - case PRECOPY_NOTIFY_SETUP:
> - precopy_enable_free_page_optimization();
> - break;
> case PRECOPY_NOTIFY_AFTER_BITMAP_SYNC:
> virtio_mem_precopy_exclude_unplugged(vmem);
> break;
> diff --git a/include/migration/misc.h b/include/migration/misc.h
> index bccc1b6b44..69c7e7e14b 100644
> --- a/include/migration/misc.h
> +++ b/include/migration/misc.h
> @@ -37,7 +37,6 @@ void precopy_infrastructure_init(void);
> void precopy_add_notifier(NotifierWithReturn *n);
> void precopy_remove_notifier(NotifierWithReturn *n);
> int precopy_notify(PrecopyNotifyReason reason, Error **errp);
> -void precopy_enable_free_page_optimization(void);
>
> void ram_mig_init(void);
> void qemu_guest_free_page_hint(void *addr, size_t len);
> diff --git a/migration/ram.c b/migration/ram.c
> index 72143da0ac..7394a9c414 100644
> --- a/migration/ram.c
> +++ b/migration/ram.c
> @@ -313,10 +313,6 @@ struct RAMState {
> ram_addr_t last_page;
> /* last ram version we have seen */
> uint32_t last_version;
> - /* We are in the first round */
> - bool ram_bulk_stage;
> - /* The free page optimization is enabled */
> - bool fpo_enabled;
> /* How many times we have dirty too many pages */
> int dirty_rate_high_cnt;
> /* these variables are used for bitmap sync */
> @@ -332,6 +328,8 @@ struct RAMState {
> uint64_t xbzrle_pages_prev;
> /* Amount of xbzrle encoded bytes since the beginning of the period */
> uint64_t xbzrle_bytes_prev;
> + /* Start using XBZRLE (e.g., after the first round). */
> + bool xbzrle_enabled;
>
> /* compression statistics since the beginning of the period */
> /* amount of count that no free thread to compress data */
> @@ -385,15 +383,6 @@ int precopy_notify(PrecopyNotifyReason reason, Error
> **errp)
> return notifier_with_return_list_notify(&precopy_notifier_list, &pnd);
> }
>
> -void precopy_enable_free_page_optimization(void)
> -{
> - if (!ram_state) {
> - return;
> - }
> -
> - ram_state->fpo_enabled = true;
> -}
> -
> uint64_t ram_bytes_remaining(void)
> {
> return ram_state ? (ram_state->migration_dirty_pages * TARGET_PAGE_SIZE)
> :
> @@ -666,7 +655,7 @@ static void mig_throttle_guest_down(uint64_t
> bytes_dirty_period,
> */
> static void xbzrle_cache_zero_page(RAMState *rs, ram_addr_t current_addr)
> {
> - if (rs->ram_bulk_stage || !migrate_use_xbzrle()) {
> + if (!rs->xbzrle_enabled) {
> return;
> }
>
> @@ -794,23 +783,12 @@ unsigned long migration_bitmap_find_dirty(RAMState *rs,
> RAMBlock *rb,
> {
> unsigned long size = rb->used_length >> TARGET_PAGE_BITS;
> unsigned long *bitmap = rb->bmap;
> - unsigned long next;
>
> if (ramblock_is_ignored(rb)) {
> return size;
> }
>
> - /*
> - * When the free page optimization is enabled, we need to check the
> bitmap
> - * to send the non-free pages rather than all the pages in the bulk
> stage.
> - */
> - if (!rs->fpo_enabled && rs->ram_bulk_stage && start > 0) {
> - next = start + 1;
> - } else {
> - next = find_next_bit(bitmap, size, start);
> - }
> -
> - return next;
> + return find_next_bit(bitmap, size, start);
> }
>
> static inline bool migration_bitmap_clear_dirty(RAMState *rs,
> @@ -1188,8 +1166,7 @@ static int ram_save_page(RAMState *rs, PageSearchStatus
> *pss, bool last_stage)
> trace_ram_save_page(block->idstr, (uint64_t)offset, p);
>
> XBZRLE_cache_lock();
> - if (!rs->ram_bulk_stage && !migration_in_postcopy() &&
> - migrate_use_xbzrle()) {
> + if (rs->xbzrle_enabled && !migration_in_postcopy()) {
> pages = save_xbzrle_page(rs, &p, current_addr, block,
> offset, last_stage);
> if (!last_stage) {
> @@ -1389,7 +1366,10 @@ static bool find_dirty_block(RAMState *rs,
> PageSearchStatus *pss, bool *again)
> pss->block = QLIST_FIRST_RCU(&ram_list.blocks);
> /* Flag that we've looped */
> pss->complete_round = true;
> - rs->ram_bulk_stage = false;
> + /* After the first round, enable XBZRLE. */
> + if (migrate_use_xbzrle()) {
> + rs->xbzrle_enabled = true;
> + }
> }
> /* Didn't find anything this time, but try again on the new block */
> *again = true;
> @@ -1752,14 +1732,6 @@ static bool get_queued_page(RAMState *rs,
> PageSearchStatus *pss)
> }
>
> if (block) {
> - /*
> - * As soon as we start servicing pages out of order, then we have
> - * to kill the bulk stage, since the bulk stage assumes
> - * in (migration_bitmap_find_and_reset_dirty) that every page is
> - * dirty, that's no longer true.
> - */
> - rs->ram_bulk_stage = false;
> -
> /*
> * We want the background search to continue from the queued page
> * since the guest is likely to want other pages near to the page
> @@ -1872,15 +1844,15 @@ static bool save_page_use_compression(RAMState *rs)
> }
>
> /*
> - * If xbzrle is on, stop using the data compression after first
> - * round of migration even if compression is enabled. In theory,
> - * xbzrle can do better than compression.
> + * If xbzrle is enabled (e.g., after first round of migration), stop
> + * using the data compression. In theory, xbzrle can do better than
> + * compression.
> */
> - if (rs->ram_bulk_stage || !migrate_use_xbzrle()) {
> - return true;
> + if (rs->xbzrle_enabled) {
> + return false;
> }
>
> - return false;
> + return true;
> }
>
> /*
> @@ -2187,8 +2159,7 @@ static void ram_state_reset(RAMState *rs)
> rs->last_sent_block = NULL;
> rs->last_page = 0;
> rs->last_version = ram_list.version;
> - rs->ram_bulk_stage = true;
> - rs->fpo_enabled = false;
> + rs->xbzrle_enabled = false;
> }
>
> #define MAX_WAIT 50 /* ms, half buffered_file limit */
> @@ -2672,15 +2643,7 @@ static void ram_state_resume_prepare(RAMState *rs,
> QEMUFile *out)
> /* This may not be aligned with current bitmaps. Recalculate. */
> rs->migration_dirty_pages = pages;
>
> - rs->last_seen_block = NULL;
> - rs->last_sent_block = NULL;
> - rs->last_page = 0;
> - rs->last_version = ram_list.version;
> - /*
> - * Disable the bulk stage, otherwise we'll resend the whole RAM no
> - * matter what we have sent.
> - */
> - rs->ram_bulk_stage = false;
> + ram_state_reset(rs);
>
> /* Update RAMState cache of output QEMUFile */
> rs->f = out;
> @@ -3298,16 +3261,9 @@ static void
> decompress_data_with_multi_threads(QEMUFile *f,
> qemu_mutex_unlock(&decomp_done_lock);
> }
>
> - /*
> - * we must set ram_bulk_stage to false, otherwise in
> - * migation_bitmap_find_dirty the bitmap will be unused and
> - * all the pages in ram cache wil be flushed to the ram of
> - * secondary VM.
> - */
> static void colo_init_ram_state(void)
> {
> ram_state_init(&ram_state);
> - ram_state->ram_bulk_stage = false;
> }
>
> /*
> --
> 2.29.2
>
>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
- Re: [PATCH RFC] migrate/ram: remove "ram_bulk_stage" and "fpo_enabled",
Dr. David Alan Gilbert <=