Merge pull request #209 from arutk/stop_no_queue

Allow to stop cache without management queue
This commit is contained in:
Jan Musiał 2019-07-23 13:51:21 +02:00 committed by GitHub
commit 1fd1a6fe17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 29 deletions

View File

@ -1928,7 +1928,6 @@ struct ocf_mngt_cache_stop_context {
ocf_ctx_t ctx;
char cache_name[OCF_CACHE_NAME_SIZE];
int cache_write_error;
bool cache_attached;
};
static void ocf_mngt_cache_stop_wait_metadata_io_finish(void *priv)
@ -1944,19 +1943,13 @@ static void ocf_mngt_cache_stop_wait_metadata_io(ocf_pipeline_t pipeline,
struct ocf_mngt_cache_stop_context *context = priv;
ocf_cache_t cache = context->cache;
if (!context->cache_attached)
OCF_PL_NEXT_RET(pipeline);
ocf_refcnt_freeze(&cache->refcnt.metadata);
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
ocf_mngt_cache_stop_wait_metadata_io_finish, context);
}
static void ocf_mngt_cache_stop_remove_cores(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
static void _ocf_mngt_cache_stop_remove_cores(ocf_cache_t cache, bool attached)
{
struct ocf_mngt_cache_stop_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_core_t core;
ocf_core_id_t core_id;
int no = cache->conf_meta->core_count;
@ -1964,13 +1957,22 @@ static void ocf_mngt_cache_stop_remove_cores(ocf_pipeline_t pipeline,
/* All exported objects removed, cleaning up rest. */
for_each_core(cache, core, core_id) {
cache_mngt_core_remove_from_cache(core);
if (context->cache_attached)
if (attached)
cache_mngt_core_remove_from_cleaning_pol(core);
cache_mngt_core_close(core);
if (--no == 0)
break;
}
ENV_BUG_ON(cache->conf_meta->core_count != 0);
}
static void ocf_mngt_cache_stop_remove_cores(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_mngt_cache_stop_context *context = priv;
ocf_cache_t cache = context->cache;
_ocf_mngt_cache_stop_remove_cores(cache, true);
ocf_pipeline_next(pipeline);
}
@ -1993,26 +1995,39 @@ static void ocf_mngt_cache_stop_unplug(ocf_pipeline_t pipeline,
struct ocf_mngt_cache_stop_context *context = priv;
ocf_cache_t cache = context->cache;
if (!context->cache_attached)
OCF_PL_NEXT_RET(pipeline);
_ocf_mngt_cache_unplug(cache, true, &context->unplug_context,
ocf_mngt_cache_stop_unplug_complete, context);
}
static void _ocf_mngt_cache_put_io_queues(ocf_cache_t cache)
{
ocf_queue_t queue, tmp_queue;
list_for_each_entry_safe(queue, tmp_queue, &cache->io_queues, list)
ocf_queue_put(queue);
}
static void ocf_mngt_cache_stop_put_io_queues(ocf_pipeline_t pipeline,
void *priv, ocf_pipeline_arg_t arg)
{
struct ocf_mngt_cache_stop_context *context = priv;
ocf_cache_t cache = context->cache;
ocf_queue_t queue, tmp_queue;
list_for_each_entry_safe(queue, tmp_queue, &cache->io_queues, list)
ocf_queue_put(queue);
_ocf_mngt_cache_put_io_queues(cache);
ocf_pipeline_next(pipeline);
}
static void ocf_mngt_cache_remove(ocf_ctx_t ctx, ocf_cache_t cache)
{
env_mutex_lock(&ctx->lock);
/* Mark device uninitialized */
ocf_refcnt_freeze(&cache->refcnt.cache);
/* Remove cache from the list */
list_del(&cache->list);
env_mutex_unlock(&ctx->lock);
}
static void ocf_mngt_cache_stop_finish(ocf_pipeline_t pipeline,
void *priv, int error)
{
@ -2024,12 +2039,7 @@ static void ocf_mngt_cache_stop_finish(ocf_pipeline_t pipeline,
void *completion_priv;
if (!error) {
env_mutex_lock(&ctx->lock);
/* Mark device uninitialized */
ocf_refcnt_freeze(&cache->refcnt.cache);
/* Remove cache from the list */
list_del(&cache->list);
env_mutex_unlock(&ctx->lock);
ocf_mngt_cache_remove(context->ctx, cache);
} else {
/* undo metadata counter freeze */
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
@ -2084,6 +2094,18 @@ struct ocf_pipeline_properties ocf_mngt_cache_stop_pipeline_properties = {
},
};
static void ocf_mngt_cache_stop_detached(ocf_cache_t cache,
ocf_mngt_cache_stop_end_t cmpl, void *priv)
{
_ocf_mngt_cache_stop_remove_cores(cache, false);
_ocf_mngt_cache_put_io_queues(cache);
ocf_mngt_cache_remove(cache->owner, cache);
ocf_cache_log(cache, log_info, "Cache %s successfully stopped\n",
ocf_cache_get_name(cache));
cmpl(cache, priv, 0);
ocf_mngt_cache_put(cache);
}
void ocf_mngt_cache_stop(ocf_cache_t cache,
ocf_mngt_cache_stop_end_t cmpl, void *priv)
{
@ -2093,13 +2115,12 @@ void ocf_mngt_cache_stop(ocf_cache_t cache,
OCF_CHECK_NULL(cache);
/*
* FIXME: What if creating/setting management queue failed?
* In such case we will be unable to use pipeline, and thus
* perform cache stop procedure.
*/
if (!cache->mngt_queue)
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
if (!ocf_cache_is_device_attached(cache)) {
ocf_mngt_cache_stop_detached(cache, cmpl, priv);
return;
}
ENV_BUG_ON(!cache->mngt_queue);
result = ocf_pipeline_create(&pipeline, cache,
&ocf_mngt_cache_stop_pipeline_properties);
@ -2113,7 +2134,6 @@ void ocf_mngt_cache_stop(ocf_cache_t cache,
context->pipeline = pipeline;
context->cache = cache;
context->ctx = cache->owner;
context->cache_attached = ocf_cache_is_device_attached(cache);
result = env_strncpy(context->cache_name, sizeof(context->cache_name),
ocf_cache_get_name(cache), sizeof(context->cache_name));

View File

@ -354,6 +354,25 @@ def test_start_too_small_device(pyocf_ctx, mode, cls):
Cache.start_on_device(cache_device, cache_mode=mode, cache_line_size=cls)
def test_start_stop_noqueue(pyocf_ctx):
# cache object just to construct cfg conveniently
_cache = Cache(pyocf_ctx.ctx_handle)
cache_handle = c_void_p()
status = pyocf_ctx.lib.ocf_mngt_cache_start(
pyocf_ctx.ctx_handle, byref(cache_handle), byref(_cache.cfg)
)
assert not status, "Failed to start cache: {}".format(status)
# stop without creating mngmt queue
c = OcfCompletion(
[("cache", c_void_p), ("priv", c_void_p), ("error", c_int)]
)
pyocf_ctx.lib.ocf_mngt_cache_stop(cache_handle, c, None)
c.wait()
assert not c.results["error"], "Failed to stop cache: {}".format(c.results["error"])
def run_io_and_cache_data_if_possible(exported_obj, mode, cls, cls_no):
test_data = Data(cls_no * cls)