Blame SOURCES/kvm-jobs-utilize-job_exit-shim.patch

1bdc94
From 2986609502d393267e97d2bb874427acef906a61 Mon Sep 17 00:00:00 2001
1bdc94
From: John Snow <jsnow@redhat.com>
1bdc94
Date: Mon, 10 Sep 2018 18:17:44 +0200
1bdc94
Subject: [PATCH 06/25] jobs: utilize job_exit shim
1bdc94
1bdc94
RH-Author: John Snow <jsnow@redhat.com>
1bdc94
Message-id: <20180910181803.11781-7-jsnow@redhat.com>
1bdc94
Patchwork-id: 82106
1bdc94
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH 06/25] jobs: utilize job_exit shim
1bdc94
Bugzilla: 1626061
1bdc94
RH-Acked-by: Max Reitz <mreitz@redhat.com>
1bdc94
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
1bdc94
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
1bdc94
1bdc94
Utilize the job_exit shim by not calling job_defer_to_main_loop, and
1bdc94
where applicable, converting the deferred callback into the job_exit
1bdc94
callback.
1bdc94
1bdc94
This converts backup, stream, create, and the unit tests all at once.
1bdc94
Most of these jobs do not see any changes to the order in which they
1bdc94
clean up their resources, except the test-blockjob-txn test, which
1bdc94
now puts down its bs before job_completed is called.
1bdc94
1bdc94
This is safe for the same reason the reordering in the mirror job is
1bdc94
safe, because job_completed no longer runs under two locks, making
1bdc94
the unref safe even if it causes a flush.
1bdc94
1bdc94
Signed-off-by: John Snow <jsnow@redhat.com>
1bdc94
Reviewed-by: Max Reitz <mreitz@redhat.com>
1bdc94
Message-id: 20180830015734.19765-7-jsnow@redhat.com
1bdc94
Signed-off-by: Max Reitz <mreitz@redhat.com>
1bdc94
(cherry picked from commit eb23654dbe43b549ea2a9ebff9d8edf544d34a73)
1bdc94
Signed-off-by: John Snow <jsnow@redhat.com>
1bdc94
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
1bdc94
---
1bdc94
 block/backup.c            | 16 ----------------
1bdc94
 block/create.c            | 14 +++-----------
1bdc94
 block/stream.c            | 22 +++++++---------------
1bdc94
 tests/test-bdrv-drain.c   |  6 ------
1bdc94
 tests/test-blockjob-txn.c | 11 ++---------
1bdc94
 tests/test-blockjob.c     | 10 ++++------
1bdc94
 6 files changed, 16 insertions(+), 63 deletions(-)
1bdc94
1bdc94
diff --git a/block/backup.c b/block/backup.c
1bdc94
index a5bf699..08a5b74 100644
1bdc94
--- a/block/backup.c
1bdc94
+++ b/block/backup.c
1bdc94
@@ -380,18 +380,6 @@ static BlockErrorAction backup_error_action(BackupBlockJob *job,
1bdc94
     }
1bdc94
 }
1bdc94
 
1bdc94
-typedef struct {
1bdc94
-    int ret;
1bdc94
-} BackupCompleteData;
1bdc94
-
1bdc94
-static void backup_complete(Job *job, void *opaque)
1bdc94
-{
1bdc94
-    BackupCompleteData *data = opaque;
1bdc94
-
1bdc94
-    job_completed(job, data->ret);
1bdc94
-    g_free(data);
1bdc94
-}
1bdc94
-
1bdc94
 static bool coroutine_fn yield_and_check(BackupBlockJob *job)
