Merge pull request #209 from arutk/stop_no_queue
Allow to stop cache without management queue
This commit is contained in:
commit
1fd1a6fe17
@ -1928,7 +1928,6 @@ struct ocf_mngt_cache_stop_context {
|
|||||||
ocf_ctx_t ctx;
|
ocf_ctx_t ctx;
|
||||||
char cache_name[OCF_CACHE_NAME_SIZE];
|
char cache_name[OCF_CACHE_NAME_SIZE];
|
||||||
int cache_write_error;
|
int cache_write_error;
|
||||||
bool cache_attached;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ocf_mngt_cache_stop_wait_metadata_io_finish(void *priv)
|
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;
|
struct ocf_mngt_cache_stop_context *context = priv;
|
||||||
ocf_cache_t cache = context->cache;
|
ocf_cache_t cache = context->cache;
|
||||||
|
|
||||||
if (!context->cache_attached)
|
|
||||||
OCF_PL_NEXT_RET(pipeline);
|
|
||||||
|
|
||||||
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
ocf_refcnt_freeze(&cache->refcnt.metadata);
|
||||||
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
ocf_refcnt_register_zero_cb(&cache->refcnt.metadata,
|
||||||
ocf_mngt_cache_stop_wait_metadata_io_finish, context);
|
ocf_mngt_cache_stop_wait_metadata_io_finish, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ocf_mngt_cache_stop_remove_cores(ocf_pipeline_t pipeline,
|
static void _ocf_mngt_cache_stop_remove_cores(ocf_cache_t cache, bool attached)
|
||||||
void *priv, ocf_pipeline_arg_t arg)
|
|
||||||
{
|
{
|
||||||
struct ocf_mngt_cache_stop_context *context = priv;
|
|
||||||
ocf_cache_t cache = context->cache;
|
|
||||||
ocf_core_t core;
|
ocf_core_t core;
|
||||||
ocf_core_id_t core_id;
|
ocf_core_id_t core_id;
|
||||||
int no = cache->conf_meta->core_count;
|
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. */
|
/* All exported objects removed, cleaning up rest. */
|
||||||
for_each_core(cache, core, core_id) {
|
for_each_core(cache, core, core_id) {
|
||||||
cache_mngt_core_remove_from_cache(core);
|
cache_mngt_core_remove_from_cache(core);
|
||||||
if (context->cache_attached)
|
if (attached)
|
||||||
cache_mngt_core_remove_from_cleaning_pol(core);
|
cache_mngt_core_remove_from_cleaning_pol(core);
|
||||||
cache_mngt_core_close(core);
|
cache_mngt_core_close(core);
|
||||||
if (--no == 0)
|
if (--no == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ENV_BUG_ON(cache->conf_meta->core_count != 0);
|
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);
|
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;
|
struct ocf_mngt_cache_stop_context *context = priv;
|
||||||
ocf_cache_t cache = context->cache;
|
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_unplug(cache, true, &context->unplug_context,
|
||||||
ocf_mngt_cache_stop_unplug_complete, 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,
|
static void ocf_mngt_cache_stop_put_io_queues(ocf_pipeline_t pipeline,
|
||||||
void *priv, ocf_pipeline_arg_t arg)
|
void *priv, ocf_pipeline_arg_t arg)
|
||||||
{
|
{
|
||||||
struct ocf_mngt_cache_stop_context *context = priv;
|
struct ocf_mngt_cache_stop_context *context = priv;
|
||||||
ocf_cache_t cache = context->cache;
|
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_mngt_cache_put_io_queues(cache);
|
||||||
ocf_queue_put(queue);
|
|
||||||
|
|
||||||
ocf_pipeline_next(pipeline);
|
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,
|
static void ocf_mngt_cache_stop_finish(ocf_pipeline_t pipeline,
|
||||||
void *priv, int error)
|
void *priv, int error)
|
||||||
{
|
{
|
||||||
@ -2024,12 +2039,7 @@ static void ocf_mngt_cache_stop_finish(ocf_pipeline_t pipeline,
|
|||||||
void *completion_priv;
|
void *completion_priv;
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
env_mutex_lock(&ctx->lock);
|
ocf_mngt_cache_remove(context->ctx, cache);
|
||||||
/* Mark device uninitialized */
|
|
||||||
ocf_refcnt_freeze(&cache->refcnt.cache);
|
|
||||||
/* Remove cache from the list */
|
|
||||||
list_del(&cache->list);
|
|
||||||
env_mutex_unlock(&ctx->lock);
|
|
||||||
} else {
|
} else {
|
||||||
/* undo metadata counter freeze */
|
/* undo metadata counter freeze */
|
||||||
ocf_refcnt_unfreeze(&cache->refcnt.metadata);
|
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,
|
void ocf_mngt_cache_stop(ocf_cache_t cache,
|
||||||
ocf_mngt_cache_stop_end_t cmpl, void *priv)
|
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);
|
OCF_CHECK_NULL(cache);
|
||||||
|
|
||||||
/*
|
if (!ocf_cache_is_device_attached(cache)) {
|
||||||
* FIXME: What if creating/setting management queue failed?
|
ocf_mngt_cache_stop_detached(cache, cmpl, priv);
|
||||||
* In such case we will be unable to use pipeline, and thus
|
return;
|
||||||
* perform cache stop procedure.
|
}
|
||||||
*/
|
|
||||||
if (!cache->mngt_queue)
|
ENV_BUG_ON(!cache->mngt_queue);
|
||||||
OCF_CMPL_RET(cache, priv, -OCF_ERR_INVAL);
|
|
||||||
|
|
||||||
result = ocf_pipeline_create(&pipeline, cache,
|
result = ocf_pipeline_create(&pipeline, cache,
|
||||||
&ocf_mngt_cache_stop_pipeline_properties);
|
&ocf_mngt_cache_stop_pipeline_properties);
|
||||||
@ -2113,7 +2134,6 @@ void ocf_mngt_cache_stop(ocf_cache_t cache,
|
|||||||
context->pipeline = pipeline;
|
context->pipeline = pipeline;
|
||||||
context->cache = cache;
|
context->cache = cache;
|
||||||
context->ctx = cache->owner;
|
context->ctx = cache->owner;
|
||||||
context->cache_attached = ocf_cache_is_device_attached(cache);
|
|
||||||
|
|
||||||
result = env_strncpy(context->cache_name, sizeof(context->cache_name),
|
result = env_strncpy(context->cache_name, sizeof(context->cache_name),
|
||||||
ocf_cache_get_name(cache), sizeof(context->cache_name));
|
ocf_cache_get_name(cache), sizeof(context->cache_name));
|
||||||
|
@ -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)
|
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):
|
def run_io_and_cache_data_if_possible(exported_obj, mode, cls, cls_no):
|
||||||
test_data = Data(cls_no * cls)
|
test_data = Data(cls_no * cls)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user