From 218e9c5723043b3c21766b64ea3e3c5d9cb7b961 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Thu, 25 Jul 2024 16:37:06 +0200 Subject: [PATCH] Revert "cleaner: Remove complete_queue" This functionality is used by cleaning policies via cmpl_queue to reschedule the completion, so that we avoid unlocking mutex in the cleaner completion from interrupt context of IO completion. This reverts commit 1e5eda68a7e1abb7e9c6bdfa6c5d2a4f940681dc. Signed-off-by: Robert Baldyga --- src/ocf_request.h | 3 +++ src/utils/utils_cleaner.c | 28 +++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/ocf_request.h b/src/ocf_request.h index d03a4789..5e05139f 100644 --- a/src/ocf_request.h +++ b/src/ocf_request.h @@ -195,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 7346e2c6..65112e59 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -104,6 +104,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); @@ -177,6 +178,17 @@ 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 void _ocf_cleaner_complete_req(struct ocf_request *req) { struct ocf_request *master = NULL; @@ -203,12 +215,18 @@ 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 priv */ - cmpl = master->master_io_req; - cmpl(master->priv, master->error); + if (master->complete_queue) { + ocf_req_get(master); + ocf_engine_push_req_front_cb(master, + _ocf_cleaner_complete, true); + } else { + /* Only master contains completion function and priv */ + cmpl = master->master_io_req; + cmpl(master->priv, master->error); - /* For additional get on master allocation */ - ocf_req_put(master); + /* For additional get on master allocation */ + ocf_req_put(master); + } } static void _ocf_cleaner_on_resume(struct ocf_request *req)