qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCHv7 10/17] block: honour BlockLimits in bdrv_co_di


From: Kevin Wolf
Subject: Re: [Qemu-devel] [PATCHv7 10/17] block: honour BlockLimits in bdrv_co_discard
Date: Mon, 11 Nov 2013 14:20:20 +0100
User-agent: Mutt/1.5.21 (2010-09-15)

Am 24.10.2013 um 12:06 hat Peter Lieven geschrieben:
> Reviewed-by: Eric Blake <address@hidden>
> Signed-off-by: Peter Lieven <address@hidden>
> ---
>  block.c |   37 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
> 
> diff --git a/block.c b/block.c
> index 0c0b0ac..b28dd42 100644
> --- a/block.c
> +++ b/block.c
> @@ -4234,6 +4234,11 @@ static void coroutine_fn bdrv_discard_co_entry(void 
> *opaque)
>      rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, 
> rwco->nb_sectors);
>  }
>  
> +/* if no limit is specified in the BlockLimits use a default
> + * of 32768 512-byte sectors (16 MiB) per request.
> + */
> +#define MAX_DISCARD_DEFAULT 32768
> +
>  int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
>                                   int nb_sectors)
>  {
> @@ -4255,7 +4260,37 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, 
> int64_t sector_num,
>      }
>  
>      if (bs->drv->bdrv_co_discard) {
> -        return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
> +        int max_discard = bs->bl.max_discard ?
> +                          bs->bl.max_discard : MAX_DISCARD_DEFAULT;
> +
> +        while (nb_sectors > 0) {
> +            int ret;
> +            int num = nb_sectors;
> +
> +            /* align request */
> +            if (bs->bl.discard_alignment &&
> +                num >= bs->bl.discard_alignment &&
> +                sector_num % bs->bl.discard_alignment) {
> +                if (num > bs->bl.discard_alignment) {
> +                    num = bs->bl.discard_alignment;
> +                }
> +                num -= sector_num % bs->bl.discard_alignment;
> +            }
> +
> +            /* limit request size */
> +            if (num > max_discard) {
> +                num = max_discard;
> +            }
> +
> +            ret = bs->drv->bdrv_co_discard(bs, sector_num, num);
> +            if (ret) {
> +                return ret;
> +            }
> +
> +            sector_num += num;
> +            nb_sectors -= num;
> +        }
> +        return 0;
>      } else if (bs->drv->bdrv_aio_discard) {
>          BlockDriverAIOCB *acb;
>          CoroutineIOCompletion co = {

You're only optimising drivers which have a .bdrv_co_discard()
implementation, but not those with .bdrv_aio_discard(). Not very nice,
and it would have been easy to avoid this by putting the loop around the
whole if statement instead of inside the 'then' branch.

Kevin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]