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

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