From: Jeff Cody <jcody@redhat.com>
To: John Snow <jsnow@redhat.com>
Cc: qemu-block@nongnu.org, qemu-devel@nongnu.org, kwolf@redhat.com,
Stefan Hajnoczi <stefanha@redhat.com>,
Max Reitz <mreitz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v3 3/9] jobs: add exit shim
Date: Fri, 31 Aug 2018 09:48:28 -0400 [thread overview]
Message-ID: <20180831134828.GE415265@localhost.localdomain> (raw)
In-Reply-To: <20180830015734.19765-4-jsnow@redhat.com>
On Wed, Aug 29, 2018 at 09:57:28PM -0400, John Snow wrote:
> 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>
Reviewed-by: Jeff Cody <jcody@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-31 13:48 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 ` [Qemu-devel] [PATCH v3 3/9] jobs: add exit shim John Snow
2018-08-31 13:48 ` Jeff Cody [this message]
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=20180831134828.GE415265@localhost.localdomain \
--to=jcody@redhat.com \
--cc=jsnow@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.