On Tue, May 13, 2025 at 03:32:37AM +0200, Andrey Zhadchenko wrote:
> HBitmaps allow us to search set bits pretty fast. On the contrary,
> when searching zeroes, we may be forced to fully traverse the lower
> level.
> When we run blockdev-backup with mode=full on top of snapshot filter
> + cbw filter, the job fills copy bitmap by calling block_status()
> with range (X, virtual_size). The problem is that we check for zeroes
> in this whole range. We also hit the worst case here, as access
> bitmap is fully set and we need to scan the entire lowest level.
> After scanning the full bitmap we actually ask the block status of
> original image, which may return significantly lower amount of empty
> clusters.
> Beacuse of this, the backup job 'hangs' on block copy initializaiton
> for a long time with 100% CPU.
> 
> Example copy bitmap buildup time for image with clu_size=65536 and
> preallocated metadata
> size                 10T   11T
> blockdev-backup      52s   57s
> cbw + snap           325s  413s
> cbw + snap + patch   55s   61s
> 
> To fix it, reverse the access bitmap in cbw filter: rather set it

s/reverse/invert/

> when the user is not allowed to read the cluster.
> 
> Update qemu-iotest 257: now access bitmap have count 0 instead of
> the image size 67108864
> 
> Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@virtuozzo.com>
> ---
> @@ -501,9 +501,12 @@ static int cbw_open(BlockDriverState *bs, QDict 
> *options, int flags,
>          return -EINVAL;
>      }
>      bdrv_disable_dirty_bitmap(s->access_bitmap);
> -    bdrv_dirty_bitmap_merge_internal(s->access_bitmap,
> -                                     block_copy_dirty_bitmap(s->bcs), NULL,
> -                                     true);
> +    if (bitmap) {
> +        bdrv_dirty_bitmap_merge_internal(s->access_bitmap,
> +                                         block_copy_dirty_bitmap(s->bcs), 
> NULL,
> +                                         true);
> +        bdrv_dirty_bitmap_reverse(s->access_bitmap);

Is this setting the bits correctly?  Inverting a bitmap is a
reversible operation, but it looks odd that you are only reversing
once around the merge.  Either the two sources of the merge have the
same sense (whether that be 0 for dirty 1 for clean, or 0 for readable
1 for avoid) and no inverting is needed before or after the merge, or
the two sources have opposite sense (in which case, I would have
expected inverting one of the bitmaps before the merge to get them to
agree on sense, then merging, then inverting back to the desired
sense).  Am I missing something?

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization:  qemu.org | libguestfs.org


Reply via email to