[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 14/15] blockjob: add AioContext attach/detach cal
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH v3 14/15] blockjob: add AioContext attach/detach callbacks |
Date: |
Mon, 13 Jun 2016 18:05:34 +0100 |
Block jobs need callbacks to get their affairs in order when the
AioContext is switched. Simple block jobs can get away without
implementing these callbacks.
The callbacks are needed if the block job accesses other
BlockDriverStates. Other BDSes need to be moved to the new AioContext
in the attach callback.
The detach callback must be used to quiesce asynchronous I/O. Although
bdrv_set_aio_context() internally calls bdrv_drain(), this isn't enough
when multiple BDSes are accessed by the job:
When completing requests on one BDS submits new requests on another BDS,
especially if this is cyclical, then a custom detach callback is needed.
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
blockjob.c | 33 +++++++++++++++++++++++++++++++++
include/block/blockjob.h | 14 ++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/blockjob.c b/blockjob.c
index b810d73..dd384fe 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -60,6 +60,33 @@ BlockJob *block_job_next(BlockJob *job)
return QLIST_NEXT(job, job_list);
}
+static void block_job_attached_aio_context(AioContext *new_context,
+ void *opaque)
+{
+ BlockJob *job = opaque;
+
+ if (job->driver->attached_aio_context) {
+ job->driver->attached_aio_context(job, new_context);
+ }
+
+ block_job_resume(job);
+}
+
+static void block_job_detach_aio_context(void *opaque)
+{
+ BlockJob *job = opaque;
+
+ block_job_pause(job);
+
+ if (job->driver->detach_aio_context) {
+ job->driver->detach_aio_context(job);
+ }
+
+ while (job->busy) {
+ aio_poll(blk_get_aio_context(job->blk), true);
+ }
+}
+
void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
int64_t speed, BlockCompletionFunc *cb,
void *opaque, Error **errp)
@@ -92,6 +119,9 @@ void *block_job_create(const BlockJobDriver *driver,
BlockDriverState *bs,
QLIST_INSERT_HEAD(&block_jobs, job, job_list);
+ blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
+ block_job_detach_aio_context, job);
+
/* Only set speed when necessary to avoid NotSupported error */
if (speed != 0) {
Error *local_err = NULL;
@@ -117,6 +147,9 @@ void block_job_unref(BlockJob *job)
BlockDriverState *bs = blk_bs(job->blk);
bs->job = NULL;
bdrv_op_unblock_all(bs, job->blocker);
+ blk_remove_aio_context_notifier(job->blk,
+ block_job_attached_aio_context,
+ block_job_detach_aio_context, job);
blk_unref(job->blk);
error_free(job->blocker);
g_free(job->id);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index f83a4f0..604aff8 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -70,6 +70,20 @@ typedef struct BlockJobDriver {
* never both.
*/
void (*abort)(BlockJob *job);
+
+ /**
+ * If the callback is not NULL, it will be invoked before the job is
+ * resumed in a new AioContext. This is the place to move any resources
+ * besides job->blk to the new AioContext.
+ */
+ void (*attached_aio_context)(BlockJob *job, AioContext *new_context);
+
+ /**
+ * If the callback is not NULL, it will be invoked after the job is paused
+ * but before job->blk is detached from the old AioContext. This is the
+ * place to complete all asynchronous I/O that is in flight.
+ */
+ void (*detach_aio_context)(BlockJob *job);
} BlockJobDriver;
/**
--
2.5.5
- [Qemu-devel] [PATCH v3 04/15] user-exec: Don't reextract sigmask from usercontext pointer, (continued)
- [Qemu-devel] [PATCH v3 04/15] user-exec: Don't reextract sigmask from usercontext pointer, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 05/15] target-i386: Add comment about do_interrupt_user() next_eip argument, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 06/15] target-i386: Move user-mode exception actions out of user-exec.c, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 08/15] ui: fix regression in printing VNC host/port on startup, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 07/15] vnc: drop unused depth arg for set_pixel_format, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 09/15] gtk: fix vte version check, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 10/15] ui/console-gl: Add support for big endian display surfaces, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 12/15] blockjob: move iostatus reset out of block_job_enter(), Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 11/15] console: ignore ui_info updates which don't actually update something, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 13/15] blockjob: add pause points, Stefan Hajnoczi, 2016/06/13
- [Qemu-devel] [PATCH v3 14/15] blockjob: add AioContext attach/detach callbacks,
Stefan Hajnoczi <=
- [Qemu-devel] [PATCH v3 15/15] mirror: follow AioContext change gracefully, Stefan Hajnoczi, 2016/06/13
- Re: [Qemu-devel] [PATCH v3 00/15] mirror: follow AioContext change gracefully, Stefan Hajnoczi, 2016/06/13
- Re: [Qemu-devel] [PATCH v3 00/15] mirror: follow AioContext change gracefully, Fam Zheng, 2016/06/14