From 23984126225dfc23d43928a77f1334927ad13c4a Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Thu, 21 Mar 2024 15:10:03 +0100 Subject: [PATCH] cleaner: Unlock cache mngt lock from queue context Cache mngt lock cannot be unlocked from io completion context (which is potentially atomic context) as it may involve sleeping operations. Modify cleaner utility to support rescheduling to queue context before calling the completion. Update cleaning policies to use that option. Signed-off-by: Robert Baldyga --- src/cleaning/acp.c | 2 ++ src/cleaning/alru.c | 2 ++ src/ocf_request.h | 4 ++++ src/utils/utils_cleaner.c | 30 +++++++++++++++++++++++++++--- src/utils/utils_cleaner.h | 3 +++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/cleaning/acp.c b/src/cleaning/acp.c index 841bf47..7cf964f 100644 --- a/src/cleaning/acp.c +++ b/src/cleaning/acp.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -652,6 +653,7 @@ static void _acp_flush(struct acp_context *acp) .lock_cacheline = false, .lock_metadata = true, .do_sort = false, + .cmpl_queue = true, .io_queue = cache->cleaner.io_queue, }; diff --git a/src/cleaning/alru.c b/src/cleaning/alru.c index 3d3de77..e4e1d51 100644 --- a/src/cleaning/alru.c +++ b/src/cleaning/alru.c @@ -1,6 +1,7 @@ /* * Copyright(c) 2012-2022 Intel Corporation * Copyright(c) 2022 David Lee + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -941,6 +942,7 @@ void cleaning_alru_perform_cleaning(ocf_cache_t cache, ocf_cleaner_end_t cmpl) fctx->attribs.lock_metadata = false; fctx->attribs.do_sort = true; fctx->attribs.io_queue = cache->cleaner.io_queue; + fctx->attribs.cmpl_queue = true; fctx->clines_no = config->flush_max_buffers; fctx->cache = cache; diff --git a/src/ocf_request.h b/src/ocf_request.h index 4725290..5e05139 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -194,6 +195,9 @@ struct ocf_request { uint8_t part_evict : 1; /* !< Some cachelines from request's partition must be evicted */ + uint8_t complete_queue : 1; + /* !< Request needs to be completed from the queue context */ + uint8_t lock_idx : OCF_METADATA_GLOBAL_LOCK_IDX_BITS; /* !< Selected global metadata read lock */ diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index dcca1aa..f9fbe51 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2022 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -85,6 +86,7 @@ static struct ocf_request *_ocf_cleaner_alloc_master_req( /* In master, save completion context and function */ req->priv = attribs->cmpl_context; req->master_io_req = attribs->cmpl_fn; + req->complete_queue = attribs->cmpl_queue; /* The count of all requests */ env_atomic_set(&req->master_remaining, 1); @@ -167,6 +169,22 @@ static void _ocf_cleaner_set_error(struct ocf_request *req) master->error = -OCF_ERR_IO; } +static int _ocf_cleaner_complete(struct ocf_request *master) +{ + ocf_req_end_t cmpl; + + cmpl = master->master_io_req; + cmpl(master->priv, master->error); + ocf_req_put(master); + + return 0; +} + +static const struct ocf_io_if _io_if_cleaner_complete = { + .read = _ocf_cleaner_complete, + .write = _ocf_cleaner_complete, +}; + static void _ocf_cleaner_complete_req(struct ocf_request *req) { struct ocf_request *master = NULL; @@ -193,9 +211,15 @@ static void _ocf_cleaner_complete_req(struct ocf_request *req) OCF_DEBUG_MSG(req->cache, "All cleaning request completed"); - /* Only master contains completion function and completion context */ - cmpl = master->master_io_req; - cmpl(master->priv, master->error); + if (master->complete_queue) { + ocf_req_get(master); + ocf_engine_push_req_front_if(master, + &_io_if_cleaner_complete, true); + } else { + /* Only master contains completion function and priv */ + cmpl = master->master_io_req; + cmpl(master->priv, master->error); + } } static void _ocf_cleaner_on_resume(struct ocf_request *req) diff --git a/src/utils/utils_cleaner.h b/src/utils/utils_cleaner.h index 005a491..f92d57c 100644 --- a/src/utils/utils_cleaner.h +++ b/src/utils/utils_cleaner.h @@ -1,5 +1,6 @@ /* * Copyright(c) 2012-2021 Intel Corporation + * Copyright(c) 2024 Huawei Technologies * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,6 +31,8 @@ struct ocf_cleaner_attribs { uint8_t lock_metadata : 1; /*!< Cleaner to lock metadata on its own */ uint8_t do_sort : 1; /*!< Sort cache lines which will be cleaned */ + uint8_t cmpl_queue : 1; + /*!< Completion needs to be called from the queue context */ uint32_t count; /*!< max number of cache lines to be cleaned */