From 97ee3af8f7b5e6e4daee95c51114f434130b8e20 Mon Sep 17 00:00:00 2001 From: Rafal Stefanowski Date: Mon, 23 Sep 2024 12:13:33 +0200 Subject: [PATCH] Use management queue for parallelized management operations When IO queues are used for parallelized management operations, e.g. changing cleaning policy, a deadlock may occur due to global metadata lock interfering with taking request from IO queue, as they might be run on the same thread. As a workaround using a management queue specifically for such operations eliminates this problem. Signed-off-by: Rafal Stefanowski --- src/cleaning/acp.c | 3 ++- src/cleaning/alru.c | 3 ++- src/metadata/metadata.c | 5 +++-- src/mngt/ocf_mngt_cache.c | 2 +- src/ocf_lru.c | 2 +- src/utils/utils_parallelize.c | 5 +++-- src/utils/utils_parallelize.h | 4 +++- 7 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/cleaning/acp.c b/src/cleaning/acp.c index 26725626..4513cf48 100644 --- a/src/cleaning/acp.c +++ b/src/cleaning/acp.c @@ -435,7 +435,8 @@ void cleaning_policy_acp_populate(ocf_cache_t cache, result = ocf_parallelize_create(¶llelize, cache, OCF_ACP_POPULATE_SHARDS_CNT, sizeof(*context), - ocf_acp_populate_handle, ocf_acp_populate_finish); + ocf_acp_populate_handle, ocf_acp_populate_finish, + true); if (result) { cmpl(priv, result); return; diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index 6bc6f4e1..f66c6646 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -547,7 +547,8 @@ void cleaning_policy_alru_populate(ocf_cache_t cache, result = ocf_parallelize_create(¶llelize, cache, OCF_ALRU_POPULATE_SHARDS_CNT, sizeof(*context), - ocf_alru_populate_handle, ocf_alru_populate_finish); + ocf_alru_populate_handle, ocf_alru_populate_finish, + true); if (result) { cmpl(priv, result); return; diff --git a/src/metadata/metadata.c b/src/metadata/metadata.c index 96a9aeb3..6df8848c 100644 --- a/src/metadata/metadata.c +++ b/src/metadata/metadata.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -882,7 +883,7 @@ void ocf_metadata_init_collision(ocf_pipeline_t pipeline, void *priv, result = ocf_parallelize_create(¶llelize, cache, ocf_cache_get_queue_count(cache), sizeof(*context), ocf_metadata_init_collision_handle, - ocf_metadata_init_finish); + ocf_metadata_init_finish, false); if (result) OCF_PL_FINISH_RET(pipeline, result); @@ -934,7 +935,7 @@ void ocf_metadata_init_hash_table(ocf_pipeline_t pipeline, void *priv, result = ocf_parallelize_create(¶llelize, cache, ocf_cache_get_queue_count(cache), sizeof(*context), ocf_metadata_init_hash_table_handle, - ocf_metadata_init_finish); + ocf_metadata_init_finish, false); if (result) OCF_PL_FINISH_RET(pipeline, result); diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 64cbf32b..41cf6986 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -672,7 +672,7 @@ static void ocf_mngt_rebuild_metadata(ocf_cache_t cache, result = ocf_parallelize_create(¶llelize, cache, OCF_MNGT_REBUILD_METADATA_SHARDS_CNT, sizeof(*context), ocf_mngt_rebuild_metadata_handle, - ocf_mngt_rebuild_metadata_finish); + ocf_mngt_rebuild_metadata_finish, false); if (result) { cmpl(priv, result); return; diff --git a/src/ocf_lru.c b/src/ocf_lru.c index 16eaa740..66c14d9b 100644 --- a/src/ocf_lru.c +++ b/src/ocf_lru.c @@ -930,7 +930,7 @@ void ocf_lru_populate(ocf_cache_t cache, result = ocf_parallelize_create(¶llelize, cache, OCF_NUM_LRU_LISTS, sizeof(*context), ocf_lru_populate_handle, - ocf_lru_populate_finish); + ocf_lru_populate_finish, false); if (result) { cmpl(priv, result); return; diff --git a/src/utils/utils_parallelize.c b/src/utils/utils_parallelize.c index 53160d32..3e5bfbc7 100644 --- a/src/utils/utils_parallelize.c +++ b/src/utils/utils_parallelize.c @@ -59,7 +59,8 @@ static int _ocf_parallelize_hndl(struct ocf_request *req) int ocf_parallelize_create(ocf_parallelize_t *parallelize, ocf_cache_t cache, unsigned shards_cnt, uint32_t priv_size, ocf_parallelize_handle_t handle, - ocf_parallelize_finish_t finish) + ocf_parallelize_finish_t finish, + bool use_mngt_queue) { ocf_parallelize_t tmp_parallelize; struct list_head *iter; @@ -97,7 +98,7 @@ int ocf_parallelize_create(ocf_parallelize_t *parallelize, iter = cache->io_queues.next; for (i = 0; i < shards_cnt; i++) { - if (queue_count > 0) { + if (queue_count > 0 && !use_mngt_queue) { queue = list_entry(iter, struct ocf_queue, list); iter = iter->next; if (iter == &cache->io_queues) diff --git a/src/utils/utils_parallelize.h b/src/utils/utils_parallelize.h index 0066ef41..8b6f2878 100644 --- a/src/utils/utils_parallelize.h +++ b/src/utils/utils_parallelize.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2022 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +20,8 @@ typedef void (*ocf_parallelize_finish_t)(ocf_parallelize_t parallelize, int ocf_parallelize_create(ocf_parallelize_t *parallelize, ocf_cache_t cache, unsigned shards_cnt, uint32_t priv_size, ocf_parallelize_handle_t handle, - ocf_parallelize_finish_t finish); + ocf_parallelize_finish_t finish, + bool use_mngt_queue); void ocf_parallelize_destroy(ocf_parallelize_t parallelize);