From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Ky89w-0005C4-Ey for qemu-devel@nongnu.org; Thu, 06 Nov 2008 11:56:40 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Ky89v-0005BZ-Bj for qemu-devel@nongnu.org; Thu, 06 Nov 2008 11:56:39 -0500 Received: from [199.232.76.173] (port=41037 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Ky89v-0005BT-7I for qemu-devel@nongnu.org; Thu, 06 Nov 2008 11:56:39 -0500 Received: from ecfrec.frec.bull.fr ([129.183.4.8]:40488) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Ky89u-0000EB-Ul for qemu-devel@nongnu.org; Thu, 06 Nov 2008 11:56:39 -0500 Received: from localhost (localhost [127.0.0.1]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id 247631A18BF for ; Thu, 6 Nov 2008 17:56:03 +0100 (CET) Received: from ecfrec.frec.bull.fr ([127.0.0.1]) by localhost (ecfrec.frec.bull.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 01454-03 for ; Thu, 6 Nov 2008 17:55:59 +0100 (CET) Received: from cyclope.frec.bull.fr (cyclope.frec.bull.fr [129.183.4.9]) by ecfrec.frec.bull.fr (Postfix) with ESMTP id 477F919FE03 for ; Thu, 6 Nov 2008 17:55:56 +0100 (CET) From: Laurent Vivier References: <20081106165212.380421945@bull.net> Content-Type: text/plain; charset=utf-8 Date: Thu, 06 Nov 2008 17:55:59 +0100 Message-Id: <1225990559.6576.13.camel@frecb07144> Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH 3/4] qcow2: Align I/O access to l2 table and refcount block. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Laurent Vivier pi=C3=A8ce 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 --- block-qcow2.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) Index: qemu/block-qcow2.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 =3D qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint= 64_t)); + s->l2_cache =3D qemu_memalign(512, + s->l2_size * L2_CACHE_SIZE * sizeof(uint= 64_t)); if (!s->l2_cache) goto fail; s->cluster_cache =3D qemu_malloc(s->cluster_size); @@ -865,7 +866,7 @@ static uint64_t alloc_cluster_offset(Blo int *num) { BDRVQcowState *s =3D 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); =20 + /* 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) =3D 12 - 3 =3D 9; + * and s->l2_size =3D 1 << s->l2_bits, so l2_cache is aligned on 512= boundary. + */ + aligned_index =3D l2_index & ~63; + aligned_size =3D (l2_index - aligned_index + nb_clusters + 63) & ~63= ULL; + aligned_size *=3D sizeof(uint64_t); if (bdrv_pwrite(s->hd, - l2_offset + l2_index * sizeof(uint64_t), - l2_table + l2_index, - nb_clusters * sizeof(uint64_t)) !=3D - nb_clusters * sizeof(uint64_t)) + l2_offset + aligned_index * sizeof(uint64_t), + l2_table + aligned_index, + aligned_size) !=3D aligned_size) return 0; =20 out: @@ -2137,7 +2145,7 @@ static int refcount_init(BlockDriverStat BDRVQcowState *s =3D bs->opaque; int ret, refcount_table_size2, i; =20 - s->refcount_block_cache =3D qemu_malloc(s->cluster_size); + s->refcount_block_cache =3D qemu_memalign(512, s->cluster_size); if (!s->refcount_block_cache) goto fail; refcount_table_size2 =3D 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_inde= x, refcount; int nb_block_index; int refcount_cache_size; + int aligned_index, aligned_size; =20 if (nb_clusters =3D=3D 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 =3D block_index & ~((512 >> REFCOUNT_SHIFT) - 1); + aligned_size =3D (block_index - aligned_index + nb_block_index += =20 + ((512 >> REFCOUNT_SHIFT) - 1)) & + ~((512 >> REFCOUNT_SHIFT) - 1); + aligned_size *=3D 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)) !=3D - nb_block_index * sizeof(uint16_t)) + refcount_block_offset + + (aligned_index << REFCOUNT_SHIFT), + s->refcount_block_cache + aligned_index, + aligned_size) !=3D aligned_size) return -EIO; } return refcount; --=20