qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/2] crpyto: support encryt and decrypt parallelly using thread p


From: tugy
Subject: [PATCH 1/2] crpyto: support encryt and decrypt parallelly using thread pool
Date: Thu, 28 Nov 2024 18:51:21 +0800

From: Guoyi Tu <tugy@chinatelecom.cn>

Currently, disk I/O encryption and decryption operations are performed 
sequentially
in the main thread or IOthread. When the number of I/O requests increases,
this becomes a performance bottleneck.

To address this issue, this patch using the thread pool to perform I/O 
encryption
and decryption in parallel to improving overall efficiency.

Signed-off-by: Guoyi Tu <tugy@chinatelecom.cn>
---
 block/crypto.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 97 insertions(+), 6 deletions(-)

diff --git a/block/crypto.c b/block/crypto.c
index 80b2dba17a..c085f331ce 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -22,6 +22,7 @@
 
 #include "block/block_int.h"
 #include "block/qdict.h"
+#include "block/thread-pool.h"
 #include "sysemu/block-backend.h"
 #include "crypto/block.h"
 #include "qapi/opts-visitor.h"
@@ -40,6 +41,7 @@ struct BlockCrypto {
     QCryptoBlock *block;
     bool updating_keys;
     BdrvChild *header;  /* Reference to the detached LUKS header */
+    bool encrypt_in_parallel;
 };
 
 
@@ -460,6 +462,94 @@ static int block_crypto_reopen_prepare(BDRVReopenState 
*state,
     return 0;
 }
 
+
+typedef struct CryptoAIOData {
+    QCryptoBlock *block;
+    uint64_t offset;
+    uint8_t *buf;
+    size_t len;
+    bool encrypt;
+    Error **errp;
+} CryptoAIOData;
+
+
+static int handle_aiocb_encdec(void *opaque)
+{
+    CryptoAIOData *aiocb = opaque;
+
+    if (aiocb->encrypt) {
+        if (qcrypto_block_encrypt(aiocb->block, aiocb->offset,
+                                  aiocb->buf, aiocb->len, aiocb->errp) < 0) {
+            return -EIO;
+        }
+    } else {
+        if (qcrypto_block_decrypt(aiocb->block, aiocb->offset,
+                                  aiocb->buf, aiocb->len, aiocb->errp) < 0) {
+            return -EIO;
+        }
+    }
+
+    return 0;
+}
+
+
+static int coroutine_fn block_crypto_submit_co(BlockDriverState *bs, uint64_t 
offset,
+                                               uint8_t *buf, size_t len, bool 
encrypt,
+                                               Error **errp)
+{
+    BlockCrypto *crypto = bs->opaque;
+    CryptoAIOData acb;
+
+    acb = (CryptoAIOData) {
+        .block = crypto->block,
+        .offset = offset,
+        .buf = buf,
+        .len = len,
+        .encrypt = encrypt,
+        .errp = errp,
+    };
+    return thread_pool_submit_co(handle_aiocb_encdec, &acb);
+}
+
+
+static int coroutine_fn GRAPH_RDLOCK
+block_crypto_encrypt(BlockDriverState *bs, uint64_t offset,
+                     uint8_t *buf, size_t len, Error **errp)
+{
+    BlockCrypto *crypto = bs->opaque;
+    int ret = 0;
+
+    if (crypto->encrypt_in_parallel) {
+        ret = block_crypto_submit_co(bs, offset, buf, len, true, errp);
+    } else {
+        if (qcrypto_block_encrypt(crypto->block, offset, buf, len, errp) < 0) {
+            ret = -EIO;
+        }
+    }
+
+    return ret;
+}
+
+
+static int coroutine_fn GRAPH_RDLOCK
+block_crypto_decrypt(BlockDriverState *bs, uint64_t offset,
+                     uint8_t *buf, size_t len, Error **errp)
+{
+    BlockCrypto *crypto = bs->opaque;
+    int ret = 0;
+
+    if (crypto->encrypt_in_parallel) {
+        ret = block_crypto_submit_co(bs, offset, buf, len, false, errp);
+    } else {
+        if (qcrypto_block_decrypt(crypto->block, offset, buf, len, errp) < 0) {
+            ret = -EIO;
+        }
+    }
+
+    return ret;
+}
+
+
 /*
  * 1 MB bounce buffer gives good performance / memory tradeoff
  * when using cache=none|directsync.
@@ -508,9 +598,10 @@ block_crypto_co_preadv(BlockDriverState *bs, int64_t 
offset, int64_t bytes,
             goto cleanup;
         }
 
-        if (qcrypto_block_decrypt(crypto->block, offset + bytes_done,
-                                  cipher_data, cur_bytes, NULL) < 0) {
-            ret = -EIO;
+        ret = block_crypto_decrypt(bs, offset + bytes_done,
+                                   cipher_data, cur_bytes, NULL);
+
+        if (ret < 0) {
             goto cleanup;
         }
 
@@ -565,9 +656,9 @@ block_crypto_co_pwritev(BlockDriverState *bs, int64_t 
offset, int64_t bytes,
 
         qemu_iovec_to_buf(qiov, bytes_done, cipher_data, cur_bytes);
 
-        if (qcrypto_block_encrypt(crypto->block, offset + bytes_done,
-                                  cipher_data, cur_bytes, NULL) < 0) {
-            ret = -EIO;
+        ret = block_crypto_encrypt(bs, offset + bytes_done,
+                                   cipher_data, cur_bytes, NULL);
+        if (ret < 0) {
             goto cleanup;
         }
 
-- 
2.17.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]