On 11/04/2018 18:39, Kevin Wolf wrote:
> +bool bdrv_drain_poll(BlockDriverState *bs, bool top_level)
>  {
>      /* Execute pending BHs first and check everything else only after the BHs
>       * have executed. */
> -    while (aio_poll(bs->aio_context, false));
> +    if (top_level) {
> +        while (aio_poll(bs->aio_context, false));
> +    }
> +
> +    if (bdrv_parent_drained_poll(bs)) {
> +        return true;
> +    }
> +
>      return atomic_read(&bs->in_flight);
>  }
>  

Up until now I liked very much this series, but I like this patch a bit
less for two reasons.

1) I think I would prefer to have the !top_level case in a separate
function---making the API easier to use in the BdrvChildRole callback
because there is no need to pass false.  In addition, the callback is
not really polling anything, but rather returning whether the children
are quiescent.  So a better name would be bdrv_children_drained and
c->role->drained.

2) Worse, the main idea behind the first drain restructuring was that
draining could proceed in topological order: first drain the roots' I/O,
then call bdrv_drain to send the last requests to their children, then
recurse.  It is not clear to me why you need to introduce this recursive
step, which is also O(n^2) in the worst case.

Paolo

Reply via email to