On 2/6/19 11:02 AM, John Snow wrote: > When bitmaps are persistent, they may incur a disk read or write when bitmaps > are added or removed. For configurations like virtio-dataplane, failing to > acquire this lock will abort QEMU when disk IO occurs. > > We used to acquire aio_context as part of the bitmap lookup, so re-introduce > the lock for just the cases that have an IO penalty. > > Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1672010 > Reported-By: Aihua Liang <[email protected]> > Signed-off-by: John Snow <[email protected]> > --- > blockdev.c | 24 +++++++++++++++++++----- > 1 file changed, 19 insertions(+), 5 deletions(-) > > diff --git a/blockdev.c b/blockdev.c > index fb18e9c975..ce458de037 100644 > --- a/blockdev.c > +++ b/blockdev.c > @@ -2820,6 +2820,7 @@ void qmp_block_dirty_bitmap_add(const char *node, const > char *name, > { > BlockDriverState *bs; > BdrvDirtyBitmap *bitmap; > + AioContext *aio_context = NULL; > > if (!name || name[0] == '\0') { > error_setg(errp, "Bitmap name cannot be empty"); > @@ -2854,10 +2855,12 @@ void qmp_block_dirty_bitmap_add(const char *node, > const char *name, > disabled = false; > } > > - if (persistent && > - !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) > - { > - return; > + if (persistent) { > + aio_context = bdrv_get_aio_context(bs); > + aio_context_acquire(aio_context); > + if (!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) { > + goto out; > + } > } > > bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); if (bitmap == NULL) { return; }
Oops - this early return fails to release the aio context.
> @@ -2870,6 +2873,10 @@ void qmp_block_dirty_bitmap_add(const char *node,
> const char *name,
> }
>
> bdrv_dirty_bitmap_set_persistance(bitmap, persistent);
> + out:
> + if (aio_context) {
> + aio_context_release(aio_context);
> + }
> }
>
> void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
> @@ -2878,6 +2885,7 @@ void qmp_block_dirty_bitmap_remove(const char *node,
> const char *name,
> BlockDriverState *bs;
> BdrvDirtyBitmap *bitmap;
> Error *local_err = NULL;
> + AioContext *aio_context = NULL;
>
> bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
> if (!bitmap || !bs) {
> @@ -2892,14 +2900,20 @@ void qmp_block_dirty_bitmap_remove(const char *node,
> const char *name,
> }
>
> if (bdrv_dirty_bitmap_get_persistance(bitmap)) {
> + aio_context = bdrv_get_aio_context(bs);
> + aio_context_acquire(aio_context);
> bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err);
> if (local_err != NULL) {
> error_propagate(errp, local_err);
> - return;
> + goto out;
> }
> }
>
> bdrv_release_dirty_bitmap(bs, bitmap);
> + out:
> + if (aio_context) {
> + aio_context_release(aio_context);
> + }
> }
>
> /**
>
--
Eric Blake, Principal Software Engineer
Red Hat, Inc. +1-919-301-3226
Virtualization: qemu.org | libvirt.org
signature.asc
Description: OpenPGP digital signature