1bdc94
 {
1bdc94
     uint64_t delay_ns;
1bdc94
@@ -483,7 +471,6 @@ static void backup_incremental_init_copy_bitmap(BackupBlockJob *job)
1bdc94
 static int coroutine_fn backup_run(Job *opaque_job, Error **errp)
1bdc94
 {
1bdc94
     BackupBlockJob *job = container_of(opaque_job, BackupBlockJob, common.job);
1bdc94
-    BackupCompleteData *data;
1bdc94
     BlockDriverState *bs = blk_bs(job->common.blk);
1bdc94
     int64_t offset, nb_clusters;
1bdc94
     int ret = 0;
1bdc94
@@ -584,9 +571,6 @@ static int coroutine_fn backup_run(Job *opaque_job, Error **errp)
1bdc94
     qemu_co_rwlock_unlock(&job->flush_rwlock);
1bdc94
     hbitmap_free(job->copy_bitmap);
1bdc94
 
1bdc94
-    data = g_malloc(sizeof(*data));
1bdc94
-    data->ret = ret;
1bdc94
-    job_defer_to_main_loop(&job->common.job, backup_complete, data);
1bdc94
     return ret;
1bdc94
 }
1bdc94
 
1bdc94
diff --git a/block/create.c b/block/create.c
1bdc94
index 26a385c..9534121 100644
1bdc94
--- a/block/create.c
1bdc94
+++ b/block/create.c
1bdc94
@@ -34,28 +34,20 @@ typedef struct BlockdevCreateJob {
1bdc94
     Job common;
1bdc94
     BlockDriver *drv;
1bdc94
     BlockdevCreateOptions *opts;
1bdc94
-    int ret;
1bdc94
 } BlockdevCreateJob;
1bdc94
 
1bdc94
-static void blockdev_create_complete(Job *job, void *opaque)
1bdc94
-{
1bdc94
-    BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
1bdc94
-
1bdc94
-    job_completed(job, s->ret);
1bdc94
-}
1bdc94
-
1bdc94
 static int coroutine_fn blockdev_create_run(Job *job, Error **errp)
1bdc94
 {
1bdc94
     BlockdevCreateJob *s = container_of(job, BlockdevCreateJob, common);
1bdc94
+    int ret;
1bdc94
 
1bdc94
     job_progress_set_remaining(&s->common, 1);
1bdc94
-    s->ret = s->drv->bdrv_co_create(s->opts, errp);
1bdc94
+    ret = s->drv->bdrv_co_create(s->opts, errp);
1bdc94
     job_progress_update(&s->common, 1);
1bdc94
 
1bdc94
     qapi_free_BlockdevCreateOptions(s->opts);
1bdc94
-    job_defer_to_main_loop(&s->common, blockdev_create_complete, NULL);
1bdc94
 
1bdc94
-    return s->ret;
1bdc94
+    return ret;
1bdc94
 }
1bdc94
 
1bdc94
 static const JobDriver blockdev_create_job_driver = {
1bdc94
diff --git a/block/stream.c b/block/stream.c
1bdc94
index 26a7753..67e1e72 100644
1bdc94
--- a/block/stream.c
1bdc94
+++ b/block/stream.c
1bdc94
@@ -54,20 +54,16 @@ static int coroutine_fn stream_populate(BlockBackend *blk,
1bdc94
     return blk_co_preadv(blk, offset, qiov.size, &qiov, BDRV_REQ_COPY_ON_READ);
1bdc94
 }
1bdc94
 
1bdc94
-typedef struct {
1bdc94
-    int ret;
1bdc94
-} StreamCompleteData;
1bdc94
-
1bdc94
-static void stream_complete(Job *job, void *opaque)
1bdc94
+static void stream_exit(Job *job)
1bdc94
 {
1bdc94
     StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
1bdc94
     BlockJob *bjob = &s->common;
1bdc94
-    StreamCompleteData *data = opaque;
1bdc94
     BlockDriverState *bs = blk_bs(bjob->blk);
1bdc94
     BlockDriverState *base = s->base;
1bdc94
     Error *local_err = NULL;
1bdc94
+    int ret = job->ret;
1bdc94
 
1bdc94
-    if (!job_is_cancelled(job) && bs->backing && data->ret == 0) {
1bdc94
+    if (!job_is_cancelled(job) && bs->backing && ret == 0) {
1bdc94
         const char *base_id = NULL, *base_fmt = NULL;
1bdc94
         if (base) {
1bdc94
             base_id = s->backing_file_str;
1bdc94
@@ -75,11 +71,11 @@ static void stream_complete(Job *job, void *opaque)
1bdc94
                 base_fmt = base->drv->format_name;
1bdc94
             }
1bdc94
         }
1bdc94
-        data->ret = bdrv_change_backing_file(bs, base_id, base_fmt);
1bdc94
+        ret = bdrv_change_backing_file(bs, base_id, base_fmt);
1bdc94
         bdrv_set_backing_hd(bs, base, &local_err);
1bdc94
         if (local_err) {
1bdc94
             error_report_err(local_err);
1bdc94
-            data->ret = -EPERM;
1bdc94
+            ret = -EPERM;
1bdc94
             goto out;
1bdc94
         }
1bdc94
     }
1bdc94
@@ -93,14 +89,12 @@ out:
1bdc94
     }
1bdc94
 
1bdc94
     g_free(s->backing_file_str);
1bdc94
-    job_completed(job, data->ret);
1bdc94
-    g_free(data);
1bdc94
+    job->ret = ret;
1bdc94
 }
1bdc94
 
1bdc94
 static int coroutine_fn stream_run(Job *job, Error **errp)
1bdc94
 {
1bdc94
     StreamBlockJob *s = container_of(job, StreamBlockJob, common.job);
1bdc94
-    StreamCompleteData *data;
1bdc94
     BlockBackend *blk = s->common.blk;
1bdc94
     BlockDriverState *bs = blk_bs(blk);
1bdc94
     BlockDriverState *base = s->base;
1bdc94
@@ -203,9 +197,6 @@ static int coroutine_fn stream_run(Job *job, Error **errp)
1bdc94
 
1bdc94
 out:
1bdc94
     /* Modify backing chain and close BDSes in main loop */
1bdc94
-    data = g_malloc(sizeof(*data));
1bdc94
-    data->ret = ret;
1bdc94
-    job_defer_to_main_loop(&s->common.job, stream_complete, data);
1bdc94
     return ret;
1bdc94
 }
1bdc94
 
1bdc94
@@ -215,6 +206,7 @@ static const BlockJobDriver stream_job_driver = {
1bdc94
         .job_type      = JOB_TYPE_STREAM,
1bdc94
         .free          = block_job_free,
1bdc94
         .run           = stream_run,
1bdc94
+        .exit          = stream_exit,
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
         .drain         = block_job_drain,
1bdc94
     },
1bdc94
diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c
1bdc94
index 8937894..403446e 100644
1bdc94
--- a/tests/test-bdrv-drain.c
1bdc94
+++ b/tests/test-bdrv-drain.c
1bdc94
@@ -496,11 +496,6 @@ typedef struct TestBlockJob {
1bdc94
     bool should_complete;
1bdc94
 } TestBlockJob;
1bdc94
 
1bdc94
-static void test_job_completed(Job *job, void *opaque)
1bdc94
-{
1bdc94
-    job_completed(job, 0);
1bdc94
-}
1bdc94
-
1bdc94
 static int coroutine_fn test_job_run(Job *job, Error **errp)
1bdc94
 {
1bdc94
     TestBlockJob *s = container_of(job, TestBlockJob, common.job);
1bdc94
@@ -510,7 +505,6 @@ static int coroutine_fn test_job_run(Job *job, Error **errp)
1bdc94
         job_sleep_ns(&s->common.job, 100000);
1bdc94
     }
1bdc94
 
1bdc94
-    job_defer_to_main_loop(&s->common.job, test_job_completed, NULL);
1bdc94
     return 0;
1bdc94
 }
