All of lore.kernel.org
 help / color / mirror / Atom feed
From: Emanuele Giuseppe Esposito <eesposit@redhat.com>
To: qemu-block@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Emanuele Giuseppe Esposito <eesposit@redhat.com>,
	Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	qemu-devel@nongnu.org, Max Reitz <mreitz@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>, John Snow <jsnow@redhat.com>
Subject: [RFC PATCH 2/3] block-copy: add a CoMutex to the BlockCopyTask list
Date: Tue, 20 Apr 2021 12:04:15 +0200	[thread overview]
Message-ID: <20210420100416.30713-3-eesposit@redhat.com> (raw)
In-Reply-To: <20210420100416.30713-1-eesposit@redhat.com>

Because the list of tasks is only modified by coroutine
functions, add a CoMutex in order to protect the list of tasks.

Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
 block/block-copy.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/block/block-copy.c b/block/block-copy.c
index 03df50a354..e785ac57e0 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -65,7 +65,9 @@ typedef struct BlockCopyTask {
     BlockCopyState *s;
     BlockCopyCallState *call_state;
 
-    /* State */
+    /* State. These fields are protected by the tasks_lock
+     * in BlockCopyState
+     */
     int64_t offset;
     int64_t bytes;
     bool zeroes;
@@ -95,6 +97,8 @@ typedef struct BlockCopyState {
     bool use_copy_range;
     int64_t copy_size;
     uint64_t len;
+
+    CoMutex tasks_lock;
     QLIST_HEAD(, BlockCopyTask) tasks; /* All tasks from all block-copy calls */
     QLIST_HEAD(, BlockCopyCallState) calls;
 
@@ -124,6 +128,7 @@ typedef struct BlockCopyState {
     RateLimit rate_limit;
 } BlockCopyState;
 
+/* Called with lock held */
 static BlockCopyTask *find_conflicting_task(BlockCopyState *s,
                                             int64_t offset, int64_t bytes)
 {
@@ -145,13 +150,19 @@ static BlockCopyTask *find_conflicting_task(BlockCopyState *s,
 static bool coroutine_fn block_copy_wait_one(BlockCopyState *s, int64_t offset,
                                              int64_t bytes)
 {
-    BlockCopyTask *task = find_conflicting_task(s, offset, bytes);
+    BlockCopyTask *task;
+
+    qemu_co_mutex_lock(&s->tasks_lock);
+    task = find_conflicting_task(s, offset, bytes);
 
     if (!task) {
+        qemu_co_mutex_unlock(&s->tasks_lock);
         return false;
     }
 
-    qemu_co_queue_wait(&task->wait_queue, NULL);
+    qemu_co_queue_wait(&task->wait_queue, &s->tasks_lock);
+
+    qemu_co_mutex_unlock(&s->tasks_lock);
 
     return true;
 }
@@ -178,7 +189,9 @@ static BlockCopyTask *coroutine_fn block_copy_task_create(BlockCopyState *s,
     bytes = QEMU_ALIGN_UP(bytes, s->cluster_size);
 
     /* region is dirty, so no existent tasks possible in it */
+    qemu_co_mutex_lock(&s->tasks_lock);
     assert(!find_conflicting_task(s, offset, bytes));
+    qemu_co_mutex_unlock(&s->tasks_lock);
 
     bdrv_reset_dirty_bitmap(s->copy_bitmap, offset, bytes);
     s->in_flight_bytes += bytes;
@@ -192,8 +205,9 @@ static BlockCopyTask *coroutine_fn block_copy_task_create(BlockCopyState *s,
         .bytes = bytes,
     };
     qemu_co_queue_init(&task->wait_queue);
+    qemu_co_mutex_lock(&s->tasks_lock);
     QLIST_INSERT_HEAD(&s->tasks, task, list);
-
+    qemu_co_mutex_unlock(&s->tasks_lock);
     return task;
 }
 
@@ -297,6 +311,7 @@ BlockCopyState *block_copy_state_new(BdrvChild *source, BdrvChild *target,
     }
 
     QLIST_INIT(&s->tasks);
+    qemu_co_mutex_init(&s->tasks_lock);
     QLIST_INIT(&s->calls);
 
     return s;
-- 
2.30.2



  parent reply	other threads:[~2021-04-20 10:07 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-20 10:04 [RFC PATCH 0/3] block-copy: lock tasks and calls list Emanuele Giuseppe Esposito
2021-04-20 10:04 ` [RFC PATCH 1/3] block-copy: improve documentation for BlockCopyTask type and functions Emanuele Giuseppe Esposito
2021-04-20 12:03   ` Vladimir Sementsov-Ogievskiy
2021-04-20 12:51     ` Emanuele Giuseppe Esposito
2021-04-20 13:11       ` Vladimir Sementsov-Ogievskiy
2021-04-20 10:04 ` Emanuele Giuseppe Esposito [this message]
2021-04-20 10:04 ` [RFC PATCH 3/3] block-copy: add CoMutex lock for BlockCopyCallState list Emanuele Giuseppe Esposito
2021-04-20 13:12 ` [RFC PATCH 0/3] block-copy: lock tasks and calls list Vladimir Sementsov-Ogievskiy
2021-04-21  8:38   ` Paolo Bonzini
2021-04-21  8:53     ` Vladimir Sementsov-Ogievskiy
2021-04-21 12:13       ` Paolo Bonzini

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=20210420100416.30713-3-eesposit@redhat.com \
    --to=eesposit@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.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: 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.