bdrv_change_aio_context: use hash table instead of list of visited nodes
Minor performance improvement, but given that we have hash tables available, avoid iterating in the visited nodes list every time just to check if a node has been already visited. The data structure is not actually a proper hash map, but an hash set, as we are just adding nodes and not key,value pairs. Suggested-by: Hanna Reitz <hreitz@redhat.com> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-Id: <20221025084952.2139888-4-eesposit@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
7e8c182fb5
commit
e08cc001d5
28
block.c
28
block.c
@ -105,7 +105,7 @@ static void bdrv_reopen_abort(BDRVReopenState *reopen_state);
|
||||
static bool bdrv_backing_overridden(BlockDriverState *bs);
|
||||
|
||||
static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
GSList **visited, Transaction *tran,
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp);
|
||||
|
||||
/* If non-zero, use only whitelisted block drivers */
|
||||
@ -7315,14 +7315,15 @@ typedef struct BdrvStateSetAioContext {
|
||||
} BdrvStateSetAioContext;
|
||||
|
||||
static bool bdrv_parent_change_aio_context(BdrvChild *c, AioContext *ctx,
|
||||
GSList **visited, Transaction *tran,
|
||||
GHashTable *visited,
|
||||
Transaction *tran,
|
||||
Error **errp)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
if (g_slist_find(*visited, c)) {
|
||||
if (g_hash_table_contains(visited, c)) {
|
||||
return true;
|
||||
}
|
||||
*visited = g_slist_prepend(*visited, c);
|
||||
g_hash_table_add(visited, c);
|
||||
|
||||
/*
|
||||
* A BdrvChildClass that doesn't handle AioContext changes cannot
|
||||
@ -7353,14 +7354,14 @@ bool bdrv_child_can_set_aio_context(BdrvChild *c, AioContext *ctx,
|
||||
}
|
||||
|
||||
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
|
||||
GSList **visited, Transaction *tran,
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp)
|
||||
{
|
||||
GLOBAL_STATE_CODE();
|
||||
if (g_slist_find(*visited, c)) {
|
||||
if (g_hash_table_contains(visited, c)) {
|
||||
return true;
|
||||
}
|
||||
*visited = g_slist_prepend(*visited, c);
|
||||
g_hash_table_add(visited, c);
|
||||
return bdrv_change_aio_context(c->bs, ctx, visited, tran, errp);
|
||||
}
|
||||
|
||||
@ -7445,7 +7446,7 @@ static TransactionActionDrv set_aio_context = {
|
||||
* responsible for freeing the list afterwards.
|
||||
*/
|
||||
static bool bdrv_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
GSList **visited, Transaction *tran,
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp)
|
||||
{
|
||||
BdrvChild *c;
|
||||
@ -7524,7 +7525,7 @@ int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
BdrvChild *ignore_child, Error **errp)
|
||||
{
|
||||
Transaction *tran;
|
||||
GSList *visited;
|
||||
GHashTable *visited;
|
||||
int ret;
|
||||
AioContext *old_context = bdrv_get_aio_context(bs);
|
||||
GLOBAL_STATE_CODE();
|
||||
@ -7536,9 +7537,12 @@ int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
* is successful (the transaction itself).
|
||||
*/
|
||||
tran = tran_new();
|
||||
visited = ignore_child ? g_slist_prepend(NULL, ignore_child) : NULL;
|
||||
ret = bdrv_change_aio_context(bs, ctx, &visited, tran, errp);
|
||||
g_slist_free(visited);
|
||||
visited = g_hash_table_new(NULL, NULL);
|
||||
if (ignore_child) {
|
||||
g_hash_table_add(visited, ignore_child);
|
||||
}
|
||||
ret = bdrv_change_aio_context(bs, ctx, visited, tran, errp);
|
||||
g_hash_table_destroy(visited);
|
||||
|
||||
/*
|
||||
* Linear phase: go through all callbacks collected in the transaction.
|
||||
|
@ -233,7 +233,7 @@ bool bdrv_can_set_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
AioContext *bdrv_child_get_parent_aio_context(BdrvChild *c);
|
||||
|
||||
bool bdrv_child_change_aio_context(BdrvChild *c, AioContext *ctx,
|
||||
GSList **visited, Transaction *tran,
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp);
|
||||
int bdrv_child_try_change_aio_context(BlockDriverState *bs, AioContext *ctx,
|
||||
BdrvChild *ignore_child, Error **errp);
|
||||
|
@ -911,7 +911,8 @@ struct BdrvChildClass {
|
||||
void (*set_aio_ctx)(BdrvChild *child, AioContext *ctx, GSList **ignore);
|
||||
|
||||
bool (*change_aio_ctx)(BdrvChild *child, AioContext *ctx,
|
||||
GSList **visited, Transaction *tran, Error **errp);
|
||||
GHashTable *visited, Transaction *tran,
|
||||
Error **errp);
|
||||
|
||||
AioContext *(*get_parent_aio_context)(BdrvChild *child);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user