1bdc94
 
1bdc94
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
1bdc94
index 82cedee..ef29f35 100644
1bdc94
--- a/tests/test-blockjob-txn.c
1bdc94
+++ b/tests/test-blockjob-txn.c
1bdc94
@@ -24,17 +24,11 @@ typedef struct {
1bdc94
     int *result;
1bdc94
 } TestBlockJob;
1bdc94
 
1bdc94
-static void test_block_job_complete(Job *job, void *opaque)
1bdc94
+static void test_block_job_exit(Job *job)
1bdc94
 {
1bdc94
     BlockJob *bjob = container_of(job, BlockJob, job);
1bdc94
     BlockDriverState *bs = blk_bs(bjob->blk);
1bdc94
-    int rc = (intptr_t)opaque;
1bdc94
 
1bdc94
-    if (job_is_cancelled(job)) {
1bdc94
-        rc = -ECANCELED;
1bdc94
-    }
1bdc94
-
1bdc94
-    job_completed(job, rc);
1bdc94
     bdrv_unref(bs);
1bdc94
 }
1bdc94
 
1bdc94
@@ -54,8 +48,6 @@ static int coroutine_fn test_block_job_run(Job *job, Error **errp)
1bdc94
         }
1bdc94
     }
1bdc94
 
1bdc94
-    job_defer_to_main_loop(job, test_block_job_complete,
1bdc94
-                           (void *)(intptr_t)s->rc);
1bdc94
     return s->rc;
