diff --git a/src/cleaning/acp.c b/src/cleaning/acp.c index 841bf476..7cf964f7 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 3d3de778..e4e1d51a 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 47252903..5e05139f 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 dcca1aa6..f9fbe51b 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 005a4916..f92d57c4 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 */