Blame SOURCES/kvm-job-Add-job_drain.patch

1bdc94
From eb408c486b9f287df241f65b8abcb05b3c8772da Mon Sep 17 00:00:00 2001
1bdc94
From: Kevin Wolf <kwolf@redhat.com>
1bdc94
Date: Tue, 26 Jun 2018 09:48:18 +0200
1bdc94
Subject: [PATCH 49/89] job: Add job_drain()
1bdc94
1bdc94
RH-Author: Kevin Wolf <kwolf@redhat.com>
1bdc94
Message-id: <20180626094856.6924-36-kwolf@redhat.com>
1bdc94
Patchwork-id: 81119
1bdc94
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 35/73] job: Add job_drain()
1bdc94
Bugzilla: 1513543
1bdc94
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
1bdc94
RH-Acked-by: Max Reitz <mreitz@redhat.com>
1bdc94
RH-Acked-by: Fam Zheng <famz@redhat.com>
1bdc94
1bdc94
block_job_drain() contains a blk_drain() call which cannot be moved to
1bdc94
Job, so add a new JobDriver callback JobDriver.drain which has a common
1bdc94
implementation for all BlockJobs. In addition to this we keep the
1bdc94
existing BlockJobDriver.drain callback that is called by the common
1bdc94
drain implementation for all block jobs.
1bdc94
1bdc94
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1bdc94
Reviewed-by: Max Reitz <mreitz@redhat.com>
1bdc94
(cherry picked from commit b69f777dd9ba992fdd35828a90eefcd88c0ec332)
1bdc94
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1bdc94
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
1bdc94
---
1bdc94
 block/backup.c               |  1 +
1bdc94
 block/commit.c               |  1 +
1bdc94
 block/mirror.c               |  2 ++
1bdc94
 block/stream.c               |  1 +
1bdc94
 blockjob.c                   | 20 ++++++++++----------
1bdc94
 include/block/blockjob_int.h | 12 ++++++++++++
1bdc94
 include/qemu/job.h           | 13 +++++++++++++
1bdc94
 job.c                        | 11 +++++++++++
1bdc94
 tests/test-bdrv-drain.c      |  1 +
1bdc94
 tests/test-blockjob-txn.c    |  1 +
1bdc94
 tests/test-blockjob.c        |  2 ++
1bdc94
 11 files changed, 55 insertions(+), 10 deletions(-)
1bdc94
1bdc94
diff --git a/block/backup.c b/block/backup.c
1bdc94
index bd31282..ca7d990 100644
1bdc94
--- a/block/backup.c
1bdc94
+++ b/block/backup.c
1bdc94
@@ -529,6 +529,7 @@ static const BlockJobDriver backup_job_driver = {
1bdc94
         .job_type               = JOB_TYPE_BACKUP,
1bdc94
         .free                   = block_job_free,
1bdc94
         .user_resume            = block_job_user_resume,
1bdc94
+        .drain                  = block_job_drain,
1bdc94
         .start                  = backup_run,
1bdc94
         .commit                 = backup_commit,
1bdc94
         .abort                  = backup_abort,
1bdc94
diff --git a/block/commit.c b/block/commit.c
1bdc94
index e53b2d7..02a8af9 100644
1bdc94
--- a/block/commit.c
1bdc94
+++ b/block/commit.c
1bdc94
@@ -221,6 +221,7 @@ static const BlockJobDriver commit_job_driver = {
1bdc94
         .job_type      = JOB_TYPE_COMMIT,
1bdc94
         .free          = block_job_free,
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
+        .drain         = block_job_drain,
1bdc94
         .start         = commit_run,
1bdc94
     },
1bdc94
 };
1bdc94
diff --git a/block/mirror.c b/block/mirror.c
1bdc94
index c3951d1..a579bd8 100644
1bdc94
--- a/block/mirror.c
1bdc94
+++ b/block/mirror.c
1bdc94
@@ -992,6 +992,7 @@ static const BlockJobDriver mirror_job_driver = {
1bdc94
         .job_type               = JOB_TYPE_MIRROR,
1bdc94
         .free                   = block_job_free,
1bdc94
         .user_resume            = block_job_user_resume,
1bdc94
+        .drain                  = block_job_drain,
1bdc94
         .start                  = mirror_run,
1bdc94
         .pause                  = mirror_pause,
1bdc94
     },
1bdc94
@@ -1006,6 +1007,7 @@ static const BlockJobDriver commit_active_job_driver = {
1bdc94
         .job_type               = JOB_TYPE_COMMIT,
1bdc94
         .free                   = block_job_free,
1bdc94
         .user_resume            = block_job_user_resume,
1bdc94
+        .drain                  = block_job_drain,
1bdc94
         .start                  = mirror_run,
1bdc94
         .pause                  = mirror_pause,
1bdc94
     },
