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:
parent
ac2ae233a0
commit
de90329889
@ -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"
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}}
|
}}
|
||||||
|
Loading…
Reference in New Issue
Block a user