qemu-block
[Top][All Lists]
Advanced

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

[Qemu-block] [PATCH 05/11] block-backup: add reqs_lock


From: Paolo Bonzini
Subject: [Qemu-block] [PATCH 05/11] block-backup: add reqs_lock
Date: Thu, 6 Jul 2017 18:38:22 +0200

Protect the list of inflight reqs and the CoQueues for dependent
requests.

Signed-off-by: Paolo Bonzini <address@hidden>
---
 block/backup.c               | 20 +++++++++++++++-----
 block/replication.c          |  2 +-
 include/block/block_backup.h |  2 +-
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/block/backup.c b/block/backup.c
index 9214ffcc58..0ed7726fe6 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -45,6 +45,7 @@ typedef struct BackupBlockJob {
     bool compress;
     NotifierWithReturn before_write;
     QLIST_HEAD(, CowRequest) inflight_reqs;
+    CoMutex reqs_lock;
 } BackupBlockJob;
 
 /* Size of a cluster in sectors, instead of bytes. */
@@ -61,16 +62,18 @@ static void coroutine_fn 
wait_for_overlapping_requests(BackupBlockJob *job,
     CowRequest *req;
     bool retry;
 
+    qemu_co_mutex_lock(&job->reqs_lock);
     do {
         retry = false;
         QLIST_FOREACH(req, &job->inflight_reqs, list) {
             if (end > req->start && start < req->end) {
-                qemu_co_queue_wait(&req->wait_queue, NULL);
+                qemu_co_queue_wait(&req->wait_queue, &job->reqs_lock);
                 retry = true;
                 break;
             }
         }
     } while (retry);
+    qemu_co_mutex_unlock(&job->reqs_lock);
 }
 
 /* Keep track of an in-flight request */
@@ -80,14 +83,18 @@ static void cow_request_begin(CowRequest *req, 
BackupBlockJob *job,
     req->start = start;
     req->end = end;
     qemu_co_queue_init(&req->wait_queue);
+    qemu_co_mutex_lock(&job->reqs_lock);
     QLIST_INSERT_HEAD(&job->inflight_reqs, req, list);
+    qemu_co_mutex_unlock(&job->reqs_lock);
 }
 
 /* Forget about a completed request */
-static void cow_request_end(CowRequest *req)
+static void cow_request_end(CowRequest *req, BackupBlockJob *job)
 {
+    qemu_co_mutex_lock(&job->reqs_lock);
     QLIST_REMOVE(req, list);
     qemu_co_queue_restart_all(&req->wait_queue);
+    qemu_co_mutex_unlock(&job->reqs_lock);
 }
 
 static int coroutine_fn backup_do_cow(BackupBlockJob *job,
@@ -175,7 +182,7 @@ out:
         qemu_vfree(bounce_buffer);
     }
 
-    cow_request_end(&cow_request);
+    cow_request_end(&cow_request, job);
 
     trace_backup_do_cow_return(job, sector_num, nb_sectors, ret);
 
@@ -311,9 +318,11 @@ void backup_cow_request_begin(CowRequest *req, BlockJob 
*job,
     cow_request_begin(req, backup_job, start, end);
 }
 
-void backup_cow_request_end(CowRequest *req)
+void backup_cow_request_end(CowRequest *req, BlockJob *job)
 {
-    cow_request_end(req);
+    BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
+
+    cow_request_end(req, backup_job);
 }
 
 static void backup_drain(BlockJob *job)
@@ -653,6 +662,7 @@ BlockJob *backup_job_create(const char *job_id, 
BlockDriverState *bs,
         goto error;
     }
 
+    qemu_co_mutex_init(&job->reqs_lock);
     job->on_source_error = on_source_error;
     job->on_target_error = on_target_error;
     job->sync_mode = sync_mode;
diff --git a/block/replication.c b/block/replication.c
index 3885f04c31..5d6e2ec916 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -240,7 +240,7 @@ static coroutine_fn int 
replication_co_readv(BlockDriverState *bs,
                                  remaining_sectors);
         ret = bdrv_co_readv(bs->file, sector_num, remaining_sectors,
                             qiov);
-        backup_cow_request_end(&req);
+        backup_cow_request_end(&req, child->bs->job);
         goto out;
     }
 
diff --git a/include/block/block_backup.h b/include/block/block_backup.h
index 8a759477a3..2fe0cdd808 100644
--- a/include/block/block_backup.h
+++ b/include/block/block_backup.h
@@ -32,7 +32,7 @@ void backup_wait_for_overlapping_requests(BlockJob *job, 
int64_t sector_num,
 void backup_cow_request_begin(CowRequest *req, BlockJob *job,
                               int64_t sector_num,
                               int nb_sectors);
-void backup_cow_request_end(CowRequest *req);
+void backup_cow_request_end(CowRequest *req, BlockJob *job);
 
 void backup_do_checkpoint(BlockJob *job, Error **errp);
 
-- 
2.13.0





reply via email to

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