1bdc94
diff --git a/block/stream.c b/block/stream.c
1bdc94
index eee0253..b996278 100644
1bdc94
--- a/block/stream.c
1bdc94
+++ b/block/stream.c
1bdc94
@@ -215,6 +215,7 @@ static const BlockJobDriver stream_job_driver = {
1bdc94
         .free          = block_job_free,
1bdc94
         .start         = stream_run,
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
+        .drain         = block_job_drain,
1bdc94
     },
1bdc94
 };
1bdc94
 
1bdc94
diff --git a/blockjob.c b/blockjob.c
1bdc94
index 4cac367..63e1669 100644
1bdc94
--- a/blockjob.c
1bdc94
+++ b/blockjob.c
1bdc94
@@ -169,14 +169,13 @@ static void block_job_attached_aio_context(AioContext *new_context,
1bdc94
     job_resume(&job->job);
1bdc94
 }
1bdc94
 
1bdc94
-static void block_job_drain(BlockJob *job)
1bdc94
+void block_job_drain(Job *job)
1bdc94
 {
1bdc94
-    /* If job is !job->job.busy this kicks it into the next pause point. */
1bdc94
-    block_job_enter(job);
1bdc94
+    BlockJob *bjob = container_of(job, BlockJob, job);
1bdc94
 
1bdc94
-    blk_drain(job->blk);
1bdc94
-    if (job->driver->drain) {
1bdc94
-        job->driver->drain(job);
1bdc94
+    blk_drain(bjob->blk);
1bdc94
+    if (bjob->driver->drain) {
1bdc94
+        bjob->driver->drain(bjob);
1bdc94
     }
1bdc94
 }
1bdc94
 
1bdc94
@@ -190,7 +189,7 @@ static void block_job_detach_aio_context(void *opaque)
1bdc94
     job_pause(&job->job);
1bdc94
 
1bdc94
     while (!job->job.paused && !job_is_completed(&job->job)) {
1bdc94
-        block_job_drain(job);
1bdc94
+        job_drain(&job->job);
1bdc94
     }
1bdc94
 
1bdc94
     job->job.aio_context = NULL;
1bdc94
@@ -327,11 +326,11 @@ static int block_job_finish_sync(BlockJob *job,
1bdc94
         job_unref(&job->job);
1bdc94
         return -EBUSY;
1bdc94
     }
1bdc94
-    /* block_job_drain calls block_job_enter, and it should be enough to
1bdc94
-     * induce progress until the job completes or moves to the main thread.
1bdc94
+    /* job_drain calls job_enter, and it should be enough to induce progress
1bdc94
+     * until the job completes or moves to the main thread.
1bdc94
     */
1bdc94
     while (!job->job.deferred_to_main_loop && !job_is_completed(&job->job)) {
1bdc94
-        block_job_drain(job);
1bdc94
+        job_drain(&job->job);
1bdc94
     }
1bdc94
     while (!job_is_completed(&job->job)) {
1bdc94
         aio_poll(qemu_get_aio_context(), true);
1bdc94
@@ -713,6 +712,7 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
1bdc94
     assert(is_block_job(&job->job));
1bdc94
     assert(job->job.driver->free == &block_job_free);
1bdc94
     assert(job->job.driver->user_resume == &block_job_user_resume);
1bdc94
+    assert(job->job.driver->drain == &block_job_drain);
1bdc94
 
1bdc94
     job->driver        = driver;
1bdc94
     job->blk           = blk;
1bdc94
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
1bdc94
index bf2b762..38fe22d 100644
1bdc94
--- a/include/block/blockjob_int.h
1bdc94
+++ b/include/block/blockjob_int.h
1bdc94
@@ -65,6 +65,10 @@ struct BlockJobDriver {
1bdc94
      * If the callback is not NULL, it will be invoked when the job has to be
1bdc94
      * synchronously cancelled or completed; it should drain BlockDriverStates
1bdc94
      * as required to ensure progress.
1bdc94
+     *
1bdc94
+     * Block jobs must use the default implementation for job_driver.drain,
1bdc94
+     * which will in turn call this callback after doing generic block job
1bdc94
+     * stuff.
1bdc94
      */
1bdc94
     void (*drain)(BlockJob *job);
1bdc94
 };
1bdc94
@@ -112,6 +116,14 @@ void block_job_free(Job *job);
1bdc94
 void block_job_user_resume(Job *job);
1bdc94
 
1bdc94
 /**
1bdc94
+ * block_job_drain:
1bdc94
+ * Callback to be used for JobDriver.drain in all block jobs. Drains the main
1bdc94
+ * block node associated with the block jobs and calls BlockJobDriver.drain for
1bdc94
+ * job-specific actions.
1bdc94
+ */
1bdc94
+void block_job_drain(Job *job);
1bdc94
+
1bdc94
+/**
1bdc94
  * block_job_yield:
1bdc94
  * @job: The job that calls the function.
1bdc94
  *
1bdc94
diff --git a/include/qemu/job.h b/include/qemu/job.h
1bdc94
index 2648c74..aebc195 100644
1bdc94
--- a/include/qemu/job.h
1bdc94
+++ b/include/qemu/job.h
1bdc94
@@ -167,6 +167,13 @@ struct JobDriver {
1bdc94
      */
1bdc94
     void (*user_resume)(Job *job);
1bdc94
 
1bdc94
+    /*
1bdc94
+     * If the callback is not NULL, it will be invoked when the job has to be
1bdc94
+     * synchronously cancelled or completed; it should drain any activities
1bdc94
+     * as required to ensure progress.
1bdc94
+     */
1bdc94
+    void (*drain)(Job *job);
1bdc94
+
1bdc94
     /**
1bdc94
      * If the callback is not NULL, it will be invoked when all the jobs
1bdc94
      * belonging to the same transaction complete; or upon this job's
1bdc94
@@ -325,6 +332,12 @@ bool job_user_paused(Job *job);
1bdc94
  */
1bdc94
 void job_user_resume(Job *job, Error **errp);
1bdc94
 
1bdc94
+/*
1bdc94
+ * Drain any activities as required to ensure progress. This can be called in a
1bdc94
+ * loop to synchronously complete a job.
1bdc94
+ */
1bdc94
+void job_drain(Job *job);
1bdc94
+
1bdc94
 /**
1bdc94
  * Get the next element from the list of block jobs after @job, or the
1bdc94
  * first one if @job is %NULL.
1bdc94
diff --git a/job.c b/job.c
1bdc94
index 64b64da..3772a35 100644
1bdc94
--- a/job.c
1bdc94
+++ b/job.c
1bdc94
@@ -367,6 +367,17 @@ void coroutine_fn job_sleep_ns(Job *job, int64_t ns)
1bdc94
     job_pause_point(job);
1bdc94
 }
1bdc94
 
1bdc94
+void job_drain(Job *job)
1bdc94
+{
1bdc94
+    /* If job is !busy this kicks it into the next pause point. */
1bdc94
+    job_enter(job);
1bdc94
+
1bdc94
+    if (job->driver->drain) {
1bdc94
+        job->driver->drain(job);
1bdc94
+    }
1bdc94
+}
1bdc94
+
1bdc94
+
1bdc94
 /**
1bdc94
  * All jobs must allow a pause point before entering their job proper. This
1bdc94
  * ensures that jobs can be paused prior to being started, then resumed later.
1bdc94
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
1bdc94
index c993512..58ea566 100644
1bdc94
--- a/tests/test-bdrv-drain.c
1bdc94
+++ b/tests/test-bdrv-drain.c
1bdc94
@@ -525,6 +525,7 @@ BlockJobDriver test_job_driver = {
1bdc94
         .instance_size  = sizeof(TestBlockJob),
1bdc94
         .free           = block_job_free,
1bdc94
         .user_resume    = block_job_user_resume,
1bdc94
+        .drain          = block_job_drain,
1bdc94
         .start          = test_job_start,
1bdc94
     },
1bdc94
     .complete       = test_job_complete,
1bdc94
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
1bdc94
index 60e9fa2..1572f8d 100644
1bdc94
--- a/tests/test-blockjob-txn.c
1bdc94
+++ b/tests/test-blockjob-txn.c
1bdc94
@@ -79,6 +79,7 @@ static const BlockJobDriver test_block_job_driver = {
1bdc94
         .instance_size = sizeof(TestBlockJob),
1bdc94
         .free          = block_job_free,
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
+        .drain         = block_job_drain,
1bdc94
         .start         = test_block_job_run,
1bdc94
     },
1bdc94
 };
1bdc94
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
1bdc94
index 1fe6803..592a136 100644
1bdc94
--- a/tests/test-blockjob.c
1bdc94
+++ b/tests/test-blockjob.c
1bdc94
@@ -21,6 +21,7 @@ static const BlockJobDriver test_block_job_driver = {
1bdc94
         .instance_size = sizeof(BlockJob),
1bdc94
         .free          = block_job_free,
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
+        .drain         = block_job_drain,
1bdc94
     },
1bdc94
 };
1bdc94
 
1bdc94
@@ -201,6 +202,7 @@ static const BlockJobDriver test_cancel_driver = {
1bdc94
         .instance_size = sizeof(CancelJob),
1bdc94
         .free          = block_job_free,
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
+        .drain         = block_job_drain,
1bdc94
         .start         = cancel_job_start,
1bdc94
     },
1bdc94
     .complete      = cancel_job_complete,
1bdc94
-- 
1bdc94
1.8.3.1
1bdc94