* [PATCH 0/9] Still more coroutine and various fixes in block layer
@ 2022-11-03 13:41 Emanuele Giuseppe Esposito
2022-11-03 13:41 ` [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine Emanuele Giuseppe Esposito
` (8 more replies)
0 siblings, 9 replies; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:41 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
This is a dump of all minor coroutine-related fixes found while looking
around and testing various things in the QEMU block layer.
Patches aim to:
- add missing coroutine_fn annotation to the functions
- simplify to avoid the typical "if in coroutine: fn()
// else create_coroutine(fn)" already present in generated_co_wraper
functions.
- make sure that if a BlockDriver callback is defined as coroutine_fn, then
it is always running in a coroutine.
Emanuele
Emanuele Giuseppe Esposito (9):
block: call bdrv_co_drain_begin in a coroutine
block-copy: add missing coroutine_fn annotations
nbd/server.c: add missing coroutine_fn annotations
block-backend: replace bdrv_*_above with blk_*_above
block: distinguish between bdrv_create running in coroutine and not
block/vmdk: add missing coroutine_fn annotations
block: bdrv_create_file is a coroutine_fn
block: bdrv_create is never called in non-coroutine context
block/dirty-bitmap: remove unnecessary qemu_in_coroutine() case
block.c | 107 +++++++++++++++++------------
block/block-backend.c | 21 ++++++
block/block-copy.c | 15 ++--
block/commit.c | 4 +-
block/dirty-bitmap.c | 66 ++++++++----------
block/vmdk.c | 36 +++++-----
include/block/block-global-state.h | 3 +-
include/sysemu/block-backend-io.h | 9 +++
nbd/server.c | 43 ++++++------
qemu-img.c | 4 +-
10 files changed, 178 insertions(+), 130 deletions(-)
--
2.31.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
@ 2022-11-03 13:41 ` Emanuele Giuseppe Esposito
2022-11-03 17:05 ` Paolo Bonzini
2022-11-03 13:41 ` [PATCH 2/9] block-copy: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
` (7 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:41 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
It seems that bdrv_open_driver() forgot to create a coroutine
where to call bs->drv->bdrv_co_drain_begin(), a callback
marked as coroutine_fn.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/block.c b/block.c
index 5311b21f8e..7211f62001 100644
--- a/block.c
+++ b/block.c
@@ -1637,12 +1637,34 @@ out:
g_free(gen_node_name);
}
+typedef struct DrainCo {
+ BlockDriverState *bs;
+ int ret;
+} DrainCo;
+
+static void coroutine_fn bdrv_co_drain_begin(void *opaque)
+{
+ int i;
+ DrainCo *co = opaque;
+ BlockDriverState *bs = co->bs;
+
+ for (i = 0; i < bs->quiesce_counter; i++) {
+ bs->drv->bdrv_co_drain_begin(bs);
+ }
+ co->ret = 0;
+}
+
static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
const char *node_name, QDict *options,
int open_flags, Error **errp)
{
Error *local_err = NULL;
- int i, ret;
+ int ret;
+ Coroutine *co;
+ DrainCo dco = {
+ .bs = bs,
+ .ret = NOT_DONE,
+ };
GLOBAL_STATE_CODE();
bdrv_assign_node_name(bs, node_name, &local_err);
@@ -1690,10 +1712,10 @@ static int bdrv_open_driver(BlockDriverState *bs, BlockDriver *drv,
assert(bdrv_min_mem_align(bs) != 0);
assert(is_power_of_2(bs->bl.request_alignment));
- for (i = 0; i < bs->quiesce_counter; i++) {
- if (drv->bdrv_co_drain_begin) {
- drv->bdrv_co_drain_begin(bs);
- }
+ if (drv->bdrv_co_drain_begin) {
+ co = qemu_coroutine_create(bdrv_co_drain_begin, &dco);
+ qemu_coroutine_enter(co);
+ AIO_WAIT_WHILE(qemu_get_aio_context(), dco.ret == NOT_DONE);
}
return 0;
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
2022-11-03 13:41 ` [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine Emanuele Giuseppe Esposito
@ 2022-11-03 13:41 ` Emanuele Giuseppe Esposito
2022-11-03 16:56 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 3/9] nbd/server.c: " Emanuele Giuseppe Esposito
` (6 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:41 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
block_copy_reset_unallocated and block_copy_is_cluster_allocated are
only called by backup_run, a corotuine_fn itself.
Same applies to block_copy_block_status, called by
block_copy_dirty_clusters.
Therefore mark them as coroutine too.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block/block-copy.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/block/block-copy.c b/block/block-copy.c
index bb947afdda..f33ab1d0b6 100644
--- a/block/block-copy.c
+++ b/block/block-copy.c
@@ -577,8 +577,9 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
return ret;
}
-static int block_copy_block_status(BlockCopyState *s, int64_t offset,
- int64_t bytes, int64_t *pnum)
+static coroutine_fn int block_copy_block_status(BlockCopyState *s,
+ int64_t offset,
+ int64_t bytes, int64_t *pnum)
{
int64_t num;
BlockDriverState *base;
@@ -613,8 +614,9 @@ static int block_copy_block_status(BlockCopyState *s, int64_t offset,
* Check if the cluster starting at offset is allocated or not.
* return via pnum the number of contiguous clusters sharing this allocation.
*/
-static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
- int64_t *pnum)
+static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
+ int64_t offset,
+ int64_t *pnum)
{
BlockDriverState *bs = s->source->bs;
int64_t count, total_count = 0;
@@ -669,8 +671,9 @@ void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes)
* @return 0 when the cluster at @offset was unallocated,
* 1 otherwise, and -ret on error.
*/
-int64_t block_copy_reset_unallocated(BlockCopyState *s,
- int64_t offset, int64_t *count)
+int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
+ int64_t offset,
+ int64_t *count)
{
int ret;
int64_t clusters, bytes;
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 3/9] nbd/server.c: add missing coroutine_fn annotations
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
2022-11-03 13:41 ` [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine Emanuele Giuseppe Esposito
2022-11-03 13:41 ` [PATCH 2/9] block-copy: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
2022-11-03 16:58 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 4/9] block-backend: replace bdrv_*_above with blk_*_above Emanuele Giuseppe Esposito
` (5 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
There are probably more missing, but right now it is necessary that
we extend coroutine_fn to block{allock/status}_to_extents, because
they use bdrv_* functions calling the generated_co_wrapper API, which
checks for the qemu_in_coroutine() case.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
nbd/server.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/nbd/server.c b/nbd/server.c
index ada16089f3..e2eec0cf46 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -2141,8 +2141,9 @@ static int nbd_extent_array_add(NBDExtentArray *ea,
return 0;
}
-static int blockstatus_to_extents(BlockDriverState *bs, uint64_t offset,
- uint64_t bytes, NBDExtentArray *ea)
+static int coroutine_fn blockstatus_to_extents(BlockDriverState *bs,
+ uint64_t offset, uint64_t bytes,
+ NBDExtentArray *ea)
{
while (bytes) {
uint32_t flags;
@@ -2168,8 +2169,9 @@ static int blockstatus_to_extents(BlockDriverState *bs, uint64_t offset,
return 0;
}
-static int blockalloc_to_extents(BlockDriverState *bs, uint64_t offset,
- uint64_t bytes, NBDExtentArray *ea)
+static int coroutine_fn blockalloc_to_extents(BlockDriverState *bs,
+ uint64_t offset, uint64_t bytes,
+ NBDExtentArray *ea)
{
while (bytes) {
int64_t num;
@@ -2220,11 +2222,12 @@ static int nbd_co_send_extents(NBDClient *client, uint64_t handle,
}
/* Get block status from the exported device and send it to the client */
-static int nbd_co_send_block_status(NBDClient *client, uint64_t handle,
- BlockDriverState *bs, uint64_t offset,
- uint32_t length, bool dont_fragment,
- bool last, uint32_t context_id,
- Error **errp)
+static int
+coroutine_fn nbd_co_send_block_status(NBDClient *client, uint64_t handle,
+ BlockDriverState *bs, uint64_t offset,
+ uint32_t length, bool dont_fragment,
+ bool last, uint32_t context_id,
+ Error **errp)
{
int ret;
unsigned int nb_extents = dont_fragment ? 1 : NBD_MAX_BLOCK_STATUS_EXTENTS;
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 4/9] block-backend: replace bdrv_*_above with blk_*_above
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
` (2 preceding siblings ...)
2022-11-03 13:42 ` [PATCH 3/9] nbd/server.c: " Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
2022-11-03 13:42 ` [PATCH 5/9] block: distinguish between bdrv_create running in coroutine and not Emanuele Giuseppe Esposito
` (4 subsequent siblings)
8 siblings, 0 replies; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
Avoid mixing bdrv_* functions with blk_*, so create blk_* counterparts
for:
- bdrv_block_status_above
- bdrv_is_allocated_above
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block/block-backend.c | 21 +++++++++++++++++++++
block/commit.c | 4 ++--
include/sysemu/block-backend-io.h | 9 +++++++++
nbd/server.c | 28 ++++++++++++++--------------
qemu-img.c | 4 ++--
5 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index ec17dc49a9..eb8787a3d9 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1423,6 +1423,27 @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
return blk_co_pwritev_part(blk, offset, bytes, qiov, 0, flags);
}
+int coroutine_fn blk_block_status_above(BlockBackend *blk,
+ BlockDriverState *base,
+ int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
+ BlockDriverState **file)
+{
+ IO_CODE();
+ return bdrv_block_status_above(blk_bs(blk), base, offset, bytes, pnum, map,
+ file);
+}
+
+int coroutine_fn blk_is_allocated_above(BlockBackend *blk,
+ BlockDriverState *base,
+ bool include_base, int64_t offset,
+ int64_t bytes, int64_t *pnum)
+{
+ IO_CODE();
+ return bdrv_is_allocated_above(blk_bs(blk), base, include_base, offset,
+ bytes, pnum);
+}
+
typedef struct BlkRwCo {
BlockBackend *blk;
int64_t offset;
diff --git a/block/commit.c b/block/commit.c
index 0029b31944..9d4d908344 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -155,8 +155,8 @@ static int coroutine_fn commit_run(Job *job, Error **errp)
break;
}
/* Copy if allocated above the base */
- ret = bdrv_is_allocated_above(blk_bs(s->top), s->base_overlay, true,
- offset, COMMIT_BUFFER_SIZE, &n);
+ ret = blk_is_allocated_above(s->top, s->base_overlay, true,
+ offset, COMMIT_BUFFER_SIZE, &n);
copy = (ret > 0);
trace_commit_one_iteration(s, offset, n, ret);
if (copy) {
diff --git a/include/sysemu/block-backend-io.h b/include/sysemu/block-backend-io.h
index 50f5aa2e07..a47cb825e5 100644
--- a/include/sysemu/block-backend-io.h
+++ b/include/sysemu/block-backend-io.h
@@ -92,6 +92,15 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
int64_t bytes, BdrvRequestFlags read_flags,
BdrvRequestFlags write_flags);
+int coroutine_fn blk_block_status_above(BlockBackend *blk,
+ BlockDriverState *base,
+ int64_t offset, int64_t bytes,
+ int64_t *pnum, int64_t *map,
+ BlockDriverState **file);
+int coroutine_fn blk_is_allocated_above(BlockBackend *blk,
+ BlockDriverState *base,
+ bool include_base, int64_t offset,
+ int64_t bytes, int64_t *pnum);
/*
* "I/O or GS" API functions. These functions can run without
diff --git a/nbd/server.c b/nbd/server.c
index e2eec0cf46..6389b46396 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1991,7 +1991,7 @@ static int coroutine_fn nbd_co_send_structured_error(NBDClient *client,
}
/* Do a sparse read and send the structured reply to the client.
- * Returns -errno if sending fails. bdrv_block_status_above() failure is
+ * Returns -errno if sending fails. blk_block_status_above() failure is
* reported to the client, at which point this function succeeds.
*/
static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
@@ -2007,10 +2007,10 @@ static int coroutine_fn nbd_co_send_sparse_read(NBDClient *client,
while (progress < size) {
int64_t pnum;
- int status = bdrv_block_status_above(blk_bs(exp->common.blk), NULL,
- offset + progress,
- size - progress, &pnum, NULL,
- NULL);
+ int status = blk_block_status_above(exp->common.blk, NULL,
+ offset + progress,
+ size - progress, &pnum, NULL,
+ NULL);
bool final;
if (status < 0) {
@@ -2141,14 +2141,14 @@ static int nbd_extent_array_add(NBDExtentArray *ea,
return 0;
}
-static int coroutine_fn blockstatus_to_extents(BlockDriverState *bs,
+static int coroutine_fn blockstatus_to_extents(BlockBackend *blk,
uint64_t offset, uint64_t bytes,
NBDExtentArray *ea)
{
while (bytes) {
uint32_t flags;
int64_t num;
- int ret = bdrv_block_status_above(bs, NULL, offset, bytes, &num,
+ int ret = blk_block_status_above(blk, NULL, offset, bytes, &num,
NULL, NULL);
if (ret < 0) {
@@ -2169,13 +2169,13 @@ static int coroutine_fn blockstatus_to_extents(BlockDriverState *bs,
return 0;
}
-static int coroutine_fn blockalloc_to_extents(BlockDriverState *bs,
+static int coroutine_fn blockalloc_to_extents(BlockBackend *blk,
uint64_t offset, uint64_t bytes,
NBDExtentArray *ea)
{
while (bytes) {
int64_t num;
- int ret = bdrv_is_allocated_above(bs, NULL, false, offset, bytes,
+ int ret = blk_is_allocated_above(blk, NULL, false, offset, bytes,
&num);
if (ret < 0) {
@@ -2224,7 +2224,7 @@ static int nbd_co_send_extents(NBDClient *client, uint64_t handle,
/* Get block status from the exported device and send it to the client */
static int
coroutine_fn nbd_co_send_block_status(NBDClient *client, uint64_t handle,
- BlockDriverState *bs, uint64_t offset,
+ BlockBackend *blk, uint64_t offset,
uint32_t length, bool dont_fragment,
bool last, uint32_t context_id,
Error **errp)
@@ -2234,9 +2234,9 @@ coroutine_fn nbd_co_send_block_status(NBDClient *client, uint64_t handle,
g_autoptr(NBDExtentArray) ea = nbd_extent_array_new(nb_extents);
if (context_id == NBD_META_ID_BASE_ALLOCATION) {
- ret = blockstatus_to_extents(bs, offset, length, ea);
+ ret = blockstatus_to_extents(blk, offset, length, ea);
} else {
- ret = blockalloc_to_extents(bs, offset, length, ea);
+ ret = blockalloc_to_extents(blk, offset, length, ea);
}
if (ret < 0) {
return nbd_co_send_structured_error(
@@ -2563,7 +2563,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
if (client->export_meta.base_allocation) {
ret = nbd_co_send_block_status(client, request->handle,
- blk_bs(exp->common.blk),
+ exp->common.blk,
request->from,
request->len, dont_fragment,
!--contexts_remaining,
@@ -2576,7 +2576,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
if (client->export_meta.allocation_depth) {
ret = nbd_co_send_block_status(client, request->handle,
- blk_bs(exp->common.blk),
+ exp->common.blk,
request->from, request->len,
dont_fragment,
!--contexts_remaining,
diff --git a/qemu-img.c b/qemu-img.c
index ace3adf8ae..35f8ceb6ff 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1730,8 +1730,8 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
do {
count = n * BDRV_SECTOR_SIZE;
- ret = bdrv_block_status_above(src_bs, base, offset, count, &count,
- NULL, NULL);
+ ret = bdrv_block_status_above(src_bs, base, offset, count,
+ &count, NULL, NULL);
if (ret < 0) {
if (s->salvage) {
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 5/9] block: distinguish between bdrv_create running in coroutine and not
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
` (3 preceding siblings ...)
2022-11-03 13:42 ` [PATCH 4/9] block-backend: replace bdrv_*_above with blk_*_above Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
2022-11-03 13:42 ` [PATCH 6/9] block/vmdk: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
` (3 subsequent siblings)
8 siblings, 0 replies; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
Call two different functions depending on whether bdrv_create
is in coroutine or not, following the same pattern as
generated_co_wrapper functions.
This allows to also call the coroutine function directly,
without using CreateCo or relying in bdrv_create().
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block.c | 74 ++++++++++++++++++++++++++++-----------------------------
1 file changed, 36 insertions(+), 38 deletions(-)
diff --git a/block.c b/block.c
index 7211f62001..eeb7a02aa2 100644
--- a/block.c
+++ b/block.c
@@ -522,66 +522,64 @@ typedef struct CreateCo {
Error *err;
} CreateCo;
-static void coroutine_fn bdrv_create_co_entry(void *opaque)
+static int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
+ QemuOpts *opts, Error **errp)
{
- Error *local_err = NULL;
int ret;
+ GLOBAL_STATE_CODE();
+ assert(*errp == NULL);
+
+ if (!drv->bdrv_co_create_opts) {
+ error_setg(errp, "Driver '%s' does not support image creation",
+ drv->format_name);
+ return -ENOTSUP;
+ }
+
+ ret = drv->bdrv_co_create_opts(drv, filename, opts, errp);
+ if (ret < 0 && !*errp) {
+ error_setg_errno(errp, -ret, "Could not create image");
+ }
+
+ return ret;
+}
+
+static void coroutine_fn bdrv_create_co_entry(void *opaque)
+{
CreateCo *cco = opaque;
- assert(cco->drv);
GLOBAL_STATE_CODE();
+ assert(cco->drv);
- ret = cco->drv->bdrv_co_create_opts(cco->drv,
- cco->filename, cco->opts, &local_err);
- error_propagate(&cco->err, local_err);
- cco->ret = ret;
+ cco->ret = bdrv_co_create(cco->drv, cco->filename, cco->opts, &cco->err);
}
int bdrv_create(BlockDriver *drv, const char* filename,
QemuOpts *opts, Error **errp)
{
- int ret;
-
GLOBAL_STATE_CODE();
- Coroutine *co;
- CreateCo cco = {
- .drv = drv,
- .filename = g_strdup(filename),
- .opts = opts,
- .ret = NOT_DONE,
- .err = NULL,
- };
-
- if (!drv->bdrv_co_create_opts) {
- error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
- ret = -ENOTSUP;
- goto out;
- }
-
if (qemu_in_coroutine()) {
/* Fast-path if already in coroutine context */
- bdrv_create_co_entry(&cco);
+ return bdrv_co_create(drv, filename, opts, errp);
} else {
+ Coroutine *co;
+ CreateCo cco = {
+ .drv = drv,
+ .filename = g_strdup(filename),
+ .opts = opts,
+ .ret = NOT_DONE,
+ .err = NULL,
+ };
+
co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
qemu_coroutine_enter(co);
while (cco.ret == NOT_DONE) {
aio_poll(qemu_get_aio_context(), true);
}
+ error_propagate(errp, cco.err);
+ g_free(cco.filename);
+ return cco.ret;
}
-
- ret = cco.ret;
- if (ret < 0) {
- if (cco.err) {
- error_propagate(errp, cco.err);
- } else {
- error_setg_errno(errp, -ret, "Could not create image");
- }
- }
-
-out:
- g_free(cco.filename);
- return ret;
}
/**
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 6/9] block/vmdk: add missing coroutine_fn annotations
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
` (4 preceding siblings ...)
2022-11-03 13:42 ` [PATCH 5/9] block: distinguish between bdrv_create running in coroutine and not Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
2022-11-03 17:00 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 7/9] block: bdrv_create_file is a coroutine_fn Emanuele Giuseppe Esposito
` (2 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
vmdk_co_create_opts() is a coroutine_fn, and calls vmdk_co_do_create()
which in turn can call two callbacks: vmdk_co_create_opts_cb and
vmdk_co_create_cb.
Mark all these functions as coroutine_fn, since vmdk_co_create_opts()
is the only caller.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block/vmdk.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/block/vmdk.c b/block/vmdk.c
index 26376352b9..0c32bf2e83 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -2285,10 +2285,11 @@ exit:
return ret;
}
-static int vmdk_create_extent(const char *filename, int64_t filesize,
- bool flat, bool compress, bool zeroed_grain,
- BlockBackend **pbb,
- QemuOpts *opts, Error **errp)
+static int coroutine_fn vmdk_create_extent(const char *filename,
+ int64_t filesize, bool flat,
+ bool compress, bool zeroed_grain,
+ BlockBackend **pbb,
+ QemuOpts *opts, Error **errp)
{
int ret;
BlockBackend *blk = NULL;
@@ -2366,14 +2367,14 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
* non-split format.
* idx >= 1: get the n-th extent if in a split subformat
*/
-typedef BlockBackend *(*vmdk_create_extent_fn)(int64_t size,
- int idx,
- bool flat,
- bool split,
- bool compress,
- bool zeroed_grain,
- void *opaque,
- Error **errp);
+typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size,
+ int idx,
+ bool flat,
+ bool split,
+ bool compress,
+ bool zeroed_grain,
+ void *opaque,
+ Error **errp);
static void vmdk_desc_add_extent(GString *desc,
const char *extent_line_fmt,
@@ -2616,7 +2617,7 @@ typedef struct {
QemuOpts *opts;
} VMDKCreateOptsData;
-static BlockBackend *vmdk_co_create_opts_cb(int64_t size, int idx,
+static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx,
bool flat, bool split, bool compress,
bool zeroed_grain, void *opaque,
Error **errp)
@@ -2768,10 +2769,11 @@ exit:
return ret;
}
-static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
- bool flat, bool split, bool compress,
- bool zeroed_grain, void *opaque,
- Error **errp)
+static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
+ bool flat, bool split,
+ bool compress,
+ bool zeroed_grain,
+ void *opaque, Error **errp)
{
int ret;
BlockDriverState *bs;
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 7/9] block: bdrv_create_file is a coroutine_fn
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
` (5 preceding siblings ...)
2022-11-03 13:42 ` [PATCH 6/9] block/vmdk: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
2022-11-03 17:01 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 8/9] block: bdrv_create is never called in non-coroutine context Emanuele Giuseppe Esposito
2022-11-03 13:42 ` [PATCH 9/9] block/dirty-bitmap: remove unnecessary qemu_in_coroutine() case Emanuele Giuseppe Esposito
8 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
It is always called in coroutine_fn callbacks, therefore
it can directly call bdrv_co_create().
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block.c | 6 ++++--
include/block/block-global-state.h | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/block.c b/block.c
index eeb7a02aa2..e5e70acf15 100644
--- a/block.c
+++ b/block.c
@@ -527,6 +527,7 @@ static int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
{
int ret;
GLOBAL_STATE_CODE();
+ assert(qemu_in_coroutine());
assert(*errp == NULL);
if (!drv->bdrv_co_create_opts) {
@@ -717,7 +718,8 @@ out:
return ret;
}
-int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
+int coroutine_fn bdrv_create_file(const char *filename, QemuOpts *opts,
+ Error **errp)
{
QemuOpts *protocol_opts;
BlockDriver *drv;
@@ -758,7 +760,7 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
goto out;
}
- ret = bdrv_create(drv, filename, protocol_opts, errp);
+ ret = bdrv_co_create(drv, filename, protocol_opts, errp);
out:
qemu_opts_del(protocol_opts);
qobject_unref(qdict);
diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
index 73795a0095..bd461f06a1 100644
--- a/include/block/block-global-state.h
+++ b/include/block/block-global-state.h
@@ -57,7 +57,8 @@ BlockDriver *bdrv_find_protocol(const char *filename,
BlockDriver *bdrv_find_format(const char *format_name);
int bdrv_create(BlockDriver *drv, const char* filename,
QemuOpts *opts, Error **errp);
-int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
+int coroutine_fn bdrv_create_file(const char *filename, QemuOpts *opts,
+ Error **errp);
BlockDriverState *bdrv_new(void);
int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 8/9] block: bdrv_create is never called in non-coroutine context
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
` (6 preceding siblings ...)
2022-11-03 13:42 ` [PATCH 7/9] block: bdrv_create_file is a coroutine_fn Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
2022-11-03 17:05 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 9/9] block/dirty-bitmap: remove unnecessary qemu_in_coroutine() case Emanuele Giuseppe Esposito
8 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
Delete the if case and make sure it won't be called again
in coroutines.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block.c | 37 ++++++++++++++++---------------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/block.c b/block.c
index e5e70acf15..1ee76a8694 100644
--- a/block.c
+++ b/block.c
@@ -557,30 +557,25 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
int bdrv_create(BlockDriver *drv, const char* filename,
QemuOpts *opts, Error **errp)
{
+ Coroutine *co;
+ CreateCo cco = {
+ .drv = drv,
+ .filename = g_strdup(filename),
+ .opts = opts,
+ .ret = NOT_DONE,
+ .err = NULL,
+ };
GLOBAL_STATE_CODE();
+ assert(!qemu_in_coroutine());
- if (qemu_in_coroutine()) {
- /* Fast-path if already in coroutine context */
- return bdrv_co_create(drv, filename, opts, errp);
- } else {
- Coroutine *co;
- CreateCo cco = {
- .drv = drv,
- .filename = g_strdup(filename),
- .opts = opts,
- .ret = NOT_DONE,
- .err = NULL,
- };
-
- co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
- qemu_coroutine_enter(co);
- while (cco.ret == NOT_DONE) {
- aio_poll(qemu_get_aio_context(), true);
- }
- error_propagate(errp, cco.err);
- g_free(cco.filename);
- return cco.ret;
+ co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
+ qemu_coroutine_enter(co);
+ while (cco.ret == NOT_DONE) {
+ aio_poll(qemu_get_aio_context(), true);
}
+ error_propagate(errp, cco.err);
+ g_free(cco.filename);
+ return cco.ret;
}
/**
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 9/9] block/dirty-bitmap: remove unnecessary qemu_in_coroutine() case
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
` (7 preceding siblings ...)
2022-11-03 13:42 ` [PATCH 8/9] block: bdrv_create is never called in non-coroutine context Emanuele Giuseppe Esposito
@ 2022-11-03 13:42 ` Emanuele Giuseppe Esposito
8 siblings, 0 replies; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-03 13:42 UTC (permalink / raw)
To: qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel, Emanuele Giuseppe Esposito
bdrv_can_store_new_dirty_bitmap and bdrv_remove_persistent_dirty_bitmap
check if they are running in a coroutine, directly calling the
coroutine callback if it's the case.
Except that no coroutine calls such functions, therefore that check
can be removed.
Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
---
block/dirty-bitmap.c | 66 +++++++++++++++++++-------------------------
1 file changed, 29 insertions(+), 37 deletions(-)
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index bf3dc0512a..8092d08261 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -418,24 +418,20 @@ bdrv_co_remove_persistent_dirty_bitmap_entry(void *opaque)
int bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name,
Error **errp)
{
- if (qemu_in_coroutine()) {
- return bdrv_co_remove_persistent_dirty_bitmap(bs, name, errp);
- } else {
- Coroutine *co;
- BdrvRemovePersistentDirtyBitmapCo s = {
- .bs = bs,
- .name = name,
- .errp = errp,
- .ret = -EINPROGRESS,
- };
-
- co = qemu_coroutine_create(bdrv_co_remove_persistent_dirty_bitmap_entry,
- &s);
- bdrv_coroutine_enter(bs, co);
- BDRV_POLL_WHILE(bs, s.ret == -EINPROGRESS);
-
- return s.ret;
- }
+ Coroutine *co;
+ BdrvRemovePersistentDirtyBitmapCo s = {
+ .bs = bs,
+ .name = name,
+ .errp = errp,
+ .ret = -EINPROGRESS,
+ };
+ assert(!qemu_in_coroutine());
+ co = qemu_coroutine_create(bdrv_co_remove_persistent_dirty_bitmap_entry,
+ &s);
+ bdrv_coroutine_enter(bs, co);
+ BDRV_POLL_WHILE(bs, s.ret == -EINPROGRESS);
+
+ return s.ret;
}
bool
@@ -494,25 +490,21 @@ bool bdrv_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name,
uint32_t granularity, Error **errp)
{
IO_CODE();
- if (qemu_in_coroutine()) {
- return bdrv_co_can_store_new_dirty_bitmap(bs, name, granularity, errp);
- } else {
- Coroutine *co;
- BdrvCanStoreNewDirtyBitmapCo s = {
- .bs = bs,
- .name = name,
- .granularity = granularity,
- .errp = errp,
- .in_progress = true,
- };
-
- co = qemu_coroutine_create(bdrv_co_can_store_new_dirty_bitmap_entry,
- &s);
- bdrv_coroutine_enter(bs, co);
- BDRV_POLL_WHILE(bs, s.in_progress);
-
- return s.ret;
- }
+ Coroutine *co;
+ BdrvCanStoreNewDirtyBitmapCo s = {
+ .bs = bs,
+ .name = name,
+ .granularity = granularity,
+ .errp = errp,
+ .in_progress = true,
+ };
+ assert(!qemu_in_coroutine());
+ co = qemu_coroutine_create(bdrv_co_can_store_new_dirty_bitmap_entry,
+ &s);
+ bdrv_coroutine_enter(bs, co);
+ BDRV_POLL_WHILE(bs, s.in_progress);
+
+ return s.ret;
}
void bdrv_disable_dirty_bitmap(BdrvDirtyBitmap *bitmap)
--
2.31.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-03 13:41 ` [PATCH 2/9] block-copy: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
@ 2022-11-03 16:56 ` Paolo Bonzini
2022-11-03 18:06 ` Kevin Wolf
0 siblings, 1 reply; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 16:56 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 14:41, Emanuele Giuseppe Esposito wrote:
> block_copy_reset_unallocated and block_copy_is_cluster_allocated are
> only called by backup_run, a corotuine_fn itself.
>
> Same applies to block_copy_block_status, called by
> block_copy_dirty_clusters.
>
> Therefore mark them as coroutine too.
>
> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
They don't need to be coroutine_fn. coroutine_fn is needed if you call
another coroutine_fn, but not if you _are only called_ by coroutine_fn.
There is nothing in these functions that needs them to be called from a
coroutine.
The only exception is qemu_coroutine_yield(), which is the only leaf
coroutine_fn.
Paolo
> ---
> block/block-copy.c | 15 +++++++++------
> 1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/block/block-copy.c b/block/block-copy.c
> index bb947afdda..f33ab1d0b6 100644
> --- a/block/block-copy.c
> +++ b/block/block-copy.c
> @@ -577,8 +577,9 @@ static coroutine_fn int block_copy_task_entry(AioTask *task)
> return ret;
> }
>
> -static int block_copy_block_status(BlockCopyState *s, int64_t offset,
> - int64_t bytes, int64_t *pnum)
> +static coroutine_fn int block_copy_block_status(BlockCopyState *s,
> + int64_t offset,
> + int64_t bytes, int64_t *pnum)
> {
> int64_t num;
> BlockDriverState *base;
> @@ -613,8 +614,9 @@ static int block_copy_block_status(BlockCopyState *s, int64_t offset,
> * Check if the cluster starting at offset is allocated or not.
> * return via pnum the number of contiguous clusters sharing this allocation.
> */
> -static int block_copy_is_cluster_allocated(BlockCopyState *s, int64_t offset,
> - int64_t *pnum)
> +static int coroutine_fn block_copy_is_cluster_allocated(BlockCopyState *s,
> + int64_t offset,
> + int64_t *pnum)
> {
> BlockDriverState *bs = s->source->bs;
> int64_t count, total_count = 0;
> @@ -669,8 +671,9 @@ void block_copy_reset(BlockCopyState *s, int64_t offset, int64_t bytes)
> * @return 0 when the cluster at @offset was unallocated,
> * 1 otherwise, and -ret on error.
> */
> -int64_t block_copy_reset_unallocated(BlockCopyState *s,
> - int64_t offset, int64_t *count)
> +int64_t coroutine_fn block_copy_reset_unallocated(BlockCopyState *s,
> + int64_t offset,
> + int64_t *count)
> {
> int ret;
> int64_t clusters, bytes;
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/9] nbd/server.c: add missing coroutine_fn annotations
2022-11-03 13:42 ` [PATCH 3/9] nbd/server.c: " Emanuele Giuseppe Esposito
@ 2022-11-03 16:58 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 16:58 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 14:42, Emanuele Giuseppe Esposito wrote:
> There are probably more missing, but right now it is necessary that
> we extend coroutine_fn to block{allock/status}_to_extents, because
> they use bdrv_* functions calling the generated_co_wrapper API, which
> checks for the qemu_in_coroutine() case.
>
> Signed-off-by: Emanuele Giuseppe Esposito<eesposit@redhat.com>
generated_co_wrappers should only be called from functions that are
*not* coroutine_fn. If they are coroutine_fn, they can call the
bdrv_co_* version directly.
See for example
https://patchew.org/QEMU/20221013123711.620631-1-pbonzini@redhat.com/20221013123711.620631-17-pbonzini@redhat.com/.
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/9] block/vmdk: add missing coroutine_fn annotations
2022-11-03 13:42 ` [PATCH 6/9] block/vmdk: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
@ 2022-11-03 17:00 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 17:00 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 14:42, Emanuele Giuseppe Esposito wrote:
> vmdk_co_create_opts() is a coroutine_fn, and calls vmdk_co_do_create()
> which in turn can call two callbacks: vmdk_co_create_opts_cb and
> vmdk_co_create_cb.
>
> Mark all these functions as coroutine_fn, since vmdk_co_create_opts()
> is the only caller.
>
> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
> ---
> block/vmdk.c | 36 +++++++++++++++++++-----------------
> 1 file changed, 19 insertions(+), 17 deletions(-)
>
> diff --git a/block/vmdk.c b/block/vmdk.c
> index 26376352b9..0c32bf2e83 100644
> --- a/block/vmdk.c
> +++ b/block/vmdk.c
> @@ -2285,10 +2285,11 @@ exit:
> return ret;
> }
>
> -static int vmdk_create_extent(const char *filename, int64_t filesize,
> - bool flat, bool compress, bool zeroed_grain,
> - BlockBackend **pbb,
> - QemuOpts *opts, Error **errp)
> +static int coroutine_fn vmdk_create_extent(const char *filename,
> + int64_t filesize, bool flat,
> + bool compress, bool zeroed_grain,
> + BlockBackend **pbb,
> + QemuOpts *opts, Error **errp)
> {
> int ret;
> BlockBackend *blk = NULL;
> @@ -2366,14 +2367,14 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
> * non-split format.
> * idx >= 1: get the n-th extent if in a split subformat
> */
> -typedef BlockBackend *(*vmdk_create_extent_fn)(int64_t size,
> - int idx,
> - bool flat,
> - bool split,
> - bool compress,
> - bool zeroed_grain,
> - void *opaque,
> - Error **errp);
> +typedef BlockBackend * coroutine_fn (*vmdk_create_extent_fn)(int64_t size,
> + int idx,
> + bool flat,
> + bool split,
> + bool compress,
> + bool zeroed_grain,
> + void *opaque,
> + Error **errp);
>
> static void vmdk_desc_add_extent(GString *desc,
> const char *extent_line_fmt,
> @@ -2616,7 +2617,7 @@ typedef struct {
> QemuOpts *opts;
> } VMDKCreateOptsData;
>
> -static BlockBackend *vmdk_co_create_opts_cb(int64_t size, int idx,
> +static BlockBackend * coroutine_fn vmdk_co_create_opts_cb(int64_t size, int idx,
> bool flat, bool split, bool compress,
> bool zeroed_grain, void *opaque,
> Error **errp)
> @@ -2768,10 +2769,11 @@ exit:
> return ret;
> }
>
> -static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
> - bool flat, bool split, bool compress,
> - bool zeroed_grain, void *opaque,
> - Error **errp)
> +static BlockBackend * coroutine_fn vmdk_co_create_cb(int64_t size, int idx,
> + bool flat, bool split,
> + bool compress,
> + bool zeroed_grain,
> + void *opaque, Error **errp)
> {
> int ret;
> BlockDriverState *bs;
Should not be needed either.
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 7/9] block: bdrv_create_file is a coroutine_fn
2022-11-03 13:42 ` [PATCH 7/9] block: bdrv_create_file is a coroutine_fn Emanuele Giuseppe Esposito
@ 2022-11-03 17:01 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 17:01 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 14:42, Emanuele Giuseppe Esposito wrote:
> It is always called in coroutine_fn callbacks, therefore
> it can directly call bdrv_co_create().
>
> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
> ---
> block.c | 6 ++++--
> include/block/block-global-state.h | 3 ++-
> 2 files changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/block.c b/block.c
> index eeb7a02aa2..e5e70acf15 100644
> --- a/block.c
> +++ b/block.c
> @@ -527,6 +527,7 @@ static int coroutine_fn bdrv_co_create(BlockDriver *drv, const char *filename,
> {
> int ret;
> GLOBAL_STATE_CODE();
> + assert(qemu_in_coroutine());
> assert(*errp == NULL);
>
> if (!drv->bdrv_co_create_opts) {
> @@ -717,7 +718,8 @@ out:
> return ret;
> }
>
> -int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
> +int coroutine_fn bdrv_create_file(const char *filename, QemuOpts *opts,
> + Error **errp)
> {
> QemuOpts *protocol_opts;
> BlockDriver *drv;
> @@ -758,7 +760,7 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
> goto out;
> }
>
> - ret = bdrv_create(drv, filename, protocol_opts, errp);
> + ret = bdrv_co_create(drv, filename, protocol_opts, errp);
> out:
> qemu_opts_del(protocol_opts);
> qobject_unref(qdict);
> diff --git a/include/block/block-global-state.h b/include/block/block-global-state.h
> index 73795a0095..bd461f06a1 100644
> --- a/include/block/block-global-state.h
> +++ b/include/block/block-global-state.h
> @@ -57,7 +57,8 @@ BlockDriver *bdrv_find_protocol(const char *filename,
> BlockDriver *bdrv_find_format(const char *format_name);
> int bdrv_create(BlockDriver *drv, const char* filename,
> QemuOpts *opts, Error **errp);
> -int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp);
> +int coroutine_fn bdrv_create_file(const char *filename, QemuOpts *opts,
> + Error **errp);
>
> BlockDriverState *bdrv_new(void);
> int bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top,
Ah, I see now why patch 6 is needed, but please adjust the commit message.
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine
2022-11-03 13:41 ` [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine Emanuele Giuseppe Esposito
@ 2022-11-03 17:05 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 17:05 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 14:41, Emanuele Giuseppe Esposito wrote:
> - for (i = 0; i < bs->quiesce_counter; i++) {
> - if (drv->bdrv_co_drain_begin) {
> - drv->bdrv_co_drain_begin(bs);
> - }
> + if (drv->bdrv_co_drain_begin) {
> + co = qemu_coroutine_create(bdrv_co_drain_begin, &dco);
> + qemu_coroutine_enter(co);
> + AIO_WAIT_WHILE(qemu_get_aio_context(), dco.ret == NOT_DONE);
> }
>
Alternatively there should be no reason for drv->bdrv_co_drain_begin to
wait at this point, because the device does not have any active I/O. So
you could also assert that the coroutine is terminated after
qemu_coroutine_enter(), i.e. that dco.ret != NOT_DONE.
Since you need to respin, perhaps put it the above in the commit message
in case this needs a change in the future; however your patch is simple
and should indeed work, so
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 8/9] block: bdrv_create is never called in non-coroutine context
2022-11-03 13:42 ` [PATCH 8/9] block: bdrv_create is never called in non-coroutine context Emanuele Giuseppe Esposito
@ 2022-11-03 17:05 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 17:05 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, qemu-block
Cc: Kevin Wolf, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 14:42, Emanuele Giuseppe Esposito wrote:
> Delete the if case and make sure it won't be called again
> in coroutines.
>
> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
> ---
> block.c | 37 ++++++++++++++++---------------------
> 1 file changed, 16 insertions(+), 21 deletions(-)
>
> diff --git a/block.c b/block.c
> index e5e70acf15..1ee76a8694 100644
> --- a/block.c
> +++ b/block.c
> @@ -557,30 +557,25 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
> int bdrv_create(BlockDriver *drv, const char* filename,
> QemuOpts *opts, Error **errp)
> {
> + Coroutine *co;
> + CreateCo cco = {
> + .drv = drv,
> + .filename = g_strdup(filename),
> + .opts = opts,
> + .ret = NOT_DONE,
> + .err = NULL,
> + };
> GLOBAL_STATE_CODE();
> + assert(!qemu_in_coroutine());
>
> - if (qemu_in_coroutine()) {
> - /* Fast-path if already in coroutine context */
> - return bdrv_co_create(drv, filename, opts, errp);
> - } else {
> - Coroutine *co;
> - CreateCo cco = {
> - .drv = drv,
> - .filename = g_strdup(filename),
> - .opts = opts,
> - .ret = NOT_DONE,
> - .err = NULL,
> - };
> -
> - co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
> - qemu_coroutine_enter(co);
> - while (cco.ret == NOT_DONE) {
> - aio_poll(qemu_get_aio_context(), true);
> - }
> - error_propagate(errp, cco.err);
> - g_free(cco.filename);
> - return cco.ret;
> + co = qemu_coroutine_create(bdrv_create_co_entry, &cco);
> + qemu_coroutine_enter(co);
> + while (cco.ret == NOT_DONE) {
> + aio_poll(qemu_get_aio_context(), true);
> }
> + error_propagate(errp, cco.err);
> + g_free(cco.filename);
> + return cco.ret;
> }
>
> /**
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-03 16:56 ` Paolo Bonzini
@ 2022-11-03 18:06 ` Kevin Wolf
2022-11-03 18:36 ` Paolo Bonzini
0 siblings, 1 reply; 23+ messages in thread
From: Kevin Wolf @ 2022-11-03 18:06 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Emanuele Giuseppe Esposito, qemu-block, Hanna Reitz, John Snow,
Vladimir Sementsov-Ogievskiy, Eric Blake, Fam Zheng, qemu-devel
Am 03.11.2022 um 17:56 hat Paolo Bonzini geschrieben:
> On 11/3/22 14:41, Emanuele Giuseppe Esposito wrote:
> > block_copy_reset_unallocated and block_copy_is_cluster_allocated are
> > only called by backup_run, a corotuine_fn itself.
s/corotuine_fn/coroutine_fn/
> >
> > Same applies to block_copy_block_status, called by
> > block_copy_dirty_clusters.
> >
> > Therefore mark them as coroutine too.
> >
> > Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
>
> They don't need to be coroutine_fn. coroutine_fn is needed if you call
> another coroutine_fn, but not if you _are only called_ by coroutine_fn.
> There is nothing in these functions that needs them to be called from a
> coroutine.
>
> The only exception is qemu_coroutine_yield(), which is the only leaf
> coroutine_fn.
I think it can make sense to have coroutine_fn as a documentation for
things that are only ever called in a coroutine even if they could
theoretically also work outside of coroutine context.
Otherwise, when we want to introduce a coroutine_fn call somewhere, it's
not only less obvious that it's even possible to do, but we'll have to
add potentially many additional coroutine_fn annotations in the whole
call chain in an otherwise unrelated patch.
Kevin
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-03 18:06 ` Kevin Wolf
@ 2022-11-03 18:36 ` Paolo Bonzini
2022-11-04 7:35 ` Emanuele Giuseppe Esposito
0 siblings, 1 reply; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-03 18:36 UTC (permalink / raw)
To: Kevin Wolf
Cc: Emanuele Giuseppe Esposito, qemu-block, Hanna Reitz, John Snow,
Vladimir Sementsov-Ogievskiy, Eric Blake, Fam Zheng, qemu-devel
On 11/3/22 19:06, Kevin Wolf wrote:
> I think it can make sense to have coroutine_fn as a documentation for
> things that are only ever called in a coroutine even if they could
> theoretically also work outside of coroutine context.
>
> Otherwise, when we want to introduce a coroutine_fn call somewhere, it's
> not only less obvious that it's even possible to do, but we'll have to
> add potentially many additional coroutine_fn annotations in the whole
> call chain in an otherwise unrelated patch.
This is true. On the other hand, coroutine_fn also means "this is
allowed to suspend", which may have implications on the need for locking
in the caller. So you need to judge case-by-case.
If there are good reasons to add the note, you could add an assertion
that you are qemu_in_coroutine(), which notes that you are in a
coroutine but you don't suspend. In this case however I don't think
it's likely that there will be a coroutine_fn call added later.
I guess I tend to err on the side of "it's good that it's not obvious
that you can call a coroutine_fn", but I also need to correct myself as
qemu_coroutine_yield() is not the only leaf; there is also
qemu_co_queue_next() and qemu_co_queue_restart_all(), which are
coroutine_fn because they rely on the queuing behavior of
aio_co_enter(). In this case I violated my own rule because it is
always a bug to call these functions outside coroutine context.
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-03 18:36 ` Paolo Bonzini
@ 2022-11-04 7:35 ` Emanuele Giuseppe Esposito
2022-11-04 8:44 ` Paolo Bonzini
0 siblings, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-04 7:35 UTC (permalink / raw)
To: Paolo Bonzini, Kevin Wolf
Cc: qemu-block, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
Am 03/11/2022 um 19:36 schrieb Paolo Bonzini:
> On 11/3/22 19:06, Kevin Wolf wrote:
>> I think it can make sense to have coroutine_fn as a documentation for
>> things that are only ever called in a coroutine even if they could
>> theoretically also work outside of coroutine context.
>>
>> Otherwise, when we want to introduce a coroutine_fn call somewhere, it's
>> not only less obvious that it's even possible to do, but we'll have to
>> add potentially many additional coroutine_fn annotations in the whole
>> call chain in an otherwise unrelated patch.
>
> This is true. On the other hand, coroutine_fn also means "this is
> allowed to suspend", which may have implications on the need for locking
> in the caller. So you need to judge case-by-case.
>
> If there are good reasons to add the note, you could add an assertion
> that you are qemu_in_coroutine(), which notes that you are in a
> coroutine but you don't suspend. In this case however I don't think
> it's likely that there will be a coroutine_fn call added later.
>
> I guess I tend to err on the side of "it's good that it's not obvious
> that you can call a coroutine_fn", but I also need to correct myself as
> qemu_coroutine_yield() is not the only leaf; there is also
> qemu_co_queue_next() and qemu_co_queue_restart_all(), which are
> coroutine_fn because they rely on the queuing behavior of
> aio_co_enter(). In this case I violated my own rule because it is
> always a bug to call these functions outside coroutine context.
>
But isn't it a bug also not to mark a function _only_ called by
coroutine_fn? My point is that if this function is an implementation of
a BlockDriver callback marked as coroutine_fn (like in patch 6 with
vmdk), then it would make sense.
This is actually the point of this serie (which I might not have
explained well in the cover letter), every function marked here is
eventually called by/calling a BlockDriver callback marked as coroutine_fn.
Currently we have something like this:
BlockDriver {
void coroutine_fn (*bdrv_A)(void) = implA;
}
void coroutine_fn implA() {
funcB();
funcC();
}
void funcB() {}; <--- missing coroutine_fn?
void funcC() {}; <--- missing coroutine_fn?
In addition, as I understand draining is not allowed in coroutines. If a
function/callback only running in coroutines is not marked as
coroutine_fn, then it will be less obvious to notice that draining is
not allowed there.
Emanuele
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-04 7:35 ` Emanuele Giuseppe Esposito
@ 2022-11-04 8:44 ` Paolo Bonzini
2022-11-04 9:20 ` Emanuele Giuseppe Esposito
2022-11-04 13:12 ` Kevin Wolf
0 siblings, 2 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-04 8:44 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, Kevin Wolf
Cc: qemu-block, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/4/22 08:35, Emanuele Giuseppe Esposito wrote:
> But isn't it a bug also not to mark a function _only_ called by
> coroutine_fn? My point is that if this function is an implementation of
> a BlockDriver callback marked as coroutine_fn (like in patch 6 with
> vmdk), then it would make sense.
If a function implements a coroutine_fn callback but does not suspend,
then it makes sense to mark it coroutine_fn.
In general it's not a bug. In most cases it would only be a coincidence
that the function is called from a coroutine_fn. For example consider
bdrv_round_to_clusters(). Marking it coroutine_fn signals that it may
suspend now (it doesn't) or in the future. However it's only doing some
math based on the result of bdrv_get_info(), so it is extremely unlikely
that this will happen.
In this case... oh wait. block_copy_is_cluster_allocated is calling
bdrv_is_allocated, and block_copy_reset_unallocated calls
block_copy_is_cluster_allocated. bdrv_is_allocated is a mixed
coroutine/non-coroutine function, and in this case it is useful to
document that bdrv_is_allocated will suspend. The patch is correct,
only the commit message is wrong.
Likewise for blockstatus_to_extents in patch 3, where the commit message
does mention bdrv_* functions. As I mentioned in my quick review of
patch 3, this can also snowball into a series of its own to clean up all
callees of bdrv_co_common_block_status_above, similar to what Alberto
did for read/write functions back in June, so that they are properly
marked as coroutine_fn. If you want to do it, don't do it by hand
though, you can use his static analyzer. It's slow but it's faster than
doing it by hand.
> This is actually the point of this serie (which I might not have
> explained well in the cover letter), every function marked here is
> eventually called by/calling a BlockDriver callback marked as coroutine_fn.
Again I don't think this is useful in general, but your three patches
(2/3/6) did catch cases that wants to be coroutine_fn. So my objection
is dropped with just a better commit message.
> Currently we have something like this:
> BlockDriver {
> void coroutine_fn (*bdrv_A)(void) = implA;
> }
>
> void coroutine_fn implA() {
> funcB();
> funcC();
> }
>
> void funcB() {}; <--- missing coroutine_fn?
> void funcC() {}; <--- missing coroutine_fn?
>
> In addition, as I understand draining is not allowed in coroutines.
... except we have bdrv_co_yield_to_drain() to allow that, sort of. :/
> If a function/callback only running in coroutines is not marked as
> coroutine_fn, then it will be less obvious to notice that draining is
> not allowed there.
I think it has to be judged case by base. Your patches prove that, in
most cases, you have coroutine_fn for things that ultimately do some
kind of I/O or query. In general the interesting path to explore is
"coroutine_fn calls (indirectly) non-coroutine_fn calls (indirectly)
generated_co_wrapper". The vrc tool could be extended to help finding
them, with commands like
label coroutine_fn bdrv_co_read
label coroutine_fn bdrv_co_write
...
label generated_co_wrapper bdrv_read
label generated_co_wrapper bdrv_write
paths coroutine_fn !coroutine_fn generated_co_wrapper
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-04 8:44 ` Paolo Bonzini
@ 2022-11-04 9:20 ` Emanuele Giuseppe Esposito
2022-11-04 13:16 ` Paolo Bonzini
2022-11-04 13:12 ` Kevin Wolf
1 sibling, 1 reply; 23+ messages in thread
From: Emanuele Giuseppe Esposito @ 2022-11-04 9:20 UTC (permalink / raw)
To: Paolo Bonzini, Kevin Wolf
Cc: qemu-block, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
Am 04/11/2022 um 09:44 schrieb Paolo Bonzini:
> On 11/4/22 08:35, Emanuele Giuseppe Esposito wrote:
>> But isn't it a bug also not to mark a function _only_ called by
>> coroutine_fn? My point is that if this function is an implementation of
>> a BlockDriver callback marked as coroutine_fn (like in patch 6 with
>> vmdk), then it would make sense.
>
> If a function implements a coroutine_fn callback but does not suspend,
> then it makes sense to mark it coroutine_fn.
>
> In general it's not a bug. In most cases it would only be a coincidence
> that the function is called from a coroutine_fn. For example consider
> bdrv_round_to_clusters(). Marking it coroutine_fn signals that it may
> suspend now (it doesn't) or in the future. However it's only doing some
> math based on the result of bdrv_get_info(), so it is extremely unlikely
> that this will happen.
>
> In this case... oh wait. block_copy_is_cluster_allocated is calling
> bdrv_is_allocated, and block_copy_reset_unallocated calls
> block_copy_is_cluster_allocated. bdrv_is_allocated is a mixed
> coroutine/non-coroutine function, and in this case it is useful to
> document that bdrv_is_allocated will suspend. The patch is correct,
> only the commit message is wrong.
[...]
>> This is actually the point of this serie (which I might not have
>> explained well in the cover letter), every function marked here is
>> eventually called by/calling a BlockDriver callback marked as
>> coroutine_fn.
>
> Again I don't think this is useful in general, but your three patches
> (2/3/6) did catch cases that wants to be coroutine_fn. So my objection
> is dropped with just a better commit message.
I see your point about "in general it's not a bug".
At this point I just want to make sure that we agree that it's correct
to add coroutine_fn because of "the function calls a g_c_w that
suspends" *&&* "all the callers are coroutine_fn". If the callers
weren't coroutine_fn then g_c_w would just create a new coroutine and
poll, and I don't think that would be part of your definition of "can
suspend".
Thank you,
Emanuele
>
>> Currently we have something like this:
>> BlockDriver {
>> void coroutine_fn (*bdrv_A)(void) = implA;
>> }
>>
>> void coroutine_fn implA() {
>> funcB();
>> funcC();
>> }
>>
>> void funcB() {}; <--- missing coroutine_fn?
>> void funcC() {}; <--- missing coroutine_fn?
>>
>> In addition, as I understand draining is not allowed in coroutines.
>
> ... except we have bdrv_co_yield_to_drain() to allow that, sort of. :/
>
>> If a function/callback only running in coroutines is not marked as
>> coroutine_fn, then it will be less obvious to notice that draining is
>> not allowed there.
>
> I think it has to be judged case by base. Your patches prove that, in
> most cases, you have coroutine_fn for things that ultimately do some
> kind of I/O or query. In general the interesting path to explore is
> "coroutine_fn calls (indirectly) non-coroutine_fn calls (indirectly)
> generated_co_wrapper". The vrc tool could be extended to help finding
> them, with commands like
>
> label coroutine_fn bdrv_co_read
> label coroutine_fn bdrv_co_write
> ...
> label generated_co_wrapper bdrv_read
> label generated_co_wrapper bdrv_write
> paths coroutine_fn !coroutine_fn generated_co_wrapper
>
> Paolo
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-04 8:44 ` Paolo Bonzini
2022-11-04 9:20 ` Emanuele Giuseppe Esposito
@ 2022-11-04 13:12 ` Kevin Wolf
1 sibling, 0 replies; 23+ messages in thread
From: Kevin Wolf @ 2022-11-04 13:12 UTC (permalink / raw)
To: Paolo Bonzini
Cc: Emanuele Giuseppe Esposito, qemu-block, Hanna Reitz, John Snow,
Vladimir Sementsov-Ogievskiy, Eric Blake, Fam Zheng, qemu-devel
Am 04.11.2022 um 09:44 hat Paolo Bonzini geschrieben:
> On 11/4/22 08:35, Emanuele Giuseppe Esposito wrote:
> > But isn't it a bug also not to mark a function _only_ called by
> > coroutine_fn? My point is that if this function is an implementation of
> > a BlockDriver callback marked as coroutine_fn (like in patch 6 with
> > vmdk), then it would make sense.
>
> If a function implements a coroutine_fn callback but does not suspend, then
> it makes sense to mark it coroutine_fn.
>
> In general it's not a bug. In most cases it would only be a coincidence
> that the function is called from a coroutine_fn. For example consider
> bdrv_round_to_clusters(). Marking it coroutine_fn signals that it may
> suspend now (it doesn't) or in the future. However it's only doing some
> math based on the result of bdrv_get_info(), so it is extremely unlikely
> that this will happen.
>
> In this case... oh wait. block_copy_is_cluster_allocated is calling
> bdrv_is_allocated, and block_copy_reset_unallocated calls
> block_copy_is_cluster_allocated. bdrv_is_allocated is a mixed
> coroutine/non-coroutine function, and in this case it is useful to document
> that bdrv_is_allocated will suspend. The patch is correct, only the commit
> message is wrong.
Ah, right, now I remember that this is what I had discussed with
Emanuele. I knew that there was a reason for it...
What we probably should really do is a bdrv_co_is_allocated() that
doesn't go through the mixed function, but directly calls
bdrv_co_common_block_status_above(). bdrv_is_allocated() is only a
smaller wrapper anyway, so it wouldn't duplicate much code.
I seem to remember that Emanuele had a few more bdrv_is_allocated()
calls that actually took the coroutine path and could use the same new
function.
Kevin
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] block-copy: add missing coroutine_fn annotations
2022-11-04 9:20 ` Emanuele Giuseppe Esposito
@ 2022-11-04 13:16 ` Paolo Bonzini
0 siblings, 0 replies; 23+ messages in thread
From: Paolo Bonzini @ 2022-11-04 13:16 UTC (permalink / raw)
To: Emanuele Giuseppe Esposito, Kevin Wolf
Cc: qemu-block, Hanna Reitz, John Snow, Vladimir Sementsov-Ogievskiy,
Eric Blake, Fam Zheng, qemu-devel
On 11/4/22 10:20, Emanuele Giuseppe Esposito wrote:
> At this point I just want to make sure that we agree that it's correct
> to add coroutine_fn because of "the function calls a g_c_w that
> suspends" *&&* "all the callers are coroutine_fn". If the callers
> weren't coroutine_fn then g_c_w would just create a new coroutine and
> poll, and I don't think that would be part of your definition of "can
> suspend".
Yes, we agree on that. The confusion was just on the commit message.
The even-better fix would be to also call coroutine_fn from
coroutine_fn, instead of calling mixed coroutine/non-coroutine functions
such as g_c_w functions. However, adding coroutine_fn *is* correct.
Paolo
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2022-11-04 13:18 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-03 13:41 [PATCH 0/9] Still more coroutine and various fixes in block layer Emanuele Giuseppe Esposito
2022-11-03 13:41 ` [PATCH 1/9] block: call bdrv_co_drain_begin in a coroutine Emanuele Giuseppe Esposito
2022-11-03 17:05 ` Paolo Bonzini
2022-11-03 13:41 ` [PATCH 2/9] block-copy: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
2022-11-03 16:56 ` Paolo Bonzini
2022-11-03 18:06 ` Kevin Wolf
2022-11-03 18:36 ` Paolo Bonzini
2022-11-04 7:35 ` Emanuele Giuseppe Esposito
2022-11-04 8:44 ` Paolo Bonzini
2022-11-04 9:20 ` Emanuele Giuseppe Esposito
2022-11-04 13:16 ` Paolo Bonzini
2022-11-04 13:12 ` Kevin Wolf
2022-11-03 13:42 ` [PATCH 3/9] nbd/server.c: " Emanuele Giuseppe Esposito
2022-11-03 16:58 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 4/9] block-backend: replace bdrv_*_above with blk_*_above Emanuele Giuseppe Esposito
2022-11-03 13:42 ` [PATCH 5/9] block: distinguish between bdrv_create running in coroutine and not Emanuele Giuseppe Esposito
2022-11-03 13:42 ` [PATCH 6/9] block/vmdk: add missing coroutine_fn annotations Emanuele Giuseppe Esposito
2022-11-03 17:00 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 7/9] block: bdrv_create_file is a coroutine_fn Emanuele Giuseppe Esposito
2022-11-03 17:01 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 8/9] block: bdrv_create is never called in non-coroutine context Emanuele Giuseppe Esposito
2022-11-03 17:05 ` Paolo Bonzini
2022-11-03 13:42 ` [PATCH 9/9] block/dirty-bitmap: remove unnecessary qemu_in_coroutine() case Emanuele Giuseppe Esposito
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).