All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Peter Maydell <peter.maydell@linaro.org>,
	qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>
Subject: [PULL 02/36] block: introduce aio task pool
Date: Thu, 10 Oct 2019 13:42:26 +0200	[thread overview]
Message-ID: <20191010114300.7746-3-mreitz@redhat.com> (raw)
In-Reply-To: <20191010114300.7746-1-mreitz@redhat.com>

From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>

Common interface for aio task loops. To be used for improving
performance of synchronous io loops in qcow2, block-stream,
copy-on-read, and may be other places.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-id: 20190916175324.18478-3-vsementsov@virtuozzo.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block/Makefile.objs      |   2 +
 include/block/aio_task.h |  54 +++++++++++++++++
 block/aio_task.c         | 124 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 180 insertions(+)
 create mode 100644 include/block/aio_task.h
 create mode 100644 block/aio_task.c

diff --git a/block/Makefile.objs b/block/Makefile.objs
index 35f3bca4d9..c2eb8c8769 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -40,6 +40,8 @@ block-obj-y += throttle.o copy-on-read.o
 
 block-obj-y += crypto.o
 
+block-obj-y += aio_task.o
+
 common-obj-y += stream.o
 
 nfs.o-libs         := $(LIBNFS_LIBS)
diff --git a/include/block/aio_task.h b/include/block/aio_task.h
new file mode 100644
index 0000000000..50bc1e1817
--- /dev/null
+++ b/include/block/aio_task.h
@@ -0,0 +1,54 @@
+/*
+ * Aio tasks loops
+ *
+ * Copyright (c) 2019 Virtuozzo International GmbH.
+ *
+ * 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.
+ */
+
+#ifndef BLOCK_AIO_TASK_H
+#define BLOCK_AIO_TASK_H
+
+#include "qemu/coroutine.h"
+
+typedef struct AioTaskPool AioTaskPool;
+typedef struct AioTask AioTask;
+typedef int coroutine_fn (*AioTaskFunc)(AioTask *task);
+struct AioTask {
+    AioTaskPool *pool;
+    AioTaskFunc func;
+    int ret;
+};
+
+AioTaskPool *coroutine_fn aio_task_pool_new(int max_busy_tasks);
+void aio_task_pool_free(AioTaskPool *);
+
+/* error code of failed task or 0 if all is OK */
+int aio_task_pool_status(AioTaskPool *pool);
+
+bool aio_task_pool_empty(AioTaskPool *pool);
+
+/* User provides filled @task, however task->pool will be set automatically */
+void coroutine_fn aio_task_pool_start_task(AioTaskPool *pool, AioTask *task);
+
+void coroutine_fn aio_task_pool_wait_slot(AioTaskPool *pool);
+void coroutine_fn aio_task_pool_wait_one(AioTaskPool *pool);
+void coroutine_fn aio_task_pool_wait_all(AioTaskPool *pool);
+
+#endif /* BLOCK_AIO_TASK_H */
diff --git a/block/aio_task.c b/block/aio_task.c
new file mode 100644
index 0000000000..88989fa248
--- /dev/null
+++ b/block/aio_task.c
@@ -0,0 +1,124 @@
+/*
+ * Aio tasks loops
+ *
+ * Copyright (c) 2019 Virtuozzo International GmbH.
+ *
+ * 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"
+#include "block/aio.h"
+#include "block/aio_task.h"
+
+struct AioTaskPool {
+    Coroutine *main_co;
+    int status;
+    int max_busy_tasks;
+    int busy_tasks;
+    bool waiting;
+};
+
+static void coroutine_fn aio_task_co(void *opaque)
+{
+    AioTask *task = opaque;
+    AioTaskPool *pool = task->pool;
+
+    assert(pool->busy_tasks < pool->max_busy_tasks);
+    pool->busy_tasks++;
+
+    task->ret = task->func(task);
+
+    pool->busy_tasks--;
+
+    if (task->ret < 0 && pool->status == 0) {
+        pool->status = task->ret;
+    }
+
+    g_free(task);
+
+    if (pool->waiting) {
+        pool->waiting = false;
+        aio_co_wake(pool->main_co);
+    }
+}
+
+void coroutine_fn aio_task_pool_wait_one(AioTaskPool *pool)
+{
+    assert(pool->busy_tasks > 0);
+    assert(qemu_coroutine_self() == pool->main_co);
+
+    pool->waiting = true;
+    qemu_coroutine_yield();
+
+    assert(!pool->waiting);
+    assert(pool->busy_tasks < pool->max_busy_tasks);
+}
+
+void coroutine_fn aio_task_pool_wait_slot(AioTaskPool *pool)
+{
+    if (pool->busy_tasks < pool->max_busy_tasks) {
+        return;
+    }
+
+    aio_task_pool_wait_one(pool);
+}
+
+void coroutine_fn aio_task_pool_wait_all(AioTaskPool *pool)
+{
+    while (pool->busy_tasks > 0) {
+        aio_task_pool_wait_one(pool);
+    }
+}
+
+void coroutine_fn aio_task_pool_start_task(AioTaskPool *pool, AioTask *task)
+{
+    aio_task_pool_wait_slot(pool);
+
+    task->pool = pool;
+    qemu_coroutine_enter(qemu_coroutine_create(aio_task_co, task));
+}
+
+AioTaskPool *coroutine_fn aio_task_pool_new(int max_busy_tasks)
+{
+    AioTaskPool *pool = g_new0(AioTaskPool, 1);
+
+    pool->main_co = qemu_coroutine_self();
+    pool->max_busy_tasks = max_busy_tasks;
+
+    return pool;
+}
+
+void aio_task_pool_free(AioTaskPool *pool)
+{
+    g_free(pool);
+}
+
+int aio_task_pool_status(AioTaskPool *pool)
+{
+    if (!pool) {
+        return 0; /* Sugar for lazy allocation of aio pool */
+    }
+
+    return pool->status;
+}
+
+bool aio_task_pool_empty(AioTaskPool *pool)
+{
+    return pool->busy_tasks == 0;
+}
-- 
2.21.0



  parent reply	other threads:[~2019-10-10 12:12 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-10 11:42 [PULL 00/36] Block patches Max Reitz
2019-10-10 11:42 ` [PULL 01/36] qemu-iotests: ignore leaks on failure paths in 026 Max Reitz
2019-10-10 11:42 ` Max Reitz [this message]
2019-10-10 11:42 ` [PULL 03/36] block/qcow2: refactor qcow2_co_preadv_part Max Reitz
2019-10-10 11:42 ` [PULL 04/36] block/qcow2: refactor qcow2_co_pwritev_part Max Reitz
2019-10-10 11:42 ` [PULL 05/36] block/qcow2: introduce parallel subrequest handling in read and write Max Reitz
2019-10-10 11:42 ` [PULL 06/36] block/backup: fix max_transfer handling for copy_range Max Reitz
2019-10-10 11:42 ` [PULL 07/36] block/backup: fix backup_cow_with_offload for last cluster Max Reitz
2019-10-10 11:42 ` [PULL 08/36] block/backup: split shareable copying part from backup_do_cow Max Reitz
2019-10-10 11:42 ` [PULL 09/36] block/backup: improve comment about image fleecing Max Reitz
2019-10-10 11:42 ` [PULL 10/36] block/backup: introduce BlockCopyState Max Reitz
2019-10-10 11:42 ` [PULL 11/36] block/backup: fix block-comment style Max Reitz
2019-10-10 11:42 ` [PULL 12/36] block: move block_copy from block/backup.c to separate file Max Reitz
2019-10-10 11:42 ` [PULL 13/36] block: teach bdrv_debug_breakpoint skip filters with backing Max Reitz
2019-10-10 11:42 ` [PULL 14/36] iotests: prepare 124 and 257 bitmap querying for backup-top filter Max Reitz
2019-10-10 11:42 ` [PULL 15/36] iotests: 257: drop unused Drive.device field Max Reitz
2019-10-10 11:42 ` [PULL 16/36] iotests: 257: drop device_add Max Reitz
2019-10-10 11:42 ` [PULL 17/36] qapi: group BlockDeviceStats fields Max Reitz
2019-10-10 11:42 ` [PULL 18/36] qapi: add unmap to BlockDeviceStats Max Reitz
2019-10-10 11:42 ` [PULL 19/36] block: add empty account cookie type Max Reitz
2019-10-10 11:42 ` [PULL 20/36] ide: account UNMAP (TRIM) operations Max Reitz
2019-10-10 11:42 ` [PULL 21/36] scsi: store unmap offset and nb_sectors in request struct Max Reitz
2019-10-10 11:42 ` [PULL 22/36] scsi: move unmap error checking to the complete callback Max Reitz
2019-10-10 11:42 ` [PULL 23/36] scsi: account unmap operations Max Reitz
2019-10-10 11:42 ` [PULL 24/36] file-posix: account discard operations Max Reitz
2019-10-10 11:42 ` [PULL 25/36] qapi: query-blockstat: add driver specific file-posix stats Max Reitz
2019-10-10 11:42 ` [PULL 26/36] iotests: Fix 125 for growth_mode = metadata Max Reitz
2019-10-10 11:42 ` [PULL 27/36] iotests: Disable 125 on broken XFS versions Max Reitz
2019-10-10 11:42 ` [PULL 28/36] iotests: Use stat -c %b in 125 Max Reitz
2019-10-10 11:42 ` [PULL 29/36] block/backup: move in-flight requests handling from backup to block-copy Max Reitz
2019-10-10 11:42 ` [PULL 30/36] block/backup: move write_flags calculation inside backup_job_create Max Reitz
2019-10-10 11:42 ` [PULL 31/36] block/block-copy: split block_copy_set_callbacks function Max Reitz
2019-10-10 11:42 ` [PULL 32/36] block: introduce backup-top filter driver Max Reitz
2019-10-10 11:42 ` [PULL 33/36] block/backup: use backup-top instead of write notifiers Max Reitz
2019-10-17 12:04   ` Peter Maydell
2019-10-17 13:40     ` Vladimir Sementsov-Ogievskiy
2019-10-10 11:42 ` [PULL 34/36] nbd: add empty .bdrv_reopen_prepare Max Reitz
2019-10-10 11:42 ` [PULL 35/36] tests: fix I/O test for hosts defaulting to LUKSv2 Max Reitz
2019-10-10 11:43 ` [PULL 36/36] iotests/162: Fix for newer Linux 5.3+ Max Reitz
2019-10-14 12:34 ` [PULL 00/36] Block patches Peter Maydell

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=20191010114300.7746-3-mreitz@redhat.com \
    --to=mreitz@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.