block-coroutine-wrapper: Add no_co_wrapper_bdrv_wrlock functions

Add a new wrapper type for GRAPH_WRLOCK functions that should be called
from coroutine context.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-ID: <20230911094620.45040-7-kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Kevin Wolf 2023-09-11 11:46:05 +02:00
parent ac2ae233a0
commit de90329889
2 changed files with 15 additions and 0 deletions

View File

@ -66,10 +66,14 @@
* function. The coroutine yields after scheduling the BH and is reentered when * function. The coroutine yields after scheduling the BH and is reentered when
* the wrapped function returns. * the wrapped function returns.
* *
* A no_co_wrapper_bdrv_wrlock function is a no_co_wrapper function that
* automatically takes the graph wrlock when calling the wrapped function.
*
* If the first parameter of the function is a BlockDriverState, BdrvChild or * If the first parameter of the function is a BlockDriverState, BdrvChild or
* BlockBackend pointer, the AioContext lock for it is taken in the wrapper. * BlockBackend pointer, the AioContext lock for it is taken in the wrapper.
*/ */
#define no_co_wrapper #define no_co_wrapper
#define no_co_wrapper_bdrv_wrlock
#include "block/blockjob.h" #include "block/blockjob.h"

View File

@ -71,10 +71,13 @@ class FuncDecl:
self.args = [ParamDecl(arg.strip()) for arg in args.split(',')] self.args = [ParamDecl(arg.strip()) for arg in args.split(',')]
self.create_only_co = 'mixed' not in variant self.create_only_co = 'mixed' not in variant
self.graph_rdlock = 'bdrv_rdlock' in variant self.graph_rdlock = 'bdrv_rdlock' in variant
self.graph_wrlock = 'bdrv_wrlock' in variant
self.wrapper_type = wrapper_type self.wrapper_type = wrapper_type
if wrapper_type == 'co': if wrapper_type == 'co':
if self.graph_wrlock:
raise ValueError(f"co function can't be wrlock: {self.name}")
subsystem, subname = self.name.split('_', 1) subsystem, subname = self.name.split('_', 1)
self.target_name = f'{subsystem}_co_{subname}' self.target_name = f'{subsystem}_co_{subname}'
else: else:
@ -250,6 +253,12 @@ def gen_no_co_wrapper(func: FuncDecl) -> str:
name = func.target_name name = func.target_name
struct_name = func.struct_name struct_name = func.struct_name
graph_lock=''
graph_unlock=''
if func.graph_wrlock:
graph_lock=' bdrv_graph_wrlock(NULL);'
graph_unlock=' bdrv_graph_wrunlock();'
return f"""\ return f"""\
/* /*
* Wrappers for {name} * Wrappers for {name}
@ -266,9 +275,11 @@ static void {name}_bh(void *opaque)
{struct_name} *s = opaque; {struct_name} *s = opaque;
AioContext *ctx = {func.gen_ctx('s->')}; AioContext *ctx = {func.gen_ctx('s->')};
{graph_lock}
aio_context_acquire(ctx); aio_context_acquire(ctx);
{func.get_result}{name}({ func.gen_list('s->{name}') }); {func.get_result}{name}({ func.gen_list('s->{name}') });
aio_context_release(ctx); aio_context_release(ctx);
{graph_unlock}
aio_co_wake(s->co); aio_co_wake(s->co);
}} }}