qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Benoît Canet" <benoit.canet@irqsave.net>
To: Eric Blake <eblake@redhat.com>
Cc: "Benoît Canet" <benoit.canet@irqsave.net>,
	kwolf@redhat.com, jcody@redhat.com, qemu-devel@nongnu.org,
	stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH] block: Make op blocker recursive
Date: Thu, 19 Jun 2014 22:20:43 +0200	[thread overview]
Message-ID: <20140619202043.GA18306@irqsave.net> (raw)
In-Reply-To: <53A34460.8010302@redhat.com>

The Thursday 19 Jun 2014 à 14:13:20 (-0600), Eric Blake wrote :
> On 06/19/2014 02:01 PM, Benoît Canet wrote:
> > As the code will start to operate on arbitratry nodes we need the op blocker
> 
> s/arbitratry/arbitrary/
> 
> > to recursively block or unblock whole BDS subtrees.
> > 
> > Also add a function to reset all blocker from a BDS.
> > 
> > This patch also take care of changing blocker user so they are not broken.
> > 
> > Signed-off-by: Benoit Canet <benoit@irqsave.net>
> > ---
> 
> > +
> > +/* This remove unconditionally all blockers of type op of the subtree */
> 
> This unconditionally removes all blockers of type op of the subtree
> 
> Yikes - is that really what we want?  Or do we need to start doing
> blocker reference counting?
> 
> Consider:
> 
> base <- snap1 <- active
> 
> Looking at Jeff's proposal of making blockers based on access patterns
> rather than operations, we want the mere act of being a backing file to
> automatically put a guest_write block on base and snap1 (we must not
> modify the backing chain out of underneath active).  But now suppose we
> do two operations in parallel - we take a fleecing export of active, and
> we start a drive-mirror on active.
> 
> base <- snap1 <- active
>               |        \-- fleecing
>               \-- copy
> 
> Both of those actions should be doable in parallel, and both of them
> probably put additional blocker restrictions on the chain.  But if we
> unconditionally clear those additional restrictions on the first of the
> two jobs ending, that would inappropriately stop blocking that action
> from the still on-going second action.  The only way I see around that
> is via reference-counted blocking.  Definitely not 2.1 material (but
> good to be thinking about it now, so we can get it in early in the 2.2
> cycle).

I added this reset function for the case where a whole BDS subtree is detached
from the graph and will be destroyed.

It does happen in drive mirror and bdrv_unrefing it would lead to a failed
assertion.

So the reset function take care of removing blocker of dead subtrees.

What would be a cleaner solution ?

Best regards

Benoît

> 
> 
> >  
> > +/* This remove unconditionally all blockers */
> 
> Unconditionally remove all blockers
> 
> 
> >  
> > +/* Used to prevent recursion loop. A case exists in block commit mirror usage */
> > +static BlockDriverState *recurse_op_bs = NULL;
> > +/* take note of the recursion depth to allow assigning recurse_op_bs once */
> > +static uint64_t recurse_op_depth = 0;
> 
> The '= 0' is redundant; the C language guarantees that all static
> variables are 0-initialized.
> 
> > +
> > +/* set or unset an op blocker to a BDS whether set is true or false */
> > +void bdrv_op_block_action(BlockDriverState *bs, BlockOpType op,
> > +                          BlockerAction action, Error *reason)
> > +{
> 
> Not sure I follow that comment, since 'set' is not one of the parameter
> names.
> 
> 
> > +
> > +/* Recursively set or unset an op block to a BDS tree whether set is true or
> > + * false
> > + */
> > +void bdrv_recurse_op_block(BlockDriverState *bs, BlockOpType op,
> > +                           BlockerAction action, Error *reason)
> 
> and again
> 
> > +{
> > +    /* If recursion is detected simply return */
> > +    if (recurse_op_bs == bs) {
> > +        return;
> > +    }
> > +
> > +    /* if we are starting recursion remeber the bs for later comparison */
> 
> s/remeber/remember/
> 
> > +    if (!recurse_op_depth) {
> > +        recurse_op_bs = bs;
> > +    }
> > +
> > +    /* try to set or unset on bs->file and bs->backing_hd first */
> > +    bdrv_op_block_action(bs->file, op, action, reason);
> > +    bdrv_op_block_action(bs->backing_hd, op, action, reason);
> > +
> > +    /* if the BDS is a filter with multiple childs ask the driver to recurse */
> 
> s/childs/children/
> 
> 
> > +static void blkverify_recurse_op_block(BlockDriverState *bs, BlockOpType op,
> > +                                       BlockerAction action, Error *reason)
> > +{
> > +    BDRVBlkverifyState *s = bs->opaque;
> > +    bdrv_op_block_action(bs->file, op , action, reason);
> > +    bdrv_op_block_action(s->test_file, op , action, reason);
> 
> s/ ,/,/ twice
> 
> > +++ b/include/block/block_int.h
> > @@ -86,6 +86,11 @@ struct BlockDriver {
> >       */
> >      bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs,
> >                                               BlockDriverState *candidate);
> > +    /* In order to be able to recursively block operation on BDS trees filter
> > +     * like quorum can implement this callback
> 
> s/trees filter/trees, a filter/
> 
> -- 
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 

  reply	other threads:[~2014-06-19 20:20 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-19 20:01 [Qemu-devel] [PATCH] Recursive blocker Benoît Canet
2014-06-19 20:01 ` [Qemu-devel] [PATCH] block: Make op blocker recursive Benoît Canet
2014-06-19 20:13   ` Eric Blake
2014-06-19 20:20     ` Benoît Canet [this message]
2014-06-19 20:26       ` Eric Blake
2014-06-19 20:36         ` Benoît Canet
2014-06-20  5:01       ` Fam Zheng
2014-06-20 15:30         ` Eric Blake
2014-06-21  8:53           ` Fam Zheng
2014-06-21 10:45             ` Benoît Canet
2014-06-21 15:15               ` Fam Zheng
2014-06-21 15:39                 ` Benoît Canet
2014-06-21 15:40                   ` Benoît Canet
2014-06-23  4:32                     ` Fam Zheng
2014-06-23  5:17                       ` Benoît Canet
2014-06-23  7:07                         ` Fam Zheng

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=20140619202043.GA18306@irqsave.net \
    --to=benoit.canet@irqsave.net \
    --cc=eblake@redhat.com \
    --cc=jcody@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --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 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).