summaryrefslogtreecommitdiffstats
path: root/block.c
diff options
context:
space:
mode:
authorEmanuele Giuseppe Esposito2022-10-25 10:49:45 +0200
committerKevin Wolf2022-10-27 20:14:11 +0200
commite08cc001d502958040565636e19a42c06e1ae8b7 (patch)
treed775af529b1d7d598993d80c95ad1a30907d6a47 /block.c
parentblock: use transactions as a replacement of ->{can_}set_aio_context() (diff)
downloadqemu-e08cc001d502958040565636e19a42c06e1ae8b7.tar.gz
qemu-e08cc001d502958040565636e19a42c06e1ae8b7.tar.xz
qemu-e08cc001d502958040565636e19a42c06e1ae8b7.zip
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>
Diffstat (limited to 'block.c')
-rw-r--r--block.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/block.c b/block.c
index 38e5d831ca..59319d9b0f 100644
--- a/block.c
+++ b/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.