From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59351) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VktJh-0003qD-3N for qemu-devel@nongnu.org; Mon, 25 Nov 2013 05:23:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VktJa-0006jm-6X for qemu-devel@nongnu.org; Mon, 25 Nov 2013 05:22:57 -0500 Received: from mx.ipv6.kamp.de ([2a02:248:0:51::16]:55785 helo=mx01.kamp.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VktJZ-0006jQ-Lp for qemu-devel@nongnu.org; Mon, 25 Nov 2013 05:22:50 -0500 Message-ID: <5293250C.20803@kamp.de> Date: Mon, 25 Nov 2013 11:23:08 +0100 From: Peter Lieven MIME-Version: 1.0 References: <1385124001-3576-1-git-send-email-pbonzini@redhat.com> <1385124001-3576-7-git-send-email-pbonzini@redhat.com> In-Reply-To: <1385124001-3576-7-git-send-email-pbonzini@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v3 06/19] block: make bdrv_co_do_write_zeroes stricter in producing aligned requests List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini , qemu-devel@nongnu.org Cc: kwolf@redhat.com, ronniesahlberg@gmail.com, stefanha@redhat.com On 22.11.2013 13:39, Paolo Bonzini wrote: > Right now, bdrv_co_do_write_zeroes will only try to align the > beginning of the request. However, it is simpler for many > formats to expect the block layer to separate both the head *and* > the tail. This makes sure that the format's bdrv_co_write_zeroes > function will be called with aligned sector_num and nb_sectors for > the bulk of the request. > > Signed-off-by: Paolo Bonzini > --- > block.c | 35 +++++++++++++++++++++++------------ > 1 file changed, 23 insertions(+), 12 deletions(-) > > diff --git a/block.c b/block.c > index b18ee6b..de66b21 100644 > --- a/block.c > +++ b/block.c > @@ -2768,14 +2768,21 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, > while (nb_sectors > 0 && !ret) { > int num = nb_sectors; > > - /* align request */ > - if (bs->bl.write_zeroes_alignment && > - num >= bs->bl.write_zeroes_alignment && > - sector_num % bs->bl.write_zeroes_alignment) { > - if (num > bs->bl.write_zeroes_alignment) { > + /* Align request. Block drivers can expect the "bulk" of the request > + * to be aligned. > + */ > + if (bs->bl.write_zeroes_alignment > + && num > bs->bl.write_zeroes_alignment) { > + if (sector_num % bs->bl.write_zeroes_alignment != 0) { > + /* Make a small request up to the first aligned sector. */ > num = bs->bl.write_zeroes_alignment; > + num -= sector_num % bs->bl.write_zeroes_alignment; > + } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) { > + /* Shorten the request to the last aligned sector. num cannot > + * underflow because num > bs->bl.write_zeroes_alignment. > + */ > + num -= (sector_num + num) % bs->bl.write_zeroes_alignment; > } > - num -= sector_num % bs->bl.write_zeroes_alignment; > } > > /* limit request size */ > @@ -2793,16 +2800,20 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs, > /* Fall back to bounce buffer if write zeroes is unsupported */ > iov.iov_len = num * BDRV_SECTOR_SIZE; > if (iov.iov_base == NULL) { > - /* allocate bounce buffer only once and ensure that it > - * is big enough for this and all future requests. > - */ > - size_t bufsize = num <= nb_sectors ? num : max_write_zeroes; > - iov.iov_base = qemu_blockalign(bs, bufsize * BDRV_SECTOR_SIZE); > - memset(iov.iov_base, 0, bufsize * BDRV_SECTOR_SIZE); > + iov.iov_base = qemu_blockalign(bs, num * BDRV_SECTOR_SIZE); > + memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE); > } > qemu_iovec_init_external(&qiov, &iov, 1); > > ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov); > + > + /* Keep bounce buffer around if it is big enough for all > + * all future requests. > + */ > + if (num < max_write_zeroes) { > + qemu_vfree(iov.iov_base); > + iov.iov_base = NULL; > + } > } > > sector_num += num; Reviewed-by: Peter Lieven