qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [Qemu-block] Once again with feeling: work-around for s


From: Eric Blake
Subject: Re: [Qemu-devel] [Qemu-block] Once again with feeling: work-around for slow SEEK_HOLE on Linux tmpfs.
Date: Wed, 16 Nov 2016 15:34:10 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0

On 11/16/2016 01:48 PM, Christopher Oliver wrote:
> 
> 

Attaching the patch (rather than including it inline) requires reviewers
to save the attachment off to a file in order to even see what you
wrote.  To save others some time, I'm pasting the text and replying inline:

> The following patch is a work-around for slow SEEK_HOLE on some filesystems.

The subject line is too long and doesn't match the usual pattern of
"category: short synopsis".

> Specifically, SEEK_HOLE on a dense file on Linux tmpfs is linear time in
> the length.  This slows qemu-img to a crawl as it runs SEEK_DATA/SEEK_HOLE
> pairs over the length of the image it's reading stepping by small deltas.
> 
> The key observation is that if the descriptor is read-only, and there are
> no writers anywhere else (that's undefined behavior anyhow, right?), then a
> hole seek in the interval from the previous start to the previously found
> hole will find the same hole.
> 
> Signed-off-by: Christopher Oliver

The S-o-b is incorrect; it is missing an email address.  Without that,
the patch cannot be accepted.  You'll want to try again, but this time,
I suggest getting 'qemu send-email' working to the point that you can
send yourself an inline patch (not an attachment), before sending v2 to
the list; you may also want to check out other patch submission
guidelines here:

http://wiki.qemu.org/Contribute/SubmitAPatch

> 
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index 28b47d9..b45defe 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -136,6 +136,8 @@ typedef struct BDRVRawState {
>      int type;
>      int open_flags;
>      size_t buf_align;
> +    off_t last_hole;
> +    off_t hole_follows;
>  
>  #ifdef CONFIG_XFS
>      bool is_xfs:1;
> @@ -470,6 +472,7 @@ static int raw_open_common(BlockDriverState *bs, QDict 
> *options,
>  
>      s->has_discard = true;
>      s->has_write_zeroes = true;
> +    s->last_hole = -1;
>      bs->supported_zero_flags = BDRV_REQ_MAY_UNMAP;
>      if ((bs->open_flags & BDRV_O_NOCACHE) != 0) {
>          s->needs_alignment = true;
> @@ -1710,7 +1713,24 @@ static int find_allocation(BlockDriverState *bs, off_t 
> start,
>       * H4. offs < 0, errno != ENXIO: we learned nothing
>       *     Pretend we know nothing at all, i.e. "forget" about D1.
>       */
> -    offs = lseek(s->fd, start, SEEK_HOLE);
> +    /* Addendum: Since HOLE seeks are expensive on some filesystems

Can anything be done to Linux tmpfs to make HOLE seeks less expensive?

> +     * (e.g. tmpfs) and holes don't change when an image is read only,
> +     * cache the range from a start to a hold and return that value

s/hold/hole/

> +     * for requests in that interval.  Outside of that interval, seek
> +     * and cache the new range.
> +     */
> +    if  ((s->open_flags & (O_RDWR|O_RDONLY)) == O_RDONLY) {
> +        if (start <= s->last_hole && start >= s->hole_follows) {
> +            offs = lseek(s->fd, s->last_hole, SEEK_SET);
> +        } else {
> +            offs = lseek(s->fd, start, SEEK_HOLE);
> +            s->last_hole = offs;
> +            s->hole_follows = start;
> +        }
> +    } else {
> +        offs = lseek(s->fd, start, SEEK_HOLE);
> +    }
> +
>      if (offs < 0) {
>          return -errno;          /* D1 and (H3 or H4) */
>      }

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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