From: Laurent Vivier <Laurent.Vivier@bull.net>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <Laurent.Vivier@bull.net>
Subject: [Qemu-devel] [PATCH 3/4] qcow2: Align I/O access to l2 table and refcount block.
Date: Thu, 06 Nov 2008 17:55:59 +0100 [thread overview]
Message-ID: <1225990559.6576.13.camel@frecb07144> (raw)
In-Reply-To: 20081106165212.380421945@bull.net
pièce jointe document texte brut
(0003-Align-I-O-access-to-l2-table-and-refcount-block.patch)
When used with O_DIRECT, to align I/O access (memory and offset)
avoids to have to do a read before doing a write at the block-raw
level (to align access at this level).
Signed-off-by: Laurent Vivier <Laurent.Vivier@bull.net>
---
block-qcow2.c | 40 +++++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 11 deletions(-)
Index: qemu/block-qcow2.c
===================================================================
--- qemu.orig/block-qcow2.c 2008-11-06 16:40:54.000000000 +0100
+++ qemu/block-qcow2.c 2008-11-06 16:41:09.000000000 +0100
@@ -255,7 +255,8 @@ static int qcow_open(BlockDriverState *b
be64_to_cpus(&s->l1_table[i]);
}
/* alloc L2 cache */
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
+ s->l2_cache = qemu_memalign(512,
+ s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
if (!s->l2_cache)
goto fail;
s->cluster_cache = qemu_malloc(s->cluster_size);
@@ -865,7 +866,7 @@ static uint64_t alloc_cluster_offset(Blo
int *num)
{
BDRVQcowState *s = bs->opaque;
- int l2_index, ret;
+ int l2_index, ret, aligned_index, aligned_size;
uint64_t l2_offset, *l2_table, cluster_offset;
int nb_available, nb_clusters, i, j;
uint64_t start_sect, current;
@@ -988,11 +989,18 @@ static uint64_t alloc_cluster_offset(Blo
(i << s->cluster_bits)) |
QCOW_OFLAG_COPIED);
+ /* l2 table is part of l2_cache
+ * size of l2_cache is s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t)
+ * and s->l2_bits is (s->cluster_bits - 3) = 12 - 3 = 9;
+ * and s->l2_size = 1 << s->l2_bits, so l2_cache is aligned on 512 boundary.
+ */
+ aligned_index = l2_index & ~63;
+ aligned_size = (l2_index - aligned_index + nb_clusters + 63) & ~63ULL;
+ aligned_size *= sizeof(uint64_t);
if (bdrv_pwrite(s->hd,
- l2_offset + l2_index * sizeof(uint64_t),
- l2_table + l2_index,
- nb_clusters * sizeof(uint64_t)) !=
- nb_clusters * sizeof(uint64_t))
+ l2_offset + aligned_index * sizeof(uint64_t),
+ l2_table + aligned_index,
+ aligned_size) != aligned_size)
return 0;
out:
@@ -2137,7 +2145,7 @@ static int refcount_init(BlockDriverStat
BDRVQcowState *s = bs->opaque;
int ret, refcount_table_size2, i;
- s->refcount_block_cache = qemu_malloc(s->cluster_size);
+ s->refcount_block_cache = qemu_memalign(512, s->cluster_size);
if (!s->refcount_block_cache)
goto fail;
refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
@@ -2398,6 +2406,7 @@ static int update_cluster_refcount(Block
int ret, refcount_table_index, refcount_table_last_index, block_index, refcount;
int nb_block_index;
int refcount_cache_size;
+ int aligned_index, aligned_size;
if (nb_clusters == 0)
return 0;
@@ -2454,11 +2463,20 @@ static int update_cluster_refcount(Block
nb_block_index++;
nb_clusters--;
}
+ /*
+ * size of refcount_block_cache is s->cluster_size (4096)
+ * so we can align access on a 512 boundary
+ */
+ aligned_index = block_index & ~((512 >> REFCOUNT_SHIFT) - 1);
+ aligned_size = (block_index - aligned_index + nb_block_index +
+ ((512 >> REFCOUNT_SHIFT) - 1)) &
+ ~((512 >> REFCOUNT_SHIFT) - 1);
+ aligned_size *= sizeof(uint16_t);
if (bdrv_pwrite(s->hd,
- refcount_block_offset + (block_index << REFCOUNT_SHIFT),
- s->refcount_block_cache + block_index,
- nb_block_index * sizeof(uint16_t)) !=
- nb_block_index * sizeof(uint16_t))
+ refcount_block_offset +
+ (aligned_index << REFCOUNT_SHIFT),
+ s->refcount_block_cache + aligned_index,
+ aligned_size) != aligned_size)
return -EIO;
}
return refcount;
--
next prev parent reply other threads:[~2008-11-06 16:56 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20081106165212.380421945@bull.net>
2008-11-06 16:55 ` [Qemu-devel] [PATCH 1/4] qcow2: Clean-up update_cluster_refcount() Laurent Vivier
2008-11-06 17:32 ` Kevin Wolf
2008-11-07 8:48 ` Laurent Vivier
2008-11-07 8:54 ` Kevin Wolf
2008-11-07 9:22 ` Laurent Vivier
2008-11-06 16:55 ` [Qemu-devel] [PATCH 2/4] qcow2: Allow update_cluster_refcount() to update several clusters refcount Laurent Vivier
2008-11-06 18:11 ` Kevin Wolf
2008-11-07 10:03 ` Laurent Vivier
2008-11-07 10:21 ` Kevin Wolf
2008-11-07 11:39 ` Laurent Vivier
2008-11-06 16:55 ` Laurent Vivier [this message]
2008-11-06 16:56 ` [Qemu-devel] [PATCH 4/4] qcow2: detect if no disk cache Laurent Vivier
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=1225990559.6576.13.camel@frecb07144 \
--to=laurent.vivier@bull.net \
--cc=qemu-devel@nongnu.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.