* [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads
@ 2019-05-06 14:27 Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 1/8] qcow2.h: add missing include Vladimir Sementsov-Ogievskiy
` (8 more replies)
0 siblings, 9 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
v6:
- Rebase on master, so 02 changed to reflect changes in
qcow2_compress(), keep r-b.
- Rewrite 06 to even simpler locking [Max], drop r-b
Drop following
"qcow2: qcow2_co_preadv: skip using hd_qiov when possible", I'll do
it in my other coming soon series, and it is actually unrelated to
current.
- Drop controversial perf test, hope I'll return to this topic, but not
in context of these series.
- Add Max's r-b's to all here, except 06
Vladimir Sementsov-Ogievskiy (8):
qcow2.h: add missing include
qcow2: add separate file for threaded data processing functions
qcow2-threads: use thread_pool_submit_co
qcow2-threads: qcow2_co_do_compress: protect queuing by mutex
qcow2-threads: split out generic path
qcow2: qcow2_co_preadv: improve locking
qcow2: bdrv_co_pwritev: move encryption code out of the lock
qcow2: do encryption in threads
block/qcow2.h | 20 ++-
block/qcow2-bitmap.c | 1 -
block/qcow2-cache.c | 1 -
block/qcow2-cluster.c | 8 +-
block/qcow2-refcount.c | 1 -
block/qcow2-snapshot.c | 1 -
block/qcow2-threads.c | 268 +++++++++++++++++++++++++++++++++++++++++
block/qcow2.c | 241 +++++-------------------------------
block/Makefile.objs | 2 +-
9 files changed, 321 insertions(+), 222 deletions(-)
create mode 100644 block/qcow2-threads.c
--
2.18.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 1/8] qcow2.h: add missing include
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 2/8] qcow2: add separate file for threaded data processing functions Vladimir Sementsov-Ogievskiy
` (7 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
qcow2.h depends on block_int.h. Compilation isn't broken currently only
due to block_int.h always included before qcow2.h. Though, it seems
better to directly include block_int.h in qcow2.h.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2.h | 1 +
block/qcow2-bitmap.c | 1 -
block/qcow2-cache.c | 1 -
block/qcow2-cluster.c | 1 -
block/qcow2-refcount.c | 1 -
block/qcow2-snapshot.c | 1 -
block/qcow2.c | 1 -
7 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/block/qcow2.h b/block/qcow2.h
index fdee297f33..ecb026e19a 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -28,6 +28,7 @@
#include "crypto/block.h"
#include "qemu/coroutine.h"
#include "qemu/units.h"
+#include "block/block_int.h"
//#define DEBUG_ALLOC
//#define DEBUG_ALLOC2
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index e53a1609d7..337c0ac680 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -29,7 +29,6 @@
#include "qapi/error.h"
#include "qemu/cutils.h"
-#include "block/block_int.h"
#include "qcow2.h"
/* NOTICE: BME here means Bitmaps Extension and used as a namespace for
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index df02e7b20a..b33bcbc984 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -23,7 +23,6 @@
*/
#include "qemu/osdep.h"
-#include "block/block_int.h"
#include "qemu-common.h"
#include "qcow2.h"
#include "trace.h"
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 974a4e8656..c4965479f6 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -27,7 +27,6 @@
#include "qapi/error.h"
#include "qemu-common.h"
-#include "block/block_int.h"
#include "qcow2.h"
#include "qemu/bswap.h"
#include "trace.h"
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index e0fe322500..ff27b6afd3 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -25,7 +25,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
-#include "block/block_int.h"
#include "qcow2.h"
#include "qemu/range.h"
#include "qemu/bswap.h"
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index a6ffae89a6..d0e7fa9311 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -24,7 +24,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "block/block_int.h"
#include "qcow2.h"
#include "qemu/bswap.h"
#include "qemu/error-report.h"
diff --git a/block/qcow2.c b/block/qcow2.c
index a520d116ef..ab231cbfe7 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -27,7 +27,6 @@
#define ZLIB_CONST
#include <zlib.h>
-#include "block/block_int.h"
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 2/8] qcow2: add separate file for threaded data processing functions
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 1/8] qcow2.h: add missing include Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 3/8] qcow2-threads: use thread_pool_submit_co Vladimir Sementsov-Ogievskiy
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Move compression-on-threads to separate file. Encryption will be in it
too.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2.h | 7 ++
block/qcow2-threads.c | 201 ++++++++++++++++++++++++++++++++++++++++++
block/qcow2.c | 169 -----------------------------------
block/Makefile.objs | 2 +-
4 files changed, 209 insertions(+), 170 deletions(-)
create mode 100644 block/qcow2-threads.c
diff --git a/block/qcow2.h b/block/qcow2.h
index ecb026e19a..61079f7ee8 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -735,4 +735,11 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs,
const char *name,
Error **errp);
+ssize_t coroutine_fn
+qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
+ const void *src, size_t src_size);
+ssize_t coroutine_fn
+qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
+ const void *src, size_t src_size);
+
#endif
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
new file mode 100644
index 0000000000..85b8034fd2
--- /dev/null
+++ b/block/qcow2-threads.c
@@ -0,0 +1,201 @@
+/*
+ * Threaded data processing for Qcow2: compression, encryption
+ *
+ * Copyright (c) 2004-2006 Fabrice Bellard
+ * Copyright (c) 2018 Virtuozzo International GmbH. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#define ZLIB_CONST
+#include <zlib.h>
+
+#include "qcow2.h"
+#include "block/thread-pool.h"
+
+#define MAX_COMPRESS_THREADS 4
+
+typedef ssize_t (*Qcow2CompressFunc)(void *dest, size_t dest_size,
+ const void *src, size_t src_size);
+typedef struct Qcow2CompressData {
+ void *dest;
+ size_t dest_size;
+ const void *src;
+ size_t src_size;
+ ssize_t ret;
+
+ Qcow2CompressFunc func;
+} Qcow2CompressData;
+
+/*
+ * qcow2_compress()
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: compressed size on success
+ * -ENOMEM destination buffer is not enough to store compressed data
+ * -EIO on any other error
+ */
+static ssize_t qcow2_compress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
+{
+ ssize_t ret;
+ z_stream strm;
+
+ /* best compression, small window, no zlib header */
+ memset(&strm, 0, sizeof(strm));
+ ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
+ -12, 9, Z_DEFAULT_STRATEGY);
+ if (ret != Z_OK) {
+ return -EIO;
+ }
+
+ /*
+ * strm.next_in is not const in old zlib versions, such as those used on
+ * OpenBSD/NetBSD, so cast the const away
+ */
+ strm.avail_in = src_size;
+ strm.next_in = (void *) src;
+ strm.avail_out = dest_size;
+ strm.next_out = dest;
+
+ ret = deflate(&strm, Z_FINISH);
+ if (ret == Z_STREAM_END) {
+ ret = dest_size - strm.avail_out;
+ } else {
+ ret = (ret == Z_OK ? -ENOMEM : -EIO);
+ }
+
+ deflateEnd(&strm);
+
+ return ret;
+}
+
+/*
+ * qcow2_decompress()
+ *
+ * Decompress some data (not more than @src_size bytes) to produce exactly
+ * @dest_size bytes.
+ *
+ * @dest - destination buffer, @dest_size bytes
+ * @src - source buffer, @src_size bytes
+ *
+ * Returns: 0 on success
+ * -1 on fail
+ */
+static ssize_t qcow2_decompress(void *dest, size_t dest_size,
+ const void *src, size_t src_size)
+{
+ int ret = 0;
+ z_stream strm;
+
+ memset(&strm, 0, sizeof(strm));
+ strm.avail_in = src_size;
+ strm.next_in = (void *) src;
+ strm.avail_out = dest_size;
+ strm.next_out = dest;
+
+ ret = inflateInit2(&strm, -12);
+ if (ret != Z_OK) {
+ return -1;
+ }
+
+ ret = inflate(&strm, Z_FINISH);
+ if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) {
+ /*
+ * We approve Z_BUF_ERROR because we need @dest buffer to be filled, but
+ * @src buffer may be processed partly (because in qcow2 we know size of
+ * compressed data with precision of one sector)
+ */
+ ret = -1;
+ }
+
+ inflateEnd(&strm);
+
+ return ret;
+}
+
+static int qcow2_compress_pool_func(void *opaque)
+{
+ Qcow2CompressData *data = opaque;
+
+ data->ret = data->func(data->dest, data->dest_size,
+ data->src, data->src_size);
+
+ return 0;
+}
+
+static void qcow2_compress_complete(void *opaque, int ret)
+{
+ qemu_coroutine_enter(opaque);
+}
+
+static ssize_t coroutine_fn
+qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
+ const void *src, size_t src_size, Qcow2CompressFunc func)
+{
+ BDRVQcow2State *s = bs->opaque;
+ BlockAIOCB *acb;
+ ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
+ Qcow2CompressData arg = {
+ .dest = dest,
+ .dest_size = dest_size,
+ .src = src,
+ .src_size = src_size,
+ .func = func,
+ };
+
+ while (s->nb_compress_threads >= MAX_COMPRESS_THREADS) {
+ qemu_co_queue_wait(&s->compress_wait_queue, NULL);
+ }
+
+ s->nb_compress_threads++;
+ acb = thread_pool_submit_aio(pool, qcow2_compress_pool_func, &arg,
+ qcow2_compress_complete,
+ qemu_coroutine_self());
+
+ if (!acb) {
+ s->nb_compress_threads--;
+ return -EINVAL;
+ }
+ qemu_coroutine_yield();
+ s->nb_compress_threads--;
+ qemu_co_queue_next(&s->compress_wait_queue);
+
+ return arg.ret;
+}
+
+ssize_t coroutine_fn
+qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
+ const void *src, size_t src_size)
+{
+ return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
+ qcow2_compress);
+}
+
+ssize_t coroutine_fn
+qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
+ const void *src, size_t src_size)
+{
+ return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
+ qcow2_decompress);
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index ab231cbfe7..facf8ab993 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -24,9 +24,6 @@
#include "qemu/osdep.h"
-#define ZLIB_CONST
-#include <zlib.h>
-
#include "block/qdict.h"
#include "sysemu/block-backend.h"
#include "qemu/module.h"
@@ -43,7 +40,6 @@
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-block-core.h"
#include "crypto.h"
-#include "block/thread-pool.h"
/*
Differences with QCOW:
@@ -3921,171 +3917,6 @@ fail:
return ret;
}
-/*
- * qcow2_compress()
- *
- * @dest - destination buffer, @dest_size bytes
- * @src - source buffer, @src_size bytes
- *
- * Returns: compressed size on success
- * -ENOMEM destination buffer is not enough to store compressed data
- * -EIO on any other error
- */
-static ssize_t qcow2_compress(void *dest, size_t dest_size,
- const void *src, size_t src_size)
-{
- ssize_t ret;
- z_stream strm;
-
- /* best compression, small window, no zlib header */
- memset(&strm, 0, sizeof(strm));
- ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
- -12, 9, Z_DEFAULT_STRATEGY);
- if (ret != Z_OK) {
- return -EIO;
- }
-
- /* strm.next_in is not const in old zlib versions, such as those used on
- * OpenBSD/NetBSD, so cast the const away */
- strm.avail_in = src_size;
- strm.next_in = (void *) src;
- strm.avail_out = dest_size;
- strm.next_out = dest;
-
- ret = deflate(&strm, Z_FINISH);
- if (ret == Z_STREAM_END) {
- ret = dest_size - strm.avail_out;
- } else {
- ret = (ret == Z_OK ? -ENOMEM : -EIO);
- }
-
- deflateEnd(&strm);
-
- return ret;
-}
-
-/*
- * qcow2_decompress()
- *
- * Decompress some data (not more than @src_size bytes) to produce exactly
- * @dest_size bytes.
- *
- * @dest - destination buffer, @dest_size bytes
- * @src - source buffer, @src_size bytes
- *
- * Returns: 0 on success
- * -1 on fail
- */
-static ssize_t qcow2_decompress(void *dest, size_t dest_size,
- const void *src, size_t src_size)
-{
- int ret = 0;
- z_stream strm;
-
- memset(&strm, 0, sizeof(strm));
- strm.avail_in = src_size;
- strm.next_in = (void *) src;
- strm.avail_out = dest_size;
- strm.next_out = dest;
-
- ret = inflateInit2(&strm, -12);
- if (ret != Z_OK) {
- return -1;
- }
-
- ret = inflate(&strm, Z_FINISH);
- if ((ret != Z_STREAM_END && ret != Z_BUF_ERROR) || strm.avail_out != 0) {
- /* We approve Z_BUF_ERROR because we need @dest buffer to be filled, but
- * @src buffer may be processed partly (because in qcow2 we know size of
- * compressed data with precision of one sector) */
- ret = -1;
- }
-
- inflateEnd(&strm);
-
- return ret;
-}
-
-#define MAX_COMPRESS_THREADS 4
-
-typedef ssize_t (*Qcow2CompressFunc)(void *dest, size_t dest_size,
- const void *src, size_t src_size);
-typedef struct Qcow2CompressData {
- void *dest;
- size_t dest_size;
- const void *src;
- size_t src_size;
- ssize_t ret;
-
- Qcow2CompressFunc func;
-} Qcow2CompressData;
-
-static int qcow2_compress_pool_func(void *opaque)
-{
- Qcow2CompressData *data = opaque;
-
- data->ret = data->func(data->dest, data->dest_size,
- data->src, data->src_size);
-
- return 0;
-}
-
-static void qcow2_compress_complete(void *opaque, int ret)
-{
- qemu_coroutine_enter(opaque);
-}
-
-static ssize_t coroutine_fn
-qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
- const void *src, size_t src_size, Qcow2CompressFunc func)
-{
- BDRVQcow2State *s = bs->opaque;
- BlockAIOCB *acb;
- ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
- Qcow2CompressData arg = {
- .dest = dest,
- .dest_size = dest_size,
- .src = src,
- .src_size = src_size,
- .func = func,
- };
-
- while (s->nb_compress_threads >= MAX_COMPRESS_THREADS) {
- qemu_co_queue_wait(&s->compress_wait_queue, NULL);
- }
-
- s->nb_compress_threads++;
- acb = thread_pool_submit_aio(pool, qcow2_compress_pool_func, &arg,
- qcow2_compress_complete,
- qemu_coroutine_self());
-
- if (!acb) {
- s->nb_compress_threads--;
- return -EINVAL;
- }
- qemu_coroutine_yield();
- s->nb_compress_threads--;
- qemu_co_queue_next(&s->compress_wait_queue);
-
- return arg.ret;
-}
-
-static ssize_t coroutine_fn
-qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
- const void *src, size_t src_size)
-{
- return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
- qcow2_compress);
-}
-
-static ssize_t coroutine_fn
-qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
- const void *src, size_t src_size)
-{
- return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
- qcow2_decompress);
-}
-
/* XXX: put compressed sectors first, then all the cluster aligned
tables to avoid losing bytes in alignment */
static coroutine_fn int
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 7a81892a52..ae11605c9f 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -6,7 +6,7 @@ block-obj-$(CONFIG_BOCHS) += bochs.o
block-obj-$(CONFIG_VVFAT) += vvfat.o
block-obj-$(CONFIG_DMG) += dmg.o
-block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o qcow2-bitmap.o
+block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o qcow2-bitmap.o qcow2-threads.o
block-obj-$(CONFIG_QED) += qed.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-$(CONFIG_QED) += qed-check.o
block-obj-y += vhdx.o vhdx-endian.o vhdx-log.o
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 3/8] qcow2-threads: use thread_pool_submit_co
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 1/8] qcow2.h: add missing include Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 2/8] qcow2: add separate file for threaded data processing functions Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 4/8] qcow2-threads: qcow2_co_do_compress: protect queuing by mutex Vladimir Sementsov-Ogievskiy
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Use thread_pool_submit_co, instead of reinventing it here. Note, that
thread_pool_submit_aio() never returns NULL, so checking it was an
extra thing.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2-threads.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 85b8034fd2..5a39fdac69 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -144,17 +144,11 @@ static int qcow2_compress_pool_func(void *opaque)
return 0;
}
-static void qcow2_compress_complete(void *opaque, int ret)
-{
- qemu_coroutine_enter(opaque);
-}
-
static ssize_t coroutine_fn
qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
const void *src, size_t src_size, Qcow2CompressFunc func)
{
BDRVQcow2State *s = bs->opaque;
- BlockAIOCB *acb;
ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
Qcow2CompressData arg = {
.dest = dest,
@@ -169,16 +163,9 @@ qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
}
s->nb_compress_threads++;
- acb = thread_pool_submit_aio(pool, qcow2_compress_pool_func, &arg,
- qcow2_compress_complete,
- qemu_coroutine_self());
-
- if (!acb) {
- s->nb_compress_threads--;
- return -EINVAL;
- }
- qemu_coroutine_yield();
+ thread_pool_submit_co(pool, qcow2_compress_pool_func, &arg);
s->nb_compress_threads--;
+
qemu_co_queue_next(&s->compress_wait_queue);
return arg.ret;
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 4/8] qcow2-threads: qcow2_co_do_compress: protect queuing by mutex
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
` (2 preceding siblings ...)
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 3/8] qcow2-threads: use thread_pool_submit_co Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 5/8] qcow2-threads: split out generic path Vladimir Sementsov-Ogievskiy
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Drop dependence on AioContext lock.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2-threads.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 5a39fdac69..50a9fdeec5 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -158,15 +158,19 @@ qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
.func = func,
};
+ qemu_co_mutex_lock(&s->lock);
while (s->nb_compress_threads >= MAX_COMPRESS_THREADS) {
- qemu_co_queue_wait(&s->compress_wait_queue, NULL);
+ qemu_co_queue_wait(&s->compress_wait_queue, &s->lock);
}
-
s->nb_compress_threads++;
+ qemu_co_mutex_unlock(&s->lock);
+
thread_pool_submit_co(pool, qcow2_compress_pool_func, &arg);
- s->nb_compress_threads--;
+ qemu_co_mutex_lock(&s->lock);
+ s->nb_compress_threads--;
qemu_co_queue_next(&s->compress_wait_queue);
+ qemu_co_mutex_unlock(&s->lock);
return arg.ret;
}
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 5/8] qcow2-threads: split out generic path
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
` (3 preceding siblings ...)
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 4/8] qcow2-threads: qcow2_co_do_compress: protect queuing by mutex Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 6/8] qcow2: qcow2_co_preadv: improve locking Vladimir Sementsov-Ogievskiy
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Move generic part out of qcow2_co_do_compress, to reuse it for
encryption and rename things that would be shared with encryption path.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2.h | 4 ++--
block/qcow2-threads.c | 47 ++++++++++++++++++++++++++++---------------
block/qcow2.c | 2 +-
3 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/block/qcow2.h b/block/qcow2.h
index 61079f7ee8..3089e9a68b 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -347,8 +347,8 @@ typedef struct BDRVQcow2State {
char *image_backing_format;
char *image_data_file;
- CoQueue compress_wait_queue;
- int nb_compress_threads;
+ CoQueue thread_task_queue;
+ int nb_threads;
BdrvChild *data_file;
} BDRVQcow2State;
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 50a9fdeec5..650aa2ed19 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -31,7 +31,36 @@
#include "qcow2.h"
#include "block/thread-pool.h"
-#define MAX_COMPRESS_THREADS 4
+#define QCOW2_MAX_THREADS 4
+
+static int coroutine_fn
+qcow2_co_process(BlockDriverState *bs, ThreadPoolFunc *func, void *arg)
+{
+ int ret;
+ BDRVQcow2State *s = bs->opaque;
+ ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
+
+ qemu_co_mutex_lock(&s->lock);
+ while (s->nb_threads >= QCOW2_MAX_THREADS) {
+ qemu_co_queue_wait(&s->thread_task_queue, &s->lock);
+ }
+ s->nb_threads++;
+ qemu_co_mutex_unlock(&s->lock);
+
+ ret = thread_pool_submit_co(pool, func, arg);
+
+ qemu_co_mutex_lock(&s->lock);
+ s->nb_threads--;
+ qemu_co_queue_next(&s->thread_task_queue);
+ qemu_co_mutex_unlock(&s->lock);
+
+ return ret;
+}
+
+
+/*
+ * Compression
+ */
typedef ssize_t (*Qcow2CompressFunc)(void *dest, size_t dest_size,
const void *src, size_t src_size);
@@ -148,8 +177,6 @@ static ssize_t coroutine_fn
qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
const void *src, size_t src_size, Qcow2CompressFunc func)
{
- BDRVQcow2State *s = bs->opaque;
- ThreadPool *pool = aio_get_thread_pool(bdrv_get_aio_context(bs));
Qcow2CompressData arg = {
.dest = dest,
.dest_size = dest_size,
@@ -158,19 +185,7 @@ qcow2_co_do_compress(BlockDriverState *bs, void *dest, size_t dest_size,
.func = func,
};
- qemu_co_mutex_lock(&s->lock);
- while (s->nb_compress_threads >= MAX_COMPRESS_THREADS) {
- qemu_co_queue_wait(&s->compress_wait_queue, &s->lock);
- }
- s->nb_compress_threads++;
- qemu_co_mutex_unlock(&s->lock);
-
- thread_pool_submit_co(pool, qcow2_compress_pool_func, &arg);
-
- qemu_co_mutex_lock(&s->lock);
- s->nb_compress_threads--;
- qemu_co_queue_next(&s->compress_wait_queue);
- qemu_co_mutex_unlock(&s->lock);
+ qcow2_co_process(bs, qcow2_compress_pool_func, &arg);
return arg.ret;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index facf8ab993..7970d0992a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1694,7 +1694,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
}
#endif
- qemu_co_queue_init(&s->compress_wait_queue);
+ qemu_co_queue_init(&s->thread_task_queue);
return ret;
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 6/8] qcow2: qcow2_co_preadv: improve locking
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
` (4 preceding siblings ...)
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 5/8] qcow2-threads: split out generic path Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-09 12:11 ` Alberto Garcia
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 7/8] qcow2: bdrv_co_pwritev: move encryption code out of the lock Vladimir Sementsov-Ogievskiy
` (2 subsequent siblings)
8 siblings, 1 reply; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Background: decryption will be done in threads, to take benefit of it,
we should move it out of the lock first.
But let's go further: it turns out, that only
qcow2_get_cluster_offset() needs locking, so reduce locking to it.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
block/qcow2.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 7970d0992a..5954696245 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1970,8 +1970,6 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
qemu_iovec_init(&hd_qiov, qiov->niov);
- qemu_co_mutex_lock(&s->lock);
-
while (bytes != 0) {
/* prepare next request */
@@ -1981,7 +1979,9 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
}
+ qemu_co_mutex_lock(&s->lock);
ret = qcow2_get_cluster_offset(bs, offset, &cur_bytes, &cluster_offset);
+ qemu_co_mutex_unlock(&s->lock);
if (ret < 0) {
goto fail;
}
@@ -1996,10 +1996,8 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
if (bs->backing) {
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
- qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_preadv(bs->backing, offset, cur_bytes,
&hd_qiov, 0);
- qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto fail;
}
@@ -2015,11 +2013,9 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
break;
case QCOW2_CLUSTER_COMPRESSED:
- qemu_co_mutex_unlock(&s->lock);
ret = qcow2_co_preadv_compressed(bs, cluster_offset,
offset, cur_bytes,
&hd_qiov);
- qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto fail;
}
@@ -2056,11 +2052,9 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
}
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
- qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_preadv(s->data_file,
cluster_offset + offset_in_cluster,
cur_bytes, &hd_qiov, 0);
- qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
goto fail;
}
@@ -2095,8 +2089,6 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
ret = 0;
fail:
- qemu_co_mutex_unlock(&s->lock);
-
qemu_iovec_destroy(&hd_qiov);
qemu_vfree(cluster_data);
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 7/8] qcow2: bdrv_co_pwritev: move encryption code out of the lock
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
` (5 preceding siblings ...)
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 6/8] qcow2: qcow2_co_preadv: improve locking Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 8/8] qcow2: do encryption in threads Vladimir Sementsov-Ogievskiy
2019-05-09 14:56 ` [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Max Reitz
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Encryption will be done in threads, to take benefit of it, we should
move it out of the lock first.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2.c | 35 +++++++++++++++++++++--------------
1 file changed, 21 insertions(+), 14 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 5954696245..cba2328005 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2169,11 +2169,20 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,
&cluster_offset, &l2meta);
if (ret < 0) {
- goto fail;
+ goto out_locked;
}
assert((cluster_offset & 511) == 0);
+ ret = qcow2_pre_write_overlap_check(bs, 0,
+ cluster_offset + offset_in_cluster,
+ cur_bytes, true);
+ if (ret < 0) {
+ goto out_locked;
+ }
+
+ qemu_co_mutex_unlock(&s->lock);
+
qemu_iovec_reset(&hd_qiov);
qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes);
@@ -2185,7 +2194,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
* s->cluster_size);
if (cluster_data == NULL) {
ret = -ENOMEM;
- goto fail;
+ goto out_unlocked;
}
}
@@ -2200,40 +2209,34 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
cluster_data,
cur_bytes, NULL) < 0) {
ret = -EIO;
- goto fail;
+ goto out_unlocked;
}
qemu_iovec_reset(&hd_qiov);
qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes);
}
- ret = qcow2_pre_write_overlap_check(bs, 0,
- cluster_offset + offset_in_cluster, cur_bytes, true);
- if (ret < 0) {
- goto fail;
- }
-
/* If we need to do COW, check if it's possible to merge the
* writing of the guest data together with that of the COW regions.
* If it's not possible (or not necessary) then write the
* guest data now. */
if (!merge_cow(offset, cur_bytes, &hd_qiov, l2meta)) {
- qemu_co_mutex_unlock(&s->lock);
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
trace_qcow2_writev_data(qemu_coroutine_self(),
cluster_offset + offset_in_cluster);
ret = bdrv_co_pwritev(s->data_file,
cluster_offset + offset_in_cluster,
cur_bytes, &hd_qiov, 0);
- qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
- goto fail;
+ goto out_unlocked;
}
}
+ qemu_co_mutex_lock(&s->lock);
+
ret = qcow2_handle_l2meta(bs, &l2meta, true);
if (ret) {
- goto fail;
+ goto out_locked;
}
bytes -= cur_bytes;
@@ -2242,8 +2245,12 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_bytes);
}
ret = 0;
+ goto out_locked;
-fail:
+out_unlocked:
+ qemu_co_mutex_lock(&s->lock);
+
+out_locked:
qcow2_handle_l2meta(bs, &l2meta, false);
qemu_co_mutex_unlock(&s->lock);
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [Qemu-devel] [PATCH v6 8/8] qcow2: do encryption in threads
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
` (6 preceding siblings ...)
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 7/8] qcow2: bdrv_co_pwritev: move encryption code out of the lock Vladimir Sementsov-Ogievskiy
@ 2019-05-06 14:27 ` Vladimir Sementsov-Ogievskiy
2019-05-09 14:56 ` [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Max Reitz
8 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-06 14:27 UTC (permalink / raw)
To: qemu-devel, qemu-block; +Cc: kwolf, vsementsov, berto, mreitz, den, pbonzini
Do encryption/decryption in threads, like it is already done for
compression. This improves asynchronous encrypted io.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
block/qcow2.h | 8 ++++++
block/qcow2-cluster.c | 7 ++---
block/qcow2-threads.c | 65 +++++++++++++++++++++++++++++++++++++++++--
block/qcow2.c | 22 +++++----------
4 files changed, 81 insertions(+), 21 deletions(-)
diff --git a/block/qcow2.h b/block/qcow2.h
index 3089e9a68b..5169c0d8ab 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -264,6 +264,8 @@ typedef struct Qcow2BitmapHeaderExt {
uint64_t bitmap_directory_offset;
} QEMU_PACKED Qcow2BitmapHeaderExt;
+#define QCOW2_MAX_THREADS 4
+
typedef struct BDRVQcow2State {
int cluster_bits;
int cluster_size;
@@ -741,5 +743,11 @@ qcow2_co_compress(BlockDriverState *bs, void *dest, size_t dest_size,
ssize_t coroutine_fn
qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
const void *src, size_t src_size);
+int coroutine_fn
+qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len);
+int coroutine_fn
+qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len);
#endif
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index c4965479f6..e6624c6e4e 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -471,13 +471,12 @@ static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs,
{
if (bytes && bs->encrypted) {
BDRVQcow2State *s = bs->opaque;
- int64_t offset = (s->crypt_physical_offset ?
- (cluster_offset + offset_in_cluster) :
- (src_cluster_offset + offset_in_cluster));
assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0);
assert((bytes & ~BDRV_SECTOR_MASK) == 0);
assert(s->crypto);
- if (qcrypto_block_encrypt(s->crypto, offset, buffer, bytes, NULL) < 0) {
+ if (qcow2_co_encrypt(bs, cluster_offset,
+ src_cluster_offset + offset_in_cluster,
+ buffer, bytes) < 0) {
return false;
}
}
diff --git a/block/qcow2-threads.c b/block/qcow2-threads.c
index 650aa2ed19..3b1e63fe41 100644
--- a/block/qcow2-threads.c
+++ b/block/qcow2-threads.c
@@ -30,8 +30,7 @@
#include "qcow2.h"
#include "block/thread-pool.h"
-
-#define QCOW2_MAX_THREADS 4
+#include "crypto.h"
static int coroutine_fn
qcow2_co_process(BlockDriverState *bs, ThreadPoolFunc *func, void *arg)
@@ -205,3 +204,65 @@ qcow2_co_decompress(BlockDriverState *bs, void *dest, size_t dest_size,
return qcow2_co_do_compress(bs, dest, dest_size, src, src_size,
qcow2_decompress);
}
+
+
+/*
+ * Cryptography
+ */
+
+/*
+ * Qcow2EncDecFunc: common prototype of qcrypto_block_encrypt() and
+ * qcrypto_block_decrypt() functions.
+ */
+typedef int (*Qcow2EncDecFunc)(QCryptoBlock *block, uint64_t offset,
+ uint8_t *buf, size_t len, Error **errp);
+
+typedef struct Qcow2EncDecData {
+ QCryptoBlock *block;
+ uint64_t offset;
+ uint8_t *buf;
+ size_t len;
+
+ Qcow2EncDecFunc func;
+} Qcow2EncDecData;
+
+static int qcow2_encdec_pool_func(void *opaque)
+{
+ Qcow2EncDecData *data = opaque;
+
+ return data->func(data->block, data->offset, data->buf, data->len, NULL);
+}
+
+static int coroutine_fn
+qcow2_co_encdec(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len, Qcow2EncDecFunc func)
+{
+ BDRVQcow2State *s = bs->opaque;
+ Qcow2EncDecData arg = {
+ .block = s->crypto,
+ .offset = s->crypt_physical_offset ?
+ file_cluster_offset + offset_into_cluster(s, offset) :
+ offset,
+ .buf = buf,
+ .len = len,
+ .func = func,
+ };
+
+ return qcow2_co_process(bs, qcow2_encdec_pool_func, &arg);
+}
+
+int coroutine_fn
+qcow2_co_encrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len)
+{
+ return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
+ qcrypto_block_encrypt);
+}
+
+int coroutine_fn
+qcow2_co_decrypt(BlockDriverState *bs, uint64_t file_cluster_offset,
+ uint64_t offset, void *buf, size_t len)
+{
+ return qcow2_co_encdec(bs, file_cluster_offset, offset, buf, len,
+ qcrypto_block_decrypt);
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index cba2328005..dee3b8cca3 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -297,7 +297,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
}
s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
qcow2_crypto_hdr_read_func,
- bs, cflags, 1, errp);
+ bs, cflags, QCOW2_MAX_THREADS, errp);
if (!s->crypto) {
return -EINVAL;
}
@@ -1539,7 +1539,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
}
s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.",
- NULL, NULL, cflags, 1, errp);
+ NULL, NULL, cflags,
+ QCOW2_MAX_THREADS, errp);
if (!s->crypto) {
ret = -EINVAL;
goto fail;
@@ -2062,13 +2063,8 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
assert(s->crypto);
assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);
assert((cur_bytes & (BDRV_SECTOR_SIZE - 1)) == 0);
- if (qcrypto_block_decrypt(s->crypto,
- (s->crypt_physical_offset ?
- cluster_offset + offset_in_cluster :
- offset),
- cluster_data,
- cur_bytes,
- NULL) < 0) {
+ if (qcow2_co_decrypt(bs, cluster_offset, offset,
+ cluster_data, cur_bytes) < 0) {
ret = -EIO;
goto fail;
}
@@ -2202,12 +2198,8 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);
- if (qcrypto_block_encrypt(s->crypto,
- (s->crypt_physical_offset ?
- cluster_offset + offset_in_cluster :
- offset),
- cluster_data,
- cur_bytes, NULL) < 0) {
+ if (qcow2_co_encrypt(bs, cluster_offset, offset,
+ cluster_data, cur_bytes) < 0) {
ret = -EIO;
goto out_unlocked;
}
--
2.18.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v6 6/8] qcow2: qcow2_co_preadv: improve locking
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 6/8] qcow2: qcow2_co_preadv: improve locking Vladimir Sementsov-Ogievskiy
@ 2019-05-09 12:11 ` Alberto Garcia
0 siblings, 0 replies; 12+ messages in thread
From: Alberto Garcia @ 2019-05-09 12:11 UTC (permalink / raw)
To: Vladimir Sementsov-Ogievskiy, qemu-devel, qemu-block
Cc: kwolf, vsementsov, mreitz, den, pbonzini
On Mon 06 May 2019 04:27:39 PM CEST, Vladimir Sementsov-Ogievskiy wrote:
> Background: decryption will be done in threads, to take benefit of it,
> we should move it out of the lock first.
>
> But let's go further: it turns out, that only
> qcow2_get_cluster_offset() needs locking, so reduce locking to it.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Berto
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
` (7 preceding siblings ...)
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 8/8] qcow2: do encryption in threads Vladimir Sementsov-Ogievskiy
@ 2019-05-09 14:56 ` Max Reitz
2019-05-13 9:56 ` Vladimir Sementsov-Ogievskiy
8 siblings, 1 reply; 12+ messages in thread
From: Max Reitz @ 2019-05-09 14:56 UTC (permalink / raw)
To: Vladimir Sementsov-Ogievskiy, qemu-devel, qemu-block
Cc: kwolf, pbonzini, berto, den
[-- Attachment #1: Type: text/plain, Size: 1609 bytes --]
On 06.05.19 16:27, Vladimir Sementsov-Ogievskiy wrote:
> v6:
> - Rebase on master, so 02 changed to reflect changes in
> qcow2_compress(), keep r-b.
> - Rewrite 06 to even simpler locking [Max], drop r-b
> Drop following
> "qcow2: qcow2_co_preadv: skip using hd_qiov when possible", I'll do
> it in my other coming soon series, and it is actually unrelated to
> current.
> - Drop controversial perf test, hope I'll return to this topic, but not
> in context of these series.
> - Add Max's r-b's to all here, except 06
>
> Vladimir Sementsov-Ogievskiy (8):
> qcow2.h: add missing include
> qcow2: add separate file for threaded data processing functions
> qcow2-threads: use thread_pool_submit_co
> qcow2-threads: qcow2_co_do_compress: protect queuing by mutex
> qcow2-threads: split out generic path
> qcow2: qcow2_co_preadv: improve locking
> qcow2: bdrv_co_pwritev: move encryption code out of the lock
> qcow2: do encryption in threads
>
> block/qcow2.h | 20 ++-
> block/qcow2-bitmap.c | 1 -
> block/qcow2-cache.c | 1 -
> block/qcow2-cluster.c | 8 +-
> block/qcow2-refcount.c | 1 -
> block/qcow2-snapshot.c | 1 -
> block/qcow2-threads.c | 268 +++++++++++++++++++++++++++++++++++++++++
> block/qcow2.c | 241 +++++-------------------------------
> block/Makefile.objs | 2 +-
> 9 files changed, 321 insertions(+), 222 deletions(-)
> create mode 100644 block/qcow2-threads.c
Thanks, applied to my block branch:
https://git.xanclic.moe/XanClic/qemu/commits/branch/block
Max
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads
2019-05-09 14:56 ` [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Max Reitz
@ 2019-05-13 9:56 ` Vladimir Sementsov-Ogievskiy
0 siblings, 0 replies; 12+ messages in thread
From: Vladimir Sementsov-Ogievskiy @ 2019-05-13 9:56 UTC (permalink / raw)
To: Max Reitz, qemu-devel@nongnu.org, qemu-block@nongnu.org
Cc: kwolf@redhat.com, pbonzini@redhat.com, berto@igalia.com,
berrange@redhat.com, Denis Lunev
09.05.2019 17:56, Max Reitz wrote:
> On 06.05.19 16:27, Vladimir Sementsov-Ogievskiy wrote:
>> v6:
>> - Rebase on master, so 02 changed to reflect changes in
>> qcow2_compress(), keep r-b.
>> - Rewrite 06 to even simpler locking [Max], drop r-b
>> Drop following
>> "qcow2: qcow2_co_preadv: skip using hd_qiov when possible", I'll do
>> it in my other coming soon series, and it is actually unrelated to
>> current.
>> - Drop controversial perf test, hope I'll return to this topic, but not
>> in context of these series.
>> - Add Max's r-b's to all here, except 06
>>
>> Vladimir Sementsov-Ogievskiy (8):
>> qcow2.h: add missing include
>> qcow2: add separate file for threaded data processing functions
>> qcow2-threads: use thread_pool_submit_co
>> qcow2-threads: qcow2_co_do_compress: protect queuing by mutex
>> qcow2-threads: split out generic path
>> qcow2: qcow2_co_preadv: improve locking
>> qcow2: bdrv_co_pwritev: move encryption code out of the lock
>> qcow2: do encryption in threads
>>
>> block/qcow2.h | 20 ++-
>> block/qcow2-bitmap.c | 1 -
>> block/qcow2-cache.c | 1 -
>> block/qcow2-cluster.c | 8 +-
>> block/qcow2-refcount.c | 1 -
>> block/qcow2-snapshot.c | 1 -
>> block/qcow2-threads.c | 268 +++++++++++++++++++++++++++++++++++++++++
>> block/qcow2.c | 241 +++++-------------------------------
>> block/Makefile.objs | 2 +-
>> 9 files changed, 321 insertions(+), 222 deletions(-)
>> create mode 100644 block/qcow2-threads.c
>
> Thanks, applied to my block branch:
>
> https://git.xanclic.moe/XanClic/qemu/commits/branch/block
>
Thank you!!
--
Best regards,
Vladimir
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2019-05-13 9:57 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-05-06 14:27 [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 1/8] qcow2.h: add missing include Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 2/8] qcow2: add separate file for threaded data processing functions Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 3/8] qcow2-threads: use thread_pool_submit_co Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 4/8] qcow2-threads: qcow2_co_do_compress: protect queuing by mutex Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 5/8] qcow2-threads: split out generic path Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 6/8] qcow2: qcow2_co_preadv: improve locking Vladimir Sementsov-Ogievskiy
2019-05-09 12:11 ` Alberto Garcia
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 7/8] qcow2: bdrv_co_pwritev: move encryption code out of the lock Vladimir Sementsov-Ogievskiy
2019-05-06 14:27 ` [Qemu-devel] [PATCH v6 8/8] qcow2: do encryption in threads Vladimir Sementsov-Ogievskiy
2019-05-09 14:56 ` [Qemu-devel] [PATCH v6 0/8] qcow2: encryption threads Max Reitz
2019-05-13 9:56 ` Vladimir Sementsov-Ogievskiy
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).