1bdc94
 }
1bdc94
 
1bdc94
@@ -81,6 +73,7 @@ static const BlockJobDriver test_block_job_driver = {
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
         .drain         = block_job_drain,
1bdc94
         .run           = test_block_job_run,
1bdc94
+        .exit          = test_block_job_exit,
1bdc94
     },
1bdc94
 };
1bdc94
 
1bdc94
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
1bdc94
index 408a226..ad4a65b 100644
1bdc94
--- a/tests/test-blockjob.c
1bdc94
+++ b/tests/test-blockjob.c
1bdc94
@@ -163,11 +163,10 @@ typedef struct CancelJob {
1bdc94
     bool completed;
1bdc94
 } CancelJob;
1bdc94
 
1bdc94
-static void cancel_job_completed(Job *job, void *opaque)
1bdc94
+static void cancel_job_exit(Job *job)
1bdc94
 {
1bdc94
-    CancelJob *s = opaque;
1bdc94
+    CancelJob *s = container_of(job, CancelJob, common.job);
1bdc94
     s->completed = true;
1bdc94
-    job_completed(job, 0);
1bdc94
 }
1bdc94
 
1bdc94
 static void cancel_job_complete(Job *job, Error **errp)
1bdc94
@@ -182,7 +181,7 @@ static int coroutine_fn cancel_job_run(Job *job, Error **errp)
1bdc94
 
1bdc94
     while (!s->should_complete) {
1bdc94
         if (job_is_cancelled(&s->common.job)) {
1bdc94
-            goto defer;
1bdc94
+            return 0;
1bdc94
         }
1bdc94
 
1bdc94
         if (!job_is_ready(&s->common.job) && s->should_converge) {
1bdc94
@@ -192,8 +191,6 @@ static int coroutine_fn cancel_job_run(Job *job, Error **errp)
1bdc94
         job_sleep_ns(&s->common.job, 100000);
1bdc94
     }
1bdc94
 
1bdc94
- defer:
1bdc94
-    job_defer_to_main_loop(&s->common.job, cancel_job_completed, s);
1bdc94
     return 0;
1bdc94
 }
1bdc94
 
1bdc94
@@ -204,6 +201,7 @@ static const BlockJobDriver test_cancel_driver = {
1bdc94
         .user_resume   = block_job_user_resume,
1bdc94
         .drain         = block_job_drain,
1bdc94
         .run           = cancel_job_run,
1bdc94
+        .exit          = cancel_job_exit,
1bdc94
         .complete      = cancel_job_complete,
1bdc94
     },
1bdc94
 };
1bdc94
-- 
1bdc94
1.8.3.1
1bdc94