From dca97692988cc3192c470142f34cbb45ea7ee601 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Mon, 23 Mar 2020 06:29:15 -0400 Subject: [PATCH] Acquire read lock for flushing cache Read lock allows to retrieve informations about flushing progress and printing progress bar during changing cache mode. Flushing dirty data during changing cache mode is done twice - first flush might be interrupted by user and the second one, called with write lock acquired, is uninterruptable. Signed-off-by: Michal Mielewczyk --- modules/cas_cache/layer_cache_management.c | 69 +++++++++++++++++----- ocf | 2 +- 2 files changed, 54 insertions(+), 17 deletions(-) diff --git a/modules/cas_cache/layer_cache_management.c b/modules/cas_cache/layer_cache_management.c index 0a55b87..b4b8219 100644 --- a/modules/cas_cache/layer_cache_management.c +++ b/modules/cas_cache/layer_cache_management.c @@ -2026,6 +2026,26 @@ int cache_mngt_get_seq_cutoff_policy(ocf_core_t core, return result; } +static int _cache_flush_with_lock(ocf_cache_t cache) +{ + int result = 0; + + result = ocf_mngt_cache_get(cache); + if (result) + return result; + + result = _cache_mngt_read_lock_sync(cache); + if (result) { + ocf_mngt_cache_put(cache); + return result; + } + + result = _cache_mngt_cache_flush_sync(cache, true, + _cache_read_unlock_put_cmpl); + + return result; +} + /** * @brief routine implementing dynamic cache mode switching * @param cache_name name of cache to which operation applies @@ -2045,32 +2065,49 @@ int cache_mngt_set_cache_mode(const char *cache_name, size_t name_len, if (result) return result; - result = _cache_mngt_lock_sync(cache); - if (result) { - ocf_mngt_cache_put(cache); - return result; + old_mode = ocf_cache_get_mode(cache); + if (old_mode == mode) { + printk(KERN_INFO "%s is in requested cache mode already\n", cache_name); + result = 0; + goto put; } - old_mode = ocf_cache_get_mode(cache); + if (flush) { + result = _cache_flush_with_lock(cache); + if (result) + goto put; + } + + result = _cache_mngt_lock_sync(cache); + if (result) + goto put; + + if (old_mode != ocf_cache_get_mode(cache)) { + printk(KERN_WARNING "%s cache mode changed during flush\n", + ocf_cache_get_name(cache)); + goto unlock; + } + + if (flush) { + result = _cache_mngt_cache_flush_uninterruptible(cache); + if (result) + goto unlock; + } result = ocf_mngt_cache_set_mode(cache, mode); if (result) - goto out; - - if (flush) { - result = _cache_mngt_cache_flush_sync(cache, true, NULL); - if (result) { - ocf_mngt_cache_set_mode(cache, old_mode); - goto out; - } - } + goto unlock; result = _cache_mngt_save_sync(cache); - if (result) + if (result) { + printk(KERN_ERR "%s: Failed to save new cache mode. " + "Restoring old one!\n", cache_name); ocf_mngt_cache_set_mode(cache, old_mode); + } -out: +unlock: ocf_mngt_cache_unlock(cache); +put: ocf_mngt_cache_put(cache); return result; } diff --git a/ocf b/ocf index ed91895..86d7212 160000 --- a/ocf +++ b/ocf @@ -1 +1 @@ -Subproject commit ed91895f705ed2a034e96d9a577c07a2e86f1b4a +Subproject commit 86d7212217d2ed2a5d5be55d4995a1f02cc4eb94