From: John Snow <jsnow@redhat.com>
To: qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: kwolf@redhat.com, Jeff Cody <jcody@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
Max Reitz <mreitz@redhat.com>,
jtc@redhat.com, John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [PATCH v3 3/9] jobs: add exit shim
Date: Wed, 29 Aug 2018 21:57:28 -0400 [thread overview]
Message-ID: <20180830015734.19765-4-jsnow@redhat.com> (raw)
In-Reply-To: <20180830015734.19765-1-jsnow@redhat.com>
All jobs do the same thing when they leave their running loop:
- Store the return code in a structure
- wait to receive this structure in the main thread
- signal job completion via job_completed
Few jobs do anything beyond exactly this. Consolidate this exit
logic for a net reduction in SLOC.
More seriously, when we utilize job_defer_to_main_loop_bh to call
a function that calls job_completed, job_finalize_single will run
in a context where it has recursively taken the aio_context lock,
which can cause hangs if it puts down a reference that causes a flush.
You can observe this in practice by looking at mirror_exit's careful
placement of job_completed and bdrv_unref calls.
If we centralize job exiting, we can signal job completion from outside
of the aio_context, which should allow for job cleanup code to run with
only one lock, which makes cleanup callbacks less tricky to write.
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
include/qemu/job.h | 11 +++++++++++
job.c | 18 ++++++++++++++++++
2 files changed, 29 insertions(+)
diff --git a/include/qemu/job.h b/include/qemu/job.h
index e0e99870a1..1144d671a1 100644
--- a/include/qemu/job.h
+++ b/include/qemu/job.h
@@ -208,6 +208,17 @@ struct JobDriver {
*/
void (*drain)(Job *job);
+ /**
+ * If the callback is not NULL, exit will be invoked from the main thread
+ * when the job's coroutine has finished, but before transactional
+ * convergence; before @prepare or @abort.
+ *
+ * FIXME TODO: This callback is only temporary to transition remaining jobs
+ * to prepare/commit/abort/clean callbacks and will be removed before 3.1.
+ * is released.
+ */
+ void (*exit)(Job *job);
+
/**
* If the callback is not NULL, prepare will be invoked when all the jobs
* belonging to the same transaction complete; or upon this job's completion
diff --git a/job.c b/job.c
index bc1d970df4..bc8dad4e71 100644
--- a/job.c
+++ b/job.c
@@ -535,6 +535,18 @@ void job_drain(Job *job)
}
}
+static void job_exit(void *opaque)
+{
+ Job *job = (Job *)opaque;
+ AioContext *aio_context = job->aio_context;
+
+ if (job->driver->exit) {
+ aio_context_acquire(aio_context);
+ job->driver->exit(job);
+ aio_context_release(aio_context);
+ }
+ job_completed(job, job->ret);
+}
/**
* All jobs must allow a pause point before entering their job proper. This
@@ -547,6 +559,12 @@ static void coroutine_fn job_co_entry(void *opaque)
assert(job && job->driver && job->driver->run);
job_pause_point(job);
job->ret = job->driver->run(job, &job->err);
+ if (!job->deferred_to_main_loop) {
+ job->deferred_to_main_loop = true;
+ aio_bh_schedule_oneshot(qemu_get_aio_context(),
+ job_exit,
+ job);
+ }
}
--
2.14.4
next prev parent reply other threads:[~2018-08-30 2:02 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-30 1:57 [Qemu-devel] [PATCH v3 0/9] jobs: Job Exit Refactoring Pt 1 John Snow
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 1/9] jobs: change start callback to run callback John Snow
2018-08-31 13:27 ` Jeff Cody
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 2/9] jobs: canonize Error object John Snow
2018-08-30 19:58 ` Eric Blake
2018-08-31 6:08 ` Markus Armbruster
2018-08-31 15:23 ` John Snow
2018-09-01 7:54 ` Markus Armbruster
2018-09-03 12:22 ` Kevin Wolf
2018-09-03 14:11 ` Markus Armbruster
2018-09-04 16:09 ` John Snow
2018-08-30 1:57 ` John Snow [this message]
2018-08-31 13:48 ` [Qemu-devel] [PATCH v3 3/9] jobs: add exit shim Jeff Cody
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 4/9] block/commit: utilize job_exit shim John Snow
2018-08-31 13:58 ` Jeff Cody
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 5/9] block/mirror: " John Snow
2018-08-31 13:23 ` Max Reitz
2018-08-31 14:09 ` Jeff Cody
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 6/9] jobs: " John Snow
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 7/9] block/backup: make function variables consistently named John Snow
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 8/9] jobs: remove ret argument to job_completed; privatize it John Snow
2018-08-31 13:25 ` Max Reitz
2018-08-30 1:57 ` [Qemu-devel] [PATCH v3 9/9] jobs: remove job_defer_to_main_loop John Snow
2018-08-31 14:12 ` [Qemu-devel] [PATCH v3 0/9] jobs: Job Exit Refactoring Pt 1 Max Reitz
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=20180830015734.19765-4-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=jcody@redhat.com \
--cc=jtc@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.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.