Merge pull request #363 from mmichal10/change-cachemode-with-progressbar

Show progress bar during changing cache mode
This commit is contained in:
Robert Baldyga 2020-03-27 09:14:22 +01:00 committed by GitHub
commit d7acbac253
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 88 additions and 46 deletions

View File

@ -245,6 +245,13 @@ static void _cache_mngt_cache_flush_complete(ocf_cache_t cache, void *priv,
kfree(context); kfree(context);
} }
/*
* Possible return values:
* 0 - completion was called and operation succeded
* -KCAS_ERR_WAITING_INTERRUPTED - operation was canceled, caller must
* propagate error, completion will be called asynchronously
* other values - completion was called and operation failed
*/
static int _cache_mngt_cache_flush_sync(ocf_cache_t cache, bool interruption, static int _cache_mngt_cache_flush_sync(ocf_cache_t cache, bool interruption,
void (*compl)(ocf_cache_t cache)) void (*compl)(ocf_cache_t cache))
{ {
@ -253,8 +260,11 @@ static int _cache_mngt_cache_flush_sync(ocf_cache_t cache, bool interruption,
struct cache_priv *cache_priv = ocf_cache_get_priv(cache); struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
context = kmalloc(sizeof(*context), GFP_KERNEL); context = kmalloc(sizeof(*context), GFP_KERNEL);
if (!context) if (!context) {
if (compl)
compl(cache);
return -ENOMEM; return -ENOMEM;
}
_cache_mngt_async_context_init(context); _cache_mngt_async_context_init(context);
context->compl_func = compl; context->compl_func = compl;
@ -291,6 +301,13 @@ static void _cache_mngt_core_flush_complete(ocf_core_t core, void *priv,
kfree(context); kfree(context);
} }
/*
* Possible return values:
* 0 - completion was called and operation succeded
* -KCAS_ERR_WAITING_INTERRUPTED - operation was canceled, caller must
* propagate error, completion will be called asynchronously
* other values - completion was called and operation failed
*/
static int _cache_mngt_core_flush_sync(ocf_core_t core, bool interruption, static int _cache_mngt_core_flush_sync(ocf_core_t core, bool interruption,
void (*compl)(ocf_cache_t cache)) void (*compl)(ocf_cache_t cache))
{ {
@ -300,8 +317,11 @@ static int _cache_mngt_core_flush_sync(ocf_core_t core, bool interruption,
struct cache_priv *cache_priv = ocf_cache_get_priv(cache); struct cache_priv *cache_priv = ocf_cache_get_priv(cache);
context = kmalloc(sizeof(*context), GFP_KERNEL); context = kmalloc(sizeof(*context), GFP_KERNEL);
if (!context) if (!context) {
if (compl)
compl(cache);
return -ENOMEM; return -ENOMEM;
}
_cache_mngt_async_context_init(context); _cache_mngt_async_context_init(context);
context->compl_func = compl; context->compl_func = compl;
@ -2026,6 +2046,26 @@ int cache_mngt_get_seq_cutoff_policy(ocf_core_t core,
return result; 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 * @brief routine implementing dynamic cache mode switching
* @param cache_name name of cache to which operation applies * @param cache_name name of cache to which operation applies
@ -2045,32 +2085,49 @@ int cache_mngt_set_cache_mode(const char *cache_name, size_t name_len,
if (result) if (result)
return result; return result;
result = _cache_mngt_lock_sync(cache); old_mode = ocf_cache_get_mode(cache);
if (result) { if (old_mode == mode) {
ocf_mngt_cache_put(cache); printk(KERN_INFO "%s is in requested cache mode already\n", cache_name);
return result; 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); result = ocf_mngt_cache_set_mode(cache, mode);
if (result) if (result)
goto out; goto unlock;
if (flush) {
result = _cache_mngt_cache_flush_sync(cache, true, NULL);
if (result) {
ocf_mngt_cache_set_mode(cache, old_mode);
goto out;
}
}
result = _cache_mngt_save_sync(cache); 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); ocf_mngt_cache_set_mode(cache, old_mode);
}
out: unlock:
ocf_mngt_cache_unlock(cache); ocf_mngt_cache_unlock(cache);
put:
ocf_mngt_cache_put(cache); ocf_mngt_cache_put(cache);
return result; return result;
} }
@ -2087,7 +2144,7 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
ocf_cache_t cache; ocf_cache_t cache;
struct cache_priv *cache_priv; struct cache_priv *cache_priv;
ocf_queue_t mngt_queue; ocf_queue_t mngt_queue;
int status, flush_status = 0; int status = 0, flush_status = 0;
status = ocf_mngt_cache_get_by_name(cas_ctx, cache_name, status = ocf_mngt_cache_get_by_name(cas_ctx, cache_name,
name_len, &cache); name_len, &cache);
@ -2105,34 +2162,19 @@ int cache_mngt_exit_instance(const char *cache_name, size_t name_len, int flush)
* in cache during flush operation which will not be flushed * in cache during flush operation which will not be flushed
* this time, so we need to flush cache again after disabling * this time, so we need to flush cache again after disabling
* exported object. The second flush should be much faster. * exported object. The second flush should be much faster.
*/ */
if (flush) { if (flush)
/* Getting cache twice is workaround to make flush error handling easier status = _cache_flush_with_lock(cache);
and avoid dealing with synchronizing issues */ switch (status) {
status = ocf_mngt_cache_get(cache); case -OCF_ERR_CACHE_IN_INCOMPLETE_STATE:
if (status) case -OCF_ERR_FLUSHING_INTERRUPTED:
goto put; case -KCAS_ERR_WAITING_INTERRUPTED:
goto put;
status = _cache_mngt_read_lock_sync(cache); default:
if (status) { flush_status = status;
ocf_mngt_cache_put(cache); break;
goto put;
}
status = _cache_mngt_cache_flush_sync(cache, true,
_cache_read_unlock_put_cmpl);
switch (status) {
case -OCF_ERR_CACHE_IN_INCOMPLETE_STATE:
case -OCF_ERR_FLUSHING_INTERRUPTED:
case -KCAS_ERR_WAITING_INTERRUPTED:
goto put;
default:
flush_status = status;
break;
}
} }
/* get cache write lock */
status = _cache_mngt_lock_sync(cache); status = _cache_mngt_lock_sync(cache);
if (status) if (status)
goto put; goto put;

2
ocf

@ -1 +1 @@
Subproject commit ed91895f705ed2a034e96d9a577c07a2e86f1b4a Subproject commit 86d7212217d2ed2a5d5be55d4995a1f02cc4eb94