* [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once
@ 2010-07-16 16:17 Kevin Wolf
2010-07-16 18:16 ` Christoph Hellwig
2010-07-17 7:26 ` Stefan Hajnoczi
0 siblings, 2 replies; 4+ messages in thread
From: Kevin Wolf @ 2010-07-16 16:17 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf
bdrv_commit copies the image to its backing file sector by sector, which
is (surprise!) relatively slow. Let's take a larger buffer and handle more
sectors at once if possible.
With a 1G qcow2 file, this brought the time bdrv_commit takes down from
5:06 min to 1:14 min for me.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block.c | 35 ++++++++++++++++++-----------------
1 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/block.c b/block.c
index 65cf4dc..12dbc43 100644
--- a/block.c
+++ b/block.c
@@ -729,9 +729,9 @@ int bdrv_commit(BlockDriverState *bs)
{
BlockDriver *drv = bs->drv;
int64_t i, total_sectors;
- int n, j, ro, open_flags;
+ int n, ro, open_flags;
int ret = 0, rw_ret = 0;
- unsigned char sector[BDRV_SECTOR_SIZE];
+ uint8_t *buf;
char filename[1024];
BlockDriverState *bs_rw, *bs_ro;
@@ -774,25 +774,26 @@ int bdrv_commit(BlockDriverState *bs)
}
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
+ buf = qemu_malloc(2048 * BDRV_SECTOR_SIZE);
+
for (i = 0; i < total_sectors;) {
- if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
- for(j = 0; j < n; j++) {
- if (bdrv_read(bs, i, sector, 1) != 0) {
- ret = -EIO;
- goto ro_cleanup;
- }
+ if (drv->bdrv_is_allocated(bs, i, 2048, &n)) {
- if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
- ret = -EIO;
- goto ro_cleanup;
- }
- i++;
- }
- } else {
- i += n;
+ if (bdrv_read(bs, i, buf, n) != 0) {
+ ret = -EIO;
+ goto ro_cleanup;
+ }
+
+ if (bdrv_write(bs->backing_hd, i, buf, n) != 0) {
+ ret = -EIO;
+ goto ro_cleanup;
+ }
}
+ i += n;
}
+ qemu_free(buf);
+
if (drv->bdrv_make_empty) {
ret = drv->bdrv_make_empty(bs);
bdrv_flush(bs);
--
1.7.1.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once
2010-07-16 16:17 [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once Kevin Wolf
@ 2010-07-16 18:16 ` Christoph Hellwig
2010-07-19 9:37 ` Kevin Wolf
2010-07-17 7:26 ` Stefan Hajnoczi
1 sibling, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2010-07-16 18:16 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On Fri, Jul 16, 2010 at 06:17:36PM +0200, Kevin Wolf wrote:
> + buf = qemu_malloc(2048 * BDRV_SECTOR_SIZE);
Please add a COMMIT_BUF_SIZE #define instead of the hardcoded 2048 in
various places.
> for (i = 0; i < total_sectors;) {
> + if (drv->bdrv_is_allocated(bs, i, 2048, &n)) {
>
> + if (bdrv_read(bs, i, buf, n) != 0) {
> + ret = -EIO;
> + goto ro_cleanup;
> + }
> +
> + if (bdrv_write(bs->backing_hd, i, buf, n) != 0) {
> + ret = -EIO;
> + goto ro_cleanup;
> + }
> }
> + i += n;
Maybe it's just me, but I'd prefer n getting a more descriptive name
(e.g. sector) and moving the increment of it into the for loop, e.g.
for (sector = 0; sector < total_sectors; sector += n) {
if (!drv->bdrv_is_allocated(bs, i, 2048, &n))
continue;
...
}
Otherwise this looks good to me.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once
2010-07-16 18:16 ` Christoph Hellwig
@ 2010-07-19 9:37 ` Kevin Wolf
0 siblings, 0 replies; 4+ messages in thread
From: Kevin Wolf @ 2010-07-19 9:37 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: qemu-devel
Am 16.07.2010 20:16, schrieb Christoph Hellwig:
> On Fri, Jul 16, 2010 at 06:17:36PM +0200, Kevin Wolf wrote:
>> + buf = qemu_malloc(2048 * BDRV_SECTOR_SIZE);
>
> Please add a COMMIT_BUF_SIZE #define instead of the hardcoded 2048 in
> various places.
>
>> for (i = 0; i < total_sectors;) {
>> + if (drv->bdrv_is_allocated(bs, i, 2048, &n)) {
>>
>> + if (bdrv_read(bs, i, buf, n) != 0) {
>> + ret = -EIO;
>> + goto ro_cleanup;
>> + }
>> +
>> + if (bdrv_write(bs->backing_hd, i, buf, n) != 0) {
>> + ret = -EIO;
>> + goto ro_cleanup;
>> + }
>> }
>> + i += n;
>
> Maybe it's just me, but I'd prefer n getting a more descriptive name
> (e.g. sector) and moving the increment of it into the for loop, e.g.
>
> for (sector = 0; sector < total_sectors; sector += n) {
> if (!drv->bdrv_is_allocated(bs, i, 2048, &n))
> continue;
> ...
> }
So you mean i should be renamed, not n, right? I'll change these points
in v2.
Kevin
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once
2010-07-16 16:17 [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once Kevin Wolf
2010-07-16 18:16 ` Christoph Hellwig
@ 2010-07-17 7:26 ` Stefan Hajnoczi
1 sibling, 0 replies; 4+ messages in thread
From: Stefan Hajnoczi @ 2010-07-17 7:26 UTC (permalink / raw)
To: Kevin Wolf; +Cc: qemu-devel
On Fri, Jul 16, 2010 at 5:17 PM, Kevin Wolf <kwolf@redhat.com> wrote:
> bdrv_commit copies the image to its backing file sector by sector, which
> is (surprise!) relatively slow. Let's take a larger buffer and handle more
> sectors at once if possible.
>
> With a 1G qcow2 file, this brought the time bdrv_commit takes down from
> 5:06 min to 1:14 min for me.
Nice performance improvement!
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
> block.c | 35 ++++++++++++++++++-----------------
> 1 files changed, 18 insertions(+), 17 deletions(-)
>
> diff --git a/block.c b/block.c
> index 65cf4dc..12dbc43 100644
> --- a/block.c
> +++ b/block.c
> @@ -729,9 +729,9 @@ int bdrv_commit(BlockDriverState *bs)
> {
> BlockDriver *drv = bs->drv;
> int64_t i, total_sectors;
> - int n, j, ro, open_flags;
> + int n, ro, open_flags;
> int ret = 0, rw_ret = 0;
> - unsigned char sector[BDRV_SECTOR_SIZE];
> + uint8_t *buf;
> char filename[1024];
> BlockDriverState *bs_rw, *bs_ro;
>
> @@ -774,25 +774,26 @@ int bdrv_commit(BlockDriverState *bs)
> }
>
> total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
> + buf = qemu_malloc(2048 * BDRV_SECTOR_SIZE);
> +
> for (i = 0; i < total_sectors;) {
> - if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
> - for(j = 0; j < n; j++) {
> - if (bdrv_read(bs, i, sector, 1) != 0) {
> - ret = -EIO;
> - goto ro_cleanup;
> - }
> + if (drv->bdrv_is_allocated(bs, i, 2048, &n)) {
>
> - if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
> - ret = -EIO;
> - goto ro_cleanup;
> - }
> - i++;
> - }
> - } else {
> - i += n;
> + if (bdrv_read(bs, i, buf, n) != 0) {
> + ret = -EIO;
> + goto ro_cleanup;
> + }
> +
> + if (bdrv_write(bs->backing_hd, i, buf, n) != 0) {
> + ret = -EIO;
> + goto ro_cleanup;
> + }
> }
> + i += n;
> }
>
> + qemu_free(buf);
Is buf being freed in the error case ro_cleanup label?
Stefan
> +
> if (drv->bdrv_make_empty) {
> ret = drv->bdrv_make_empty(bs);
> bdrv_flush(bs);
> --
> 1.7.1.1
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-07-19 9:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-16 16:17 [Qemu-devel] [PATCH] block: Change bdrv_commit to handle multiple sectors at once Kevin Wolf
2010-07-16 18:16 ` Christoph Hellwig
2010-07-19 9:37 ` Kevin Wolf
2010-07-17 7:26 ` Stefan Hajnoczi
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).