From 244712b0206584a1d24267cc41f917efee1a731c Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 7 Dec 2021 11:06:57 +0100 Subject: [PATCH 1/3] Prevent race condition in fast path Request submitted in fast path may be freed before the sequential cutoff stats are updated. Increment request reference counter to prevent it. Signed-off-by: Michal Mielewczyk --- src/ocf_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ocf_core.c b/src/ocf_core.c index 0c327f6..a1fcc54 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -302,12 +302,16 @@ void ocf_core_volume_submit_io(struct ocf_io *io) ocf_core_update_stats(core, io); ocf_io_get(io); + /* Prevent race condition */ + ocf_req_get(req); if (!ocf_core_submit_io_fast(io, req, core, cache)) { ocf_core_seq_cutoff_update(core, req); + ocf_req_put(req); return; } + ocf_req_put(req); ocf_req_clear_map(req); ocf_core_seq_cutoff_update(core, req); From 655f73274808bfb8fbc4fa2aca4bb047e7665547 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 8 Dec 2021 08:50:58 +0100 Subject: [PATCH 2/3] Don't access freed memory Instead of accessing memory of a freed IO, redo size calculations Signed-off-by: Michal Mielewczyk --- src/metadata/metadata_raw_dynamic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/metadata/metadata_raw_dynamic.c b/src/metadata/metadata_raw_dynamic.c index 42887f9..a776384 100644 --- a/src/metadata/metadata_raw_dynamic.c +++ b/src/metadata/metadata_raw_dynamic.c @@ -332,6 +332,8 @@ int raw_dynamic_update(ocf_cache_t cache, * RAM DYNAMIC Implementation - Load all */ #define RAW_DYNAMIC_LOAD_PAGES 128 +#define metadata_io_size(__i_page, __pages_total) \ + OCF_MIN(RAW_DYNAMIC_LOAD_PAGES, (__pages_total -__i_page)) struct raw_dynamic_load_all_context { struct ocf_metadata_raw *raw; @@ -389,8 +391,7 @@ static int raw_dynamic_load_all_read(struct ocf_request *req) uint64_t count; int result; - count = OCF_MIN(RAW_DYNAMIC_LOAD_PAGES, - raw->ssd_pages - context->i_page); + count = metadata_io_size(context->i_page, raw->ssd_pages); /* Allocate IO */ context->io = ocf_new_cache_io(context->cache, req->io_queue, @@ -428,7 +429,7 @@ static int raw_dynamic_load_all_update(struct ocf_request *req) struct raw_dynamic_load_all_context *context = req->priv; struct ocf_metadata_raw *raw = context->raw; ocf_cache_t cache = context->cache; - uint64_t count = BYTES_TO_PAGES(context->io->bytes); + uint64_t count = metadata_io_size(context->i_page, raw->ssd_pages); int result = 0; /* Reset head of data buffer */ From 911a5cddf04ee722499e870788fc035963cccf0d Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 7 Dec 2021 11:12:57 +0100 Subject: [PATCH 3/3] Deinit all registered volume types Signed-off-by: Michal Mielewczyk --- src/ocf_ctx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ocf_ctx.c b/src/ocf_ctx.c index d93d790..51e7e4c 100644 --- a/src/ocf_ctx.c +++ b/src/ocf_ctx.c @@ -84,7 +84,7 @@ void ocf_ctx_unregister_volume_type(ocf_ctx_t ctx, uint8_t type_id) { OCF_CHECK_NULL(ctx); - if (type_id < OCF_VOLUME_TYPE_MAX_USER) + if (type_id < OCF_VOLUME_TYPE_MAX) ocf_ctx_unregister_volume_type_internal(ctx, type_id); }