[RFC,16/24] block/block-copy: add max_chunk and max_workers paramters
diff mbox series

Message ID 20191115141444.24155-17-vsementsov@virtuozzo.com
State New
Headers show
Series
  • backup performance: block_status + async
Related show

Commit Message

Vladimir Sementsov-Ogievskiy Nov. 15, 2019, 2:14 p.m. UTC
They will be used for backup.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 include/block/block-copy.h | 5 +++++
 block/block-copy.c         | 9 +++++++--
 2 files changed, 12 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/include/block/block-copy.h b/include/block/block-copy.h
index 407de7e520..8fc27156b3 100644
--- a/include/block/block-copy.h
+++ b/include/block/block-copy.h
@@ -47,6 +47,11 @@  int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
 /*
  * Run block-copy in a coroutine, return state pointer. If finished early
  * returns NULL (@cb is called anyway).
+ *
+ * @max_workers means maximum of parallel coroutines to execute sub-requests,
+ * must be > 0.
+ *
+ * @max_chunk means maximum length for one IO operation. Zero means unlimited.
  */
 BlockCopyCallState *block_copy_async(BlockCopyState *s,
                                      int64_t offset, int64_t bytes,
diff --git a/block/block-copy.c b/block/block-copy.c
index 0b41afd30d..f28f3b8b6c 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -32,6 +32,8 @@  typedef struct BlockCopyCallState {
     BlockCopyState *s;
     int64_t offset;
     int64_t bytes;
+    int max_workers;
+    int64_t max_chunk;
     BlockCopyAsyncCallbackFunc cb;
 
     /* State */
@@ -393,7 +395,7 @@  static BlockCopyTask *block_copy_task_create(BlockCopyState *s,
 
     assert(bdrv_dirty_bitmap_get(s->copy_bitmap, offset));
 
-    bytes = MIN(bytes, s->copy_size);
+    bytes = MIN(bytes, MIN_NON_ZERO(s->copy_size, call_state->max_chunk));
     next_zero = bdrv_dirty_bitmap_next_zero(s->copy_bitmap, offset, bytes);
     if (next_zero >= 0) {
         assert(next_zero > offset); /* offset is dirty */
@@ -578,7 +580,7 @@  block_copy_dirty_clusters(BlockCopyCallState *call_state)
         co_get_from_shres(s->mem, task->bytes);
 
         if (!aio && task->bytes != bytes) {
-            aio = aio_task_pool_new(BLOCK_COPY_MAX_WORKERS);
+            aio = aio_task_pool_new(call_state->max_workers);
         }
 
         offset += task->bytes;
@@ -655,6 +657,7 @@  int coroutine_fn block_copy(BlockCopyState *s, int64_t start, uint64_t bytes,
         .s = s,
         .offset = start,
         .bytes = bytes,
+        .max_workers = BLOCK_COPY_MAX_WORKERS,
     };
 
     int ret = block_copy_common(&call_state);
@@ -686,6 +689,8 @@  BlockCopyCallState *block_copy_async(BlockCopyState *s,
         .offset = offset,
         .bytes = bytes,
         .cb = cb,
+        .max_workers = max_workers ?: BLOCK_COPY_MAX_WORKERS,
+        .max_chunk = max_chunk,
     };
 
     qemu_coroutine_enter(co);