qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Sergio Lopez <slp@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>,
	qemu-devel@nongnu.org, qemu-block@nongnu.org,
	Markus Armbruster <armbru@redhat.com>
Subject: Re: [PATCH v5 4/4] blockdev: honor bdrv_try_set_aio_context() context requirements
Date: Mon, 9 Dec 2019 17:06:01 +0100	[thread overview]
Message-ID: <20191209160601.GB6715@linux.fritz.box> (raw)
In-Reply-To: <20191128104129.250206-5-slp@redhat.com>

Am 28.11.2019 um 11:41 hat Sergio Lopez geschrieben:
> bdrv_try_set_aio_context() requires that the old context is held, and
> the new context is not held. Fix all the occurrences where it's not
> done this way.
> 
> Suggested-by: Max Reitz <mreitz@redhat.com>
> Signed-off-by: Sergio Lopez <slp@redhat.com>
> ---
>  blockdev.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 62 insertions(+), 10 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index 152a0f7454..e33abd7fd2 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1535,6 +1535,7 @@ static void external_snapshot_prepare(BlkActionState *common,
>                               DO_UPCAST(ExternalSnapshotState, common, common);
>      TransactionAction *action = common->action;
>      AioContext *aio_context;
> +    AioContext *old_context;
>      int ret;
>  
>      /* 'blockdev-snapshot' and 'blockdev-snapshot-sync' have similar
> @@ -1675,7 +1676,16 @@ static void external_snapshot_prepare(BlkActionState *common,
>          goto out;
>      }
>  
> +    /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
> +    old_context = bdrv_get_aio_context(state->new_bs);
> +    aio_context_release(aio_context);
> +    aio_context_acquire(old_context);
> +
>      ret = bdrv_try_set_aio_context(state->new_bs, aio_context, errp);
> +
> +    aio_context_release(old_context);
> +    aio_context_acquire(aio_context);
> +
>      if (ret < 0) {
>          goto out;
>      }
> @@ -1775,11 +1785,13 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
>      BlockDriverState *target_bs;
>      BlockDriverState *source = NULL;
>      AioContext *aio_context;
> +    AioContext *old_context;
>      QDict *options;
>      Error *local_err = NULL;
>      int flags;
>      int64_t size;
>      bool set_backing_hd = false;
> +    int ret;
>  
>      assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
>      backup = common->action->u.drive_backup.data;
> @@ -1868,6 +1880,20 @@ static void drive_backup_prepare(BlkActionState *common, Error **errp)
>          goto out;
>      }
>  
> +    /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
> +    old_context = bdrv_get_aio_context(target_bs);
> +    aio_context_release(aio_context);
> +    aio_context_acquire(old_context);
> +
> +    ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
> +    aio_context_release(old_context);
> +    aio_context_acquire(aio_context);
> +
> +    if (ret < 0) {
> +        goto out;

I think this needs to be 'goto unref'.

Or in fact, I think you need to hold the AioContext of a bs to
bdrv_unref() it, so maybe 'goto out' is right, but you need to unref
target_bs while you still hold old_context.

> +    }
> +
>      if (set_backing_hd) {
>          bdrv_set_backing_hd(target_bs, source, &local_err);
>          if (local_err) {
> @@ -1947,6 +1973,8 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
>      BlockDriverState *bs;
>      BlockDriverState *target_bs;
>      AioContext *aio_context;
> +    AioContext *old_context;
> +    int ret;
>  
>      assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
>      backup = common->action->u.blockdev_backup.data;
> @@ -1961,7 +1989,18 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp)
>          return;
>      }
>  
> +    /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
>      aio_context = bdrv_get_aio_context(bs);
> +    old_context = bdrv_get_aio_context(target_bs);
> +    aio_context_acquire(old_context);
> +
> +    ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
> +    if (ret < 0) {
> +        aio_context_release(old_context);
> +        return;
> +    }
> +
> +    aio_context_release(old_context);
>      aio_context_acquire(aio_context);
>      state->bs = bs;
>  
> @@ -3562,7 +3601,6 @@ static BlockJob *do_backup_common(BackupCommon *backup,
>      BlockJob *job = NULL;
>      BdrvDirtyBitmap *bmap = NULL;
>      int job_flags = JOB_DEFAULT;
> -    int ret;
>  
>      if (!backup->has_speed) {
>          backup->speed = 0;
> @@ -3586,11 +3624,6 @@ static BlockJob *do_backup_common(BackupCommon *backup,
>          backup->compress = false;
>      }
>  
> -    ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
> -    if (ret < 0) {
> -        return NULL;
> -    }
> -
>      if ((backup->sync == MIRROR_SYNC_MODE_BITMAP) ||
>          (backup->sync == MIRROR_SYNC_MODE_INCREMENTAL)) {
>          /* done before desugaring 'incremental' to print the right message */
> @@ -3825,6 +3858,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
>      BlockDriverState *bs;
>      BlockDriverState *source, *target_bs;
>      AioContext *aio_context;
> +    AioContext *old_context;
>      BlockMirrorBackingMode backing_mode;
>      Error *local_err = NULL;
>      QDict *options = NULL;
> @@ -3937,10 +3971,19 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
>                     (arg->mode == NEW_IMAGE_MODE_EXISTING ||
>                      !bdrv_has_zero_init(target_bs)));
>  
> +
> +    /* Honor bdrv_try_set_aio_context() context acquisition requirements. */
> +    old_context = bdrv_get_aio_context(target_bs);
> +    aio_context_release(aio_context);
> +    aio_context_acquire(old_context);
> +
>      ret = bdrv_try_set_aio_context(target_bs, aio_context, errp);
> +
> +    aio_context_release(old_context);
> +    aio_context_acquire(aio_context);
> +
>      if (ret < 0) {
> -        bdrv_unref(target_bs);
> -        goto out;
> +        goto unref;
>      }

Here you don't forget to unref target_bs, but it has still the same
problem as above that you need to hold old_context during bdrv_unref().

Kevin



  reply	other threads:[~2019-12-09 16:07 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-28 10:41 [PATCH v5 0/4] blockdev: avoid acquiring AioContext lock twice at do_drive_backup and do_blockdev_backup Sergio Lopez
2019-11-28 10:41 ` [PATCH v5 1/4] blockdev: fix coding style issues in drive_backup_prepare Sergio Lopez
2019-11-28 10:41 ` [PATCH v5 2/4] blockdev: unify qmp_drive_backup and drive-backup transaction paths Sergio Lopez
2019-11-28 10:41 ` [PATCH v5 3/4] blockdev: unify qmp_blockdev_backup and blockdev-backup " Sergio Lopez
2019-11-28 10:41 ` [PATCH v5 4/4] blockdev: honor bdrv_try_set_aio_context() context requirements Sergio Lopez
2019-12-09 16:06   ` Kevin Wolf [this message]
2019-12-13 20:59     ` Eric Blake
2019-12-16 11:29       ` Kevin Wolf
2019-12-18 15:39         ` Sergio Lopez
2019-12-18 15:08       ` Sergio Lopez
2019-12-18 15:38     ` Sergio Lopez
2019-12-09 16:07 ` [PATCH v5 0/4] blockdev: avoid acquiring AioContext lock twice at do_drive_backup and do_blockdev_backup 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=20191209160601.GB6715@linux.fritz.box \
    --to=kwolf@redhat.com \
    --cc=armbru@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=slp@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).