From: Xiang Zheng <zhengxiang9@huawei.com> To: qemu-block@nongnu.org, qemu-devel@nongnu.org Cc: wanghaibin.wang@huawei.com, peter.maydell@linaro.org, guoheyi@huawei.com, lersek@redhat.com, mreitz@redhat.com, armbru@redhat.com, kwolf@redhat.com, ard.biesheuvel@linaro.org, stefanha@redhat.com, Xiang Zheng <zhengxiang9@huawei.com> Subject: [Qemu-devel] [PATCH] pflash: Only read non-zero parts of backend image Date: Sun, 5 May 2019 15:00:59 +0800 [thread overview] Message-ID: <20190505070059.4664-1-zhengxiang9@huawei.com> (raw) Currently we fill the memory space with two 64MB NOR images when using persistent UEFI variables on virt board. Actually we only use a very small(non-zero) part of the memory while the rest significant large(zero) part of memory is wasted. So this patch checks the block status and only writes the non-zero part into memory. This requires pflash devices to use sparse files for backends. Suggested-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com> --- hw/block/block.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/hw/block/block.c b/hw/block/block.c index bf56c76..3cb9d4c 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -15,6 +15,44 @@ #include "qapi/qapi-types-block.h" /* + * Read the non-zeroes parts of @blk into @buf + * Reading all of the @blk is expensive if the zeroes parts of @blk + * is large enough. Therefore check the block status and only write + * the non-zeroes block into @buf. + * + * Return 0 on success, non-zero on error. + */ +static int blk_pread_nonzeroes(BlockBackend *blk, void *buf) +{ + int ret; + int64_t target_size, bytes, offset = 0; + BlockDriverState *bs = blk_bs(blk); + + target_size = bdrv_getlength(bs); + if (target_size < 0) { + return target_size; + } + + for (;;) { + bytes = MIN(target_size - offset, BDRV_REQUEST_MAX_SECTORS); + if (bytes <= 0) { + return 0; + } + ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL); + if (ret < 0) { + return ret; + } + if (!(ret & BDRV_BLOCK_ZERO)) { + ret = bdrv_pread(bs->file, offset, (uint8_t *) buf + offset, bytes); + if (ret < 0) { + return ret; + } + } + offset += bytes; + } +} + +/* * Read the entire contents of @blk into @buf. * @blk's contents must be @size bytes, and @size must be at most * BDRV_REQUEST_MAX_BYTES. @@ -53,7 +91,7 @@ bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size, * block device and read only on demand. */ assert(size <= BDRV_REQUEST_MAX_BYTES); - ret = blk_pread(blk, 0, buf, size); + ret = blk_pread_nonzeroes(blk, buf); if (ret < 0) { error_setg_errno(errp, -ret, "can't read block backend"); return false; -- 1.8.3.1
WARNING: multiple messages have this Message-ID (diff)
From: Xiang Zheng <zhengxiang9@huawei.com> To: <qemu-block@nongnu.org>, <qemu-devel@nongnu.org> Cc: kwolf@redhat.com, peter.maydell@linaro.org, ard.biesheuvel@linaro.org, armbru@redhat.com, mreitz@redhat.com, Xiang Zheng <zhengxiang9@huawei.com>, stefanha@redhat.com, guoheyi@huawei.com, wanghaibin.wang@huawei.com, lersek@redhat.com Subject: [Qemu-devel] [PATCH] pflash: Only read non-zero parts of backend image Date: Sun, 5 May 2019 15:00:59 +0800 [thread overview] Message-ID: <20190505070059.4664-1-zhengxiang9@huawei.com> (raw) Message-ID: <20190505070059.Lyq4oIDE-uobC6vxzuBp31m0JiopQOMfvBLpmgusxfg@z> (raw) Currently we fill the memory space with two 64MB NOR images when using persistent UEFI variables on virt board. Actually we only use a very small(non-zero) part of the memory while the rest significant large(zero) part of memory is wasted. So this patch checks the block status and only writes the non-zero part into memory. This requires pflash devices to use sparse files for backends. Suggested-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Xiang Zheng <zhengxiang9@huawei.com> --- hw/block/block.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/hw/block/block.c b/hw/block/block.c index bf56c76..3cb9d4c 100644 --- a/hw/block/block.c +++ b/hw/block/block.c @@ -15,6 +15,44 @@ #include "qapi/qapi-types-block.h" /* + * Read the non-zeroes parts of @blk into @buf + * Reading all of the @blk is expensive if the zeroes parts of @blk + * is large enough. Therefore check the block status and only write + * the non-zeroes block into @buf. + * + * Return 0 on success, non-zero on error. + */ +static int blk_pread_nonzeroes(BlockBackend *blk, void *buf) +{ + int ret; + int64_t target_size, bytes, offset = 0; + BlockDriverState *bs = blk_bs(blk); + + target_size = bdrv_getlength(bs); + if (target_size < 0) { + return target_size; + } + + for (;;) { + bytes = MIN(target_size - offset, BDRV_REQUEST_MAX_SECTORS); + if (bytes <= 0) { + return 0; + } + ret = bdrv_block_status(bs, offset, bytes, &bytes, NULL, NULL); + if (ret < 0) { + return ret; + } + if (!(ret & BDRV_BLOCK_ZERO)) { + ret = bdrv_pread(bs->file, offset, (uint8_t *) buf + offset, bytes); + if (ret < 0) { + return ret; + } + } + offset += bytes; + } +} + +/* * Read the entire contents of @blk into @buf. * @blk's contents must be @size bytes, and @size must be at most * BDRV_REQUEST_MAX_BYTES. @@ -53,7 +91,7 @@ bool blk_check_size_and_read_all(BlockBackend *blk, void *buf, hwaddr size, * block device and read only on demand. */ assert(size <= BDRV_REQUEST_MAX_BYTES); - ret = blk_pread(blk, 0, buf, size); + ret = blk_pread_nonzeroes(blk, buf); if (ret < 0) { error_setg_errno(errp, -ret, "can't read block backend"); return false; -- 1.8.3.1
next reply other threads:[~2019-05-05 7:02 UTC|newest] Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-05 7:00 Xiang Zheng [this message] 2019-05-05 7:00 ` [Qemu-devel] [PATCH] pflash: Only read non-zero parts of backend image Xiang Zheng 2019-05-05 15:37 ` Peter Maydell 2019-05-05 15:37 ` Peter Maydell 2019-05-06 2:51 ` Xiang Zheng 2019-05-07 18:01 ` Markus Armbruster 2019-05-07 19:03 ` Laszlo Ersek 2019-05-08 13:20 ` Markus Armbruster 2019-05-09 7:14 ` Xiang Zheng 2019-05-09 11:59 ` Markus Armbruster 2019-05-10 13:12 ` Xiang Zheng 2019-05-10 15:16 ` Markus Armbruster 2019-05-11 8:36 ` Xiang Zheng 2019-05-13 11:59 ` Markus Armbruster 2019-05-13 13:15 ` Kevin Wolf 2019-05-13 13:36 ` Markus Armbruster
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=20190505070059.4664-1-zhengxiang9@huawei.com \ --to=zhengxiang9@huawei.com \ --cc=ard.biesheuvel@linaro.org \ --cc=armbru@redhat.com \ --cc=guoheyi@huawei.com \ --cc=kwolf@redhat.com \ --cc=lersek@redhat.com \ --cc=mreitz@redhat.com \ --cc=peter.maydell@linaro.org \ --cc=qemu-block@nongnu.org \ --cc=qemu-devel@nongnu.org \ --cc=stefanha@redhat.com \ --cc=wanghaibin.wang@huawei.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: linkBe 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).