qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Denis V. Lunev" <den@openvz.org>
To: Paolo Bonzini <pbonzini@redhat.com>,
	qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Evgeny Yakovlev <eyakovlev@virtuozzo.com>,
	Max Reitz <mreitz@redhat.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	Fam Zheng <famz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 1/3] block: ignore flush requests when storage is clean
Date: Wed, 29 Jun 2016 11:32:32 +0300	[thread overview]
Message-ID: <577387A0.9020006@openvz.org> (raw)
In-Reply-To: <94839058-7044-cc98-45f5-170ac8906690@redhat.com>

On 06/29/2016 10:36 AM, Paolo Bonzini wrote:
>
> On 28/06/2016 23:01, Paolo Bonzini wrote:
>>
>> On 24/06/2016 17:06, Denis V. Lunev wrote:
>>> From: Evgeny Yakovlev <eyakovlev@virtuozzo.com>
>>>
>>> Some guests (win2008 server for example) do a lot of unnecessary
>>> flushing when underlying media has not changed. This adds additional
>>> overhead on host when calling fsync/fdatasync.
>>>
>>> This change introduces a dirty flag in BlockDriverState which is set
>>> in bdrv_set_dirty and is checked in bdrv_co_flush. This allows us to
>>> avoid unnesessary flushing when storage is clean.
>>>
>>> The problem with excessive flushing was found by a performance test
>>> which does parallel directory tree creation (from 2 processes).
>>> Results improved from 0.424 loops/sec to 0.432 loops/sec.
>>> Each loop creates 10^3 directories with 10 files in each.
>>>
>>> Signed-off-by: Evgeny Yakovlev <eyakovlev@virtuozzo.com>
>>> Signed-off-by: Denis V. Lunev <den@openvz.org>
>>> CC: Kevin Wolf <kwolf@redhat.com>
>>> CC: Max Reitz <mreitz@redhat.com>
>>> CC: Stefan Hajnoczi <stefanha@redhat.com>
>>> CC: Fam Zheng <famz@redhat.com>
>>> CC: John Snow <jsnow@redhat.com>
>>> ---
>>>   block.c                   |  1 +
>>>   block/dirty-bitmap.c      |  3 +++
>>>   block/io.c                | 19 +++++++++++++++++++
>>>   include/block/block_int.h |  2 ++
>>>   4 files changed, 25 insertions(+)
>>>
>>> diff --git a/block.c b/block.c
>>> index f4648e9..e36f148 100644
>>> --- a/block.c
>>> +++ b/block.c
>>> @@ -2582,6 +2582,7 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset)
>>>           ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
>>>           bdrv_dirty_bitmap_truncate(bs);
>>>           bdrv_parent_cb_resize(bs);
>>> +        bs->dirty = true; /* file node sync is needed after truncate */
>>>       }
>>>       return ret;
>>>   }
>>> diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
>>> index 4902ca5..54e0413 100644
>>> --- a/block/dirty-bitmap.c
>>> +++ b/block/dirty-bitmap.c
>>> @@ -370,6 +370,9 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t cur_sector,
>>>           }
>>>           hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
>>>       }
>>> +
>>> +    /* Set global block driver dirty flag even if bitmap is disabled */
>>> +    bs->dirty = true;
>>>   }
>>>   
>>>   /**
>>> diff --git a/block/io.c b/block/io.c
>>> index 7cf3645..8078af2 100644
>>> --- a/block/io.c
>>> +++ b/block/io.c
>>> @@ -2239,6 +2239,25 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
>>>           goto flush_parent;
>>>       }
>>>   
>>> +    /* Check if storage is actually dirty before flushing to disk */
>>> +    if (!bs->dirty) {
>>> +        /* Flush requests are appended to tracked request list in order so that
>>> +         * most recent request is at the head of the list. Following code uses
>>> +         * this ordering to wait for the most recent flush request to complete
>>> +         * to ensure that requests return in order */
>>> +        BdrvTrackedRequest *prev_req;
>>> +        QLIST_FOREACH(prev_req, &bs->tracked_requests, list) {
>>> +            if (prev_req == &req || prev_req->type != BDRV_TRACKED_FLUSH) {
>>> +                continue;
>>> +            }
>>> +
>>> +            qemu_co_queue_wait(&prev_req->wait_queue);
>>> +            break;
>>> +        }
>>> +        goto flush_parent;
>> Can you just have a CoQueue specific to flushes, where a completing
>> flush does a restart_all on the CoQueue?
> Something like this:
>
>      current_gen = bs->write_gen;
>      if (bs->flush_started_gen >= current_gen) {
>          while (bs->flushed_gen < current_gen) {
>              qemu_co_queue_wait(&bs->flush_queue);
>          }
>          return;
>      }
>
>      bs->flush_started_gen = current_gen;
>      ...
>      if (current_gen < bs->flushed_gen) {
>          bs->flushed_gen = current_gen;
>          qemu_co_queue_restart_all(&bs->flush_queue);
>      }
>
> Paolo
>
I have had exactly this inn mind originally but current queue
with tracked requests is also useful. If it is going to be removed
in 2.8, generation approach would also work.

Thank you,
     Den

  reply	other threads:[~2016-06-29  8:32 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-24 15:06 [Qemu-devel] [PATCH 0/3] block: ignore flush requests when storage is clean Denis V. Lunev
2016-06-24 15:06 ` [Qemu-devel] [PATCH 1/3] " Denis V. Lunev
2016-06-24 15:31   ` Eric Blake
2016-06-24 15:54     ` Evgeny Yakovlev
2016-06-28 21:01   ` Paolo Bonzini
2016-06-29  7:36     ` Paolo Bonzini
2016-06-29  8:32       ` Denis V. Lunev [this message]
2016-06-24 15:06 ` [Qemu-devel] [PATCH 2/3] ide: ignore retry_unit check for non-retry operations Denis V. Lunev
2016-06-28 20:56   ` Paolo Bonzini
2016-06-29  8:35     ` Evgeny Yakovlev
2016-06-29 10:41       ` Paolo Bonzini
2016-06-24 15:06 ` [Qemu-devel] [PATCH 3/3] tests: in IDE and AHCI tests perform DMA write before flushing Denis V. Lunev
2016-06-24 15:22 ` [Qemu-devel] [PATCH 0/3] block: ignore flush requests when storage is clean Eric Blake

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=577387A0.9020006@openvz.org \
    --to=den@openvz.org \
    --cc=eyakovlev@virtuozzo.com \
    --cc=famz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --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).