All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: David Hildenbrand <david@redhat.com>
Cc: "Juan Quintela" <quintela@redhat.com>,
	qemu-devel@nongnu.org,
	"Alexander Duyck" <alexander.duyck@gmail.com>,
	qemu-stable@nongnu.org, "Wei Wang" <wei.w.wang@intel.com>,
	"Peter Xu" <peterx@redhat.com>,
	"Philippe Mathieu-Daudé" <philmd@redhat.com>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>
Subject: Re: [PATCH v1 2/2] virtio-balloon: disallow postcopy with VIRTIO_BALLOON_F_FREE_PAGE_HINT
Date: Wed, 7 Jul 2021 15:05:41 -0400	[thread overview]
Message-ID: <20210707150038-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20210707140655.30982-3-david@redhat.com>

On Wed, Jul 07, 2021 at 04:06:55PM +0200, David Hildenbrand wrote:
> Postcopy never worked properly with 'free-page-hint=on', as there are
> at least two issues:
> 
> 1) With postcopy, the guest will never receive a VIRTIO_BALLOON_CMD_ID_DONE
>    and consequently won't release free pages back to the OS once
>    migration finishes.
> 
>    The issue is that for postcopy, we won't do a final bitmap sync while
>    the guest is stopped on the source and
>    virtio_balloon_free_page_hint_notify() will only call
>    virtio_balloon_free_page_done() on the source during
>    PRECOPY_NOTIFY_CLEANUP, after the VM state was already migrated to
>    the destination.
> 
> 2) Once the VM touches a page on the destination that has been excluded
>    from migration on the source via qemu_guest_free_page_hint() while
>    postcopy is active, that thread will stall until postcopy finishes
>    and all threads are woken up. (with older Linux kernels that won't
>    retry faults when woken up via userfaultfd, we might actually get a
>    SEGFAULT)
> 
>    The issue is that the source will refuse to migrate any pages that
>    are not marked as dirty in the dirty bmap -- for example, because the
>    page might just have been sent. Consequently, the faulting thread will
>    stall, waiting for the page to be migrated -- which could take quite
>    a while and result in guest OS issues.

OK so if source gets a request for a page which is not dirty
it does not respond immediately? Why not just teach it to
respond? It would seem that if destination wants a page we
should just give it to the destination ...


> 
> While we could fix 1), for example, by calling
> virtio_balloon_free_page_done() via pre_save callbacks of the
> vmstate, 2) is mostly impossible to fix without additional tracking,
> such that we can actually identify these hinted pages and handle
> them accordingly.
> As it never worked properly, let's disable it via the postcopy notifier on
> the destination. Trying to set "migrate_set_capability postcopy-ram on"
> on the destination now results in "virtio-balloon: 'free-page-hint' does
> not support postcopy Error: Postcopy is not supported".
> Note 1: We could let qemu_guest_free_page_hint() mark postcopy
>         as broken once actually clearing bits on the source. However, it's
>         harder to realize as we can race with users starting postcopy
>         and we cannot produce an expressive error message easily.


How about the reverse? Ignore qemu_guest_free_page_hint if postcopy
started?  Seems better than making it user/guest visible ..

> Note 2: virtio-mem has similar issues, however, access to "unplugged"
>         memory by the guest is very rare and we would have to be very
>         lucky for it to happen during migration. The spec states
>         "The driver SHOULD NOT read from unplugged memory blocks ..."
>         and "The driver MUST NOT write to unplugged memory blocks".
>         virtio-mem will move away from virtio_balloon_free_page_done()
>         soon and handle this case explicitly on the destination.
> 
> Fixes: c13c4153f76d ("virtio-balloon: VIRTIO_BALLOON_F_FREE_PAGE_HINT")

OK it's not too bad, but I wonder whether above aideas have been
explored.

> Cc: qemu-stable@nongnu.org
> Cc: Wei Wang <wei.w.wang@intel.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
> Cc: Alexander Duyck <alexander.duyck@gmail.com>
> Cc: Juan Quintela <quintela@redhat.com>
> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
> Cc: Peter Xu <peterx@redhat.com>
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
>  hw/virtio/virtio-balloon.c         | 26 ++++++++++++++++++++++++++
>  include/hw/virtio/virtio-balloon.h |  1 +
>  2 files changed, 27 insertions(+)
> 
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index 4b5d9e5e50..d0c9dc677c 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -30,6 +30,7 @@
>  #include "trace.h"
>  #include "qemu/error-report.h"
>  #include "migration/misc.h"
> +#include "migration/postcopy-ram.h"
>  
>  #include "hw/virtio/virtio-bus.h"
>  #include "hw/virtio/virtio-access.h"
> @@ -692,6 +693,28 @@ virtio_balloon_free_page_hint_notify(NotifierWithReturn *n, void *data)
>      return 0;
>  }
>  
> +
> +static int virtio_balloon_postcopy_notify(NotifierWithReturn *n, void *opaque)
> +{
> +    VirtIOBalloon *dev = container_of(n, VirtIOBalloon, postcopy_notifier);
> +    PostcopyNotifyData *pnd = opaque;
> +
> +    /* We register the notifier only with 'free-page-hint=on' for now. */
> +    g_assert(virtio_has_feature(dev->host_features,
> +                                VIRTIO_BALLOON_F_FREE_PAGE_HINT));
> +
> +    /*
> +     * Pages hinted via qemu_guest_free_page_hint() are cleared from the dirty
> +     * bitmap and will not get migrated, especially also not when the postcopy
> +     * destination starts using them and requests migration from the source; the
> +     * faulting thread will stall until postcopy migration finishes and
> +     * all threads are woken up.
> +     */
> +    error_setg(pnd->errp,
> +               "virtio-balloon: 'free-page-hint' does not support postcopy");
> +    return -ENOENT;
> +}
> +
>  static size_t virtio_balloon_config_size(VirtIOBalloon *s)
>  {
>      uint64_t features = s->host_features;
> @@ -911,6 +934,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp)
>          s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE,
>                                             virtio_balloon_handle_free_page_vq);
>          precopy_add_notifier(&s->free_page_hint_notify);
> +        postcopy_add_notifier(&s->postcopy_notifier);
>  
>          object_ref(OBJECT(s->iothread));
>          s->free_page_bh = aio_bh_new(iothread_get_aio_context(s->iothread),
> @@ -935,6 +959,7 @@ static void virtio_balloon_device_unrealize(DeviceState *dev)
>          object_unref(OBJECT(s->iothread));
>          virtio_balloon_free_page_stop(s);
>          precopy_remove_notifier(&s->free_page_hint_notify);
> +        postcopy_remove_notifier(&s->postcopy_notifier);
>      }
>      balloon_stats_destroy_timer(s);
>      qemu_remove_balloon_handler(s);
> @@ -1008,6 +1033,7 @@ static void virtio_balloon_instance_init(Object *obj)
>      qemu_cond_init(&s->free_page_cond);
>      s->free_page_hint_cmd_id = VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN;
>      s->free_page_hint_notify.notify = virtio_balloon_free_page_hint_notify;
> +    s->postcopy_notifier.notify = virtio_balloon_postcopy_notify;
>  
>      object_property_add(obj, "guest-stats", "guest statistics",
>                          balloon_stats_get_all, NULL, NULL, s);
> diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h
> index 5139cf8ab6..d0d5b793b9 100644
> --- a/include/hw/virtio/virtio-balloon.h
> +++ b/include/hw/virtio/virtio-balloon.h
> @@ -65,6 +65,7 @@ struct VirtIOBalloon {
>       */
>      bool block_iothread;
>      NotifierWithReturn free_page_hint_notify;
> +    NotifierWithReturn postcopy_notifier;
>      int64_t stats_last_update;
>      int64_t stats_poll_interval;
>      uint32_t host_features;
> -- 
> 2.31.1



  parent reply	other threads:[~2021-07-07 19:06 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-07 14:06 [PATCH v1 0/2] virtio-balloon: disallow postcopy with VIRTIO_BALLOON_F_FREE_PAGE_HINT David Hildenbrand
2021-07-07 14:06 ` [PATCH v1 1/2] migration/postcopy-ram: define type for "struct PostcopyNotifyData" David Hildenbrand
2021-07-07 20:30   ` Pankaj Gupta
2021-07-07 14:06 ` [PATCH v1 2/2] virtio-balloon: disallow postcopy with VIRTIO_BALLOON_F_FREE_PAGE_HINT David Hildenbrand
2021-07-07 18:02   ` Peter Xu
2021-07-07 18:57     ` David Hildenbrand
2021-07-07 19:07       ` Michael S. Tsirkin
2021-07-07 20:08       ` Peter Xu
2021-07-07 21:22         ` Alexander Duyck
2021-07-07 22:40           ` Peter Xu
2021-07-08  7:14             ` David Hildenbrand
2021-07-08  7:23           ` David Hildenbrand
2021-07-07 19:05   ` Michael S. Tsirkin [this message]
2021-07-07 19:14     ` David Hildenbrand
2021-07-07 19:19       ` Michael S. Tsirkin
2021-07-07 19:47         ` David Hildenbrand
2021-07-07 19:57           ` Michael S. Tsirkin
2021-07-08  8:19             ` David Hildenbrand
2021-07-08 19:07             ` Dr. David Alan Gilbert
2021-07-09 11:27               ` Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210707150038-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=alexander.duyck@gmail.com \
    --cc=david@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=peterx@redhat.com \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-stable@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=wei.w.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.