[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 12/14] block: Add bdrv_co_enter()/leave()
From: |
Markus Armbruster |
Subject: |
[PULL 12/14] block: Add bdrv_co_enter()/leave() |
Date: |
Fri, 9 Oct 2020 08:34:30 +0200 |
From: Kevin Wolf <kwolf@redhat.com>
Add a pair of functions to temporarily move the current coroutine to the
AioContext of a given BlockDriverState.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-Id: <20201005155855.256490-13-kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
include/block/block.h | 17 +++++++++++++++++
block.c | 23 +++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/include/block/block.h b/include/block/block.h
index ce2ac39299..1027c58a41 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -640,6 +640,23 @@ bool bdrv_debug_is_suspended(BlockDriverState *bs, const
char *tag);
*/
AioContext *bdrv_get_aio_context(BlockDriverState *bs);
+/**
+ * Move the current coroutine to the AioContext of @bs and return the old
+ * AioContext of the coroutine. Increase bs->in_flight so that draining @bs
+ * will wait for the operation to proceed until the corresponding
+ * bdrv_co_leave().
+ *
+ * Consequently, you can't call drain inside a bdrv_co_enter/leave() section as
+ * this will deadlock.
+ */
+AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs);
+
+/**
+ * Ends a section started by bdrv_co_enter(). Move the current coroutine back
+ * to old_ctx and decrease bs->in_flight again.
+ */
+void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx);
+
/**
* Transfer control to @co in the aio context of @bs
*/
diff --git a/block.c b/block.c
index 52b2e2709f..8d9b9017d3 100644
--- a/block.c
+++ b/block.c
@@ -6303,6 +6303,29 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs)
return bs ? bs->aio_context : qemu_get_aio_context();
}
+AioContext *coroutine_fn bdrv_co_enter(BlockDriverState *bs)
+{
+ Coroutine *self = qemu_coroutine_self();
+ AioContext *old_ctx = qemu_coroutine_get_aio_context(self);
+ AioContext *new_ctx;
+
+ /*
+ * Increase bs->in_flight to ensure that this operation is completed before
+ * moving the node to a different AioContext. Read new_ctx only afterwards.
+ */
+ bdrv_inc_in_flight(bs);
+
+ new_ctx = bdrv_get_aio_context(bs);
+ aio_co_reschedule_self(new_ctx);
+ return old_ctx;
+}
+
+void coroutine_fn bdrv_co_leave(BlockDriverState *bs, AioContext *old_ctx)
+{
+ aio_co_reschedule_self(old_ctx);
+ bdrv_dec_in_flight(bs);
+}
+
void bdrv_coroutine_enter(BlockDriverState *bs, Coroutine *co)
{
aio_co_enter(bdrv_get_aio_context(bs), co);
--
2.26.2
- [PULL 00/14] Monitor patches for 2020-10-09, Markus Armbruster, 2020/10/09
- [PULL 02/14] monitor: Add Monitor parameter to monitor_get_cpu_index(), Markus Armbruster, 2020/10/09
- [PULL 06/14] qmp: Call monitor_set_cur() only in qmp_dispatch(), Markus Armbruster, 2020/10/09
- [PULL 05/14] qmp: Assert that no other monitor is active, Markus Armbruster, 2020/10/09
- [PULL 12/14] block: Add bdrv_co_enter()/leave(),
Markus Armbruster <=
- [PULL 14/14] block: Convert 'block_resize' to coroutine, Markus Armbruster, 2020/10/09
- [PULL 01/14] monitor: Add Monitor parameter to monitor_set_cpu(), Markus Armbruster, 2020/10/09
- [PULL 04/14] hmp: Update current monitor only in handle_hmp_command(), Markus Armbruster, 2020/10/09
- [PULL 09/14] qmp: Move dispatcher to a coroutine, Markus Armbruster, 2020/10/09
- Re: [PULL 09/14] qmp: Move dispatcher to a coroutine, Alex Bennée, 2020/10/12
- Re: [PULL 09/14] qmp: Move dispatcher to a coroutine, Kevin Wolf, 2020/10/12
- Re: [PULL 09/14] qmp: Move dispatcher to a coroutine, Philippe Mathieu-Daudé, 2020/10/12
- Re: [PULL 09/14] qmp: Move dispatcher to a coroutine, Kevin Wolf, 2020/10/12
- Re: [PULL 09/14] qmp: Move dispatcher to a coroutine, Alex Bennée, 2020/10/12
- Re: [PULL 09/14] qmp: Move dispatcher to a coroutine, Ben Widawsky, 2020/10/12