From: "Michael S. Tsirkin" <mst@redhat.com>
To: Sergio Lopez <slp@redhat.com>
Cc: kwolf@redhat.com, stefanha@redhat.com, qemu-devel@nongnu.org,
qemu-block@nongnu.org, mreitz@redhat.com
Subject: Re: [Qemu-devel] [RFC PATCH] virtio-blk: schedule virtio_notify_config to run on main context
Date: Thu, 12 Sep 2019 15:51:53 -0400 [thread overview]
Message-ID: <20190912155023-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20190912181924.48539-1-slp@redhat.com>
On Thu, Sep 12, 2019 at 08:19:25PM +0200, Sergio Lopez wrote:
> Another AioContext-related issue, and this is a tricky one.
>
> Executing a QMP block_resize request for a virtio-blk device running
> on an iothread may cause a deadlock involving the following mutexes:
>
> - main thead
> * Has acquired: qemu_mutex_global.
> * Is trying the acquire: iothread AioContext lock via
> AIO_WAIT_WHILE (after aio_poll).
>
> - iothread
> * Has acquired: AioContext lock.
> * Is trying to acquire: qemu_mutex_global (via
> virtio_notify_config->prepare_mmio_access).
Hmm is this really the only case iothread takes qemu mutex?
If any such access can deadlock, don't we need a generic
solution? Maybe main thread can drop qemu mutex
before taking io thread AioContext lock?
> With this change, virtio_blk_resize checks if it's being called from a
> coroutine context running on a non-main thread, and if that's the
> case, creates a new coroutine and schedules it to be run on the main
> thread.
>
> This works, but means the actual operation is done
> asynchronously, perhaps opening a window in which a "device_del"
> operation may fit and remove the VirtIODevice before
> virtio_notify_config() is executed.
>
> I *think* it shouldn't be possible, as BHs will be processed before
> any new QMP/monitor command, but I'm open to a different approach.
>
> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1744955
> Signed-off-by: Sergio Lopez <slp@redhat.com>
> ---
> hw/block/virtio-blk.c | 25 ++++++++++++++++++++++++-
> 1 file changed, 24 insertions(+), 1 deletion(-)
>
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index 18851601cb..c763d071f6 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -16,6 +16,7 @@
> #include "qemu/iov.h"
> #include "qemu/module.h"
> #include "qemu/error-report.h"
> +#include "qemu/main-loop.h"
> #include "trace.h"
> #include "hw/block/block.h"
> #include "hw/qdev-properties.h"
> @@ -1086,11 +1087,33 @@ static int virtio_blk_load_device(VirtIODevice *vdev, QEMUFile *f,
> return 0;
> }
>
> +static void coroutine_fn virtio_resize_co_entry(void *opaque)
> +{
> + VirtIODevice *vdev = opaque;
> +
> + assert(qemu_get_current_aio_context() == qemu_get_aio_context());
> + virtio_notify_config(vdev);
> + aio_wait_kick();
> +}
> +
> static void virtio_blk_resize(void *opaque)
> {
> VirtIODevice *vdev = VIRTIO_DEVICE(opaque);
> + Coroutine *co;
>
> - virtio_notify_config(vdev);
> + if (qemu_in_coroutine() &&
> + qemu_get_current_aio_context() != qemu_get_aio_context()) {
> + /*
> + * virtio_notify_config() needs to acquire the global mutex,
> + * so calling it from a coroutine running on a non-main context
> + * may cause a deadlock. Instead, create a new coroutine and
> + * schedule it to be run on the main thread.
> + */
> + co = qemu_coroutine_create(virtio_resize_co_entry, vdev);
> + aio_co_schedule(qemu_get_aio_context(), co);
> + } else {
> + virtio_notify_config(vdev);
> + }
> }
>
> static const BlockDevOps virtio_block_ops = {
> --
> 2.21.0
next prev parent reply other threads:[~2019-09-12 19:52 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-12 18:19 [Qemu-devel] [RFC PATCH] virtio-blk: schedule virtio_notify_config to run on main context Sergio Lopez
2019-09-12 19:51 ` Michael S. Tsirkin [this message]
2019-09-13 7:46 ` Sergio Lopez
2019-09-13 9:04 ` Kevin Wolf
2019-09-13 9:28 ` Sergio Lopez
2019-09-13 9:45 ` Kevin Wolf
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=20190912155023-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=slp@redhat.com \
--cc=stefanha@redhat.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.