From 23b0a32aec9f0d25575adaff74fa6a81c566adc7 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Mon, 18 Mar 2019 09:34:13 +0100 Subject: [PATCH] Parametrize pipeline steps This allows to reuse same step functions giving them different parameters on each step. Additionally move pipeline to utils, to make it accessible to other subsystems of OCF (e.g. metadata). Signed-off-by: Robert Baldyga --- src/mngt/ocf_mngt_cache.c | 437 +++++++++--------- src/mngt/ocf_mngt_common.c | 80 ---- src/mngt/ocf_mngt_common.h | 18 - src/utils/utils_pipeline.c | 126 +++++ src/utils/utils_pipeline.h | 134 ++++++ .../_cache_mng_set_cache_mode_test.c | 73 +-- ...gt_cache_set_fallback_pt_error_threshold.c | 73 +-- 7 files changed, 576 insertions(+), 365 deletions(-) create mode 100644 src/utils/utils_pipeline.c create mode 100644 src/utils/utils_pipeline.h diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index a50c16a..37e0f35 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -16,6 +16,7 @@ #include "../utils/utils_device.h" #include "../utils/utils_io.h" #include "../utils/utils_cache_line.h" +#include "../utils/utils_pipeline.h" #include "../ocf_utils.h" #include "../concurrency/ocf_concurrency.h" #include "../eviction/ops.h" @@ -162,14 +163,14 @@ struct ocf_cache_attach_context { void *rw_buffer; void *cmp_buffer; unsigned long reserved_lba_addr; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; } test; _ocf_mngt_cache_attach_end_t cmpl; void *priv1; void *priv2; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; }; static ocf_cache_id_t _ocf_mngt_cache_find_free_id(ocf_ctx_t owner) @@ -473,7 +474,7 @@ void _ocf_mngt_init_instance_load_complete(void *priv, int error) if (error) { ocf_cache_log(cache, log_err, "Cannot read cache metadata\n"); - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_START_CACHE_FAIL); return; } @@ -488,7 +489,7 @@ void _ocf_mngt_init_instance_load_complete(void *priv, int error) cleaning_policy_ops[cleaning_policy].initialize(cache, 1); out: - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } /** @@ -532,7 +533,7 @@ static void _ocf_mngt_init_instance_load( ret = _ocf_mngt_init_instance_add_cores(context); if (ret) { - ocf_mngt_pipeline_finish(context->pipeline, ret); + ocf_pipeline_finish(context->pipeline, ret); return; } @@ -578,7 +579,8 @@ static int _ocf_mngt_init_new_cache(struct ocf_cachemng_init_params *params) return 0; } -static void _ocf_mngt_attach_cache_device(ocf_mngt_pipeline_t pipeline, void *priv) +static void _ocf_mngt_attach_cache_device(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -630,11 +632,11 @@ static void _ocf_mngt_attach_cache_device(ocf_mngt_pipeline_t pipeline, void *pr goto err; } - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); return; err: - ocf_mngt_pipeline_finish(context->pipeline, ret); + ocf_pipeline_finish(context->pipeline, ret); } /** @@ -716,15 +718,15 @@ static void _ocf_mngt_test_volume_initial_write_complete(void *priv, int error) struct ocf_cache_attach_context *context = priv; if (error) { - ocf_mngt_pipeline_finish(context->test.pipeline, error); + ocf_pipeline_finish(context->test.pipeline, error); return; } - ocf_mngt_pipeline_next(context->test.pipeline); + ocf_pipeline_next(context->test.pipeline); } static void _ocf_mngt_test_volume_initial_write( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t test_pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -747,35 +749,35 @@ static void _ocf_mngt_test_volume_first_read_complete(void *priv, int error) int ret, diff; if (error) { - ocf_mngt_pipeline_finish(context->test.pipeline, error); + ocf_pipeline_finish(context->test.pipeline, error); return; } ret = env_memcmp(context->test.rw_buffer, PAGE_SIZE, context->test.cmp_buffer, PAGE_SIZE, &diff); if (ret) { - ocf_mngt_pipeline_finish(context->test.pipeline, ret); + ocf_pipeline_finish(context->test.pipeline, ret); return; } if (diff) { /* we read back different data than what we had just written - this is fatal error */ - ocf_mngt_pipeline_finish(context->test.pipeline, -EIO); + ocf_pipeline_finish(context->test.pipeline, -EIO); return; } if (!ocf_volume_is_atomic(&cache->device->volume)) { /* If not atomic, stop testing here */ - ocf_mngt_pipeline_finish(context->test.pipeline, 0); + ocf_pipeline_finish(context->test.pipeline, 0); return; } - ocf_mngt_pipeline_next(context->test.pipeline); + ocf_pipeline_next(context->test.pipeline); } static void _ocf_mngt_test_volume_first_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t test_pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -797,15 +799,15 @@ static void _ocf_mngt_test_volume_discard_complete(void *priv, int error) struct ocf_cache_attach_context *context = priv; if (error) { - ocf_mngt_pipeline_finish(context->test.pipeline, error); + ocf_pipeline_finish(context->test.pipeline, error); return; } - ocf_mngt_pipeline_next(context->test.pipeline); + ocf_pipeline_next(context->test.pipeline); } static void _ocf_mngt_test_volume_discard( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t test_pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -826,14 +828,14 @@ static void _ocf_mngt_test_volume_second_read_complete(void *priv, int error) int ret, diff; if (error) { - ocf_mngt_pipeline_finish(context->test.pipeline, error); + ocf_pipeline_finish(context->test.pipeline, error); return; } ret = env_memcmp(context->test.rw_buffer, PAGE_SIZE, context->test.cmp_buffer, PAGE_SIZE, &diff); if (ret) { - ocf_mngt_pipeline_finish(context->test.pipeline, ret); + ocf_pipeline_finish(context->test.pipeline, ret); return; } @@ -843,11 +845,11 @@ static void _ocf_mngt_test_volume_second_read_complete(void *priv, int error) cache->device->volume.features.discard_zeroes = 0; } - ocf_mngt_pipeline_next(context->test.pipeline); + ocf_pipeline_next(context->test.pipeline); } static void _ocf_mngt_test_volume_second_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t test_pipeline, void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -864,40 +866,46 @@ static void _ocf_mngt_test_volume_second_read( _ocf_mngt_test_volume_second_read_complete, context); } -ocf_mngt_pipeline_step_t _ocf_mngt_test_volume_steps[] = { - _ocf_mngt_test_volume_initial_write, - _ocf_mngt_test_volume_first_read, - _ocf_mngt_test_volume_discard, - _ocf_mngt_test_volume_second_read, - NULL, -}; - -static void _ocf_mngt_test_volume_finish(ocf_mngt_pipeline_t pipeline, +static void _ocf_mngt_test_volume_finish(ocf_pipeline_t pipeline, void *priv, int error) { struct ocf_cache_attach_context *context = priv; env_free(context->test.rw_buffer); env_free(context->test.cmp_buffer); - ocf_mngt_pipeline_destroy(context->test.pipeline); if (error) - ocf_mngt_pipeline_finish(context->pipeline, error); + ocf_pipeline_finish(context->pipeline, error); else - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); + + ocf_pipeline_destroy(context->test.pipeline); } -static void _ocf_mngt_test_volume(ocf_mngt_pipeline_t pipeline, void *priv) +struct ocf_pipeline_properties _ocf_mngt_test_volume_pipeline_properties = { + .priv_size = 0, + .finish = _ocf_mngt_test_volume_finish, + .steps = { + OCF_PL_STEP(_ocf_mngt_test_volume_initial_write), + OCF_PL_STEP(_ocf_mngt_test_volume_first_read), + OCF_PL_STEP(_ocf_mngt_test_volume_discard), + OCF_PL_STEP(_ocf_mngt_test_volume_second_read), + OCF_PL_STEP_TERMINATOR(), + }, +}; + +static void _ocf_mngt_test_volume(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; - ocf_mngt_pipeline_t test_pipeline; + ocf_pipeline_t test_pipeline; int result; cache->device->volume.features.discard_zeroes = 1; if (!context->cfg.perform_test) { - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); return; } @@ -905,7 +913,7 @@ static void _ocf_mngt_test_volume(ocf_mngt_pipeline_t pipeline, void *priv) context->test.rw_buffer = env_malloc(PAGE_SIZE, ENV_MEM_NORMAL); if (!context->test.rw_buffer) { - ocf_mngt_pipeline_finish(context->pipeline, -OCF_ERR_NO_MEM); + ocf_pipeline_finish(context->pipeline, -OCF_ERR_NO_MEM); return; } @@ -913,22 +921,23 @@ static void _ocf_mngt_test_volume(ocf_mngt_pipeline_t pipeline, void *priv) if (!context->test.cmp_buffer) goto err_buffer; - result = ocf_mngt_pipeline_create(&test_pipeline, cache, - _ocf_mngt_test_volume_steps, - _ocf_mngt_test_volume_finish, context); + result = ocf_pipeline_create(&test_pipeline, cache, + &_ocf_mngt_test_volume_pipeline_properties); if (result) goto err_pipeline; + ocf_pipeline_set_priv(test_pipeline, context); + context->test.pipeline = test_pipeline; - ocf_mngt_pipeline_next(test_pipeline); + ocf_pipeline_next(test_pipeline); return; err_pipeline: env_free(context->test.rw_buffer); err_buffer: env_free(context->test.cmp_buffer); - ocf_mngt_pipeline_finish(context->pipeline, -OCF_ERR_NO_MEM); + ocf_pipeline_finish(context->pipeline, -OCF_ERR_NO_MEM); } /** @@ -944,7 +953,7 @@ static void _ocf_mngt_attach_load_properties_end(void *priv, int error, context->metadata.status = error; if (error) { - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); return; } @@ -957,11 +966,11 @@ static void _ocf_mngt_attach_load_properties_end(void *priv, int error, cache->conf_meta->cache_mode = properties->cache_mode; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void _ocf_mngt_attach_load_properties(ocf_mngt_pipeline_t pipeline, - void *priv) +static void _ocf_mngt_attach_load_properties(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -973,7 +982,7 @@ static void _ocf_mngt_attach_load_properties(ocf_mngt_pipeline_t pipeline, context->metadata.line_size = context->cfg.cache_line_size; if (cache->device->init_mode == ocf_init_mode_metadata_volatile) { - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); return; } @@ -981,8 +990,8 @@ static void _ocf_mngt_attach_load_properties(ocf_mngt_pipeline_t pipeline, _ocf_mngt_attach_load_properties_end, context); } -static void _ocf_mngt_attach_prepare_metadata(ocf_mngt_pipeline_t pipeline, - void *priv) +static void _ocf_mngt_attach_prepare_metadata(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -990,7 +999,7 @@ static void _ocf_mngt_attach_prepare_metadata(ocf_mngt_pipeline_t pipeline, if (context->init_mode == ocf_init_mode_load && context->metadata.status) { - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_START_CACHE_FAIL); return; } @@ -1004,7 +1013,7 @@ static void _ocf_mngt_attach_prepare_metadata(ocf_mngt_pipeline_t pipeline, if (ocf_metadata_init_variable_size(cache, context->volume_size, context->metadata.line_size, cache->conf_meta->metadata_layout)) { - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_START_CACHE_FAIL); return; } @@ -1021,13 +1030,13 @@ static void _ocf_mngt_attach_prepare_metadata(ocf_mngt_pipeline_t pipeline, ret = ocf_concurrency_init(cache); if (ret) { - ocf_mngt_pipeline_finish(context->pipeline, ret); + ocf_pipeline_finish(context->pipeline, ret); return; } context->flags.concurrency_inited = 1; - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } /** @@ -1044,7 +1053,7 @@ static void _ocf_mngt_init_instance_init(struct ocf_cache_attach_context *contex if (context->metadata.shutdown_status != ocf_metadata_clean_shutdown) { ocf_cache_log(cache, log_err, DIRTY_SHUTDOWN_ERROR_MSG); - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_DIRTY_SHUTDOWN); return; } @@ -1052,7 +1061,7 @@ static void _ocf_mngt_init_instance_init(struct ocf_cache_attach_context *contex if (context->metadata.dirty_flushed == DIRTY_NOT_FLUSHED) { ocf_cache_log(cache, log_err, DIRTY_NOT_FLUSHED_ERROR_MSG); - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_DIRTY_EXISTS); return; } @@ -1065,7 +1074,7 @@ static void _ocf_mngt_init_instance_init(struct ocf_cache_attach_context *contex */ cache->conf_meta->dirty_flushed = true; - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } uint64_t _ocf_mngt_calculate_ram_needed(ocf_cache_t cache, @@ -1328,7 +1337,8 @@ static void _ocf_mngt_init_attached_nonpersistent(ocf_cache_t cache) env_atomic_set(&cache->fallback_pt_error_counter, 0); } -static void _ocf_mngt_attach_check_ram(ocf_mngt_pipeline_t pipeline, void *priv) +static void _ocf_mngt_attach_check_ram(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1347,10 +1357,10 @@ static void _ocf_mngt_attach_check_ram(ocf_mngt_pipeline_t pipeline, void *priv) "Available RAM: %" ENV_PRIu64 " B\n", free_ram); ocf_cache_log(cache, log_err, "Needed RAM: %" ENV_PRIu64 " B\n", min_free_ram); - ocf_mngt_pipeline_finish(pipeline, -OCF_ERR_NO_FREE_RAM); + ocf_pipeline_finish(pipeline, -OCF_ERR_NO_FREE_RAM); } - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); } @@ -1362,22 +1372,22 @@ static void _ocf_mngt_attach_load_superblock_complete(void *priv, int error) if (error) { ocf_cache_log(cache, log_err, "ERROR: Cannot load cache state\n"); - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_START_CACHE_FAIL); return; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void _ocf_mngt_attach_load_superblock(ocf_mngt_pipeline_t pipeline, - void *priv) +static void _ocf_mngt_attach_load_superblock(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; if (cache->device->init_mode != ocf_init_mode_load) { - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); return; } @@ -1386,8 +1396,8 @@ static void _ocf_mngt_attach_load_superblock(ocf_mngt_pipeline_t pipeline, _ocf_mngt_attach_load_superblock_complete, context); } -static void _ocf_mngt_attach_init_instance(ocf_mngt_pipeline_t pipeline, - void *priv) +static void _ocf_mngt_attach_init_instance(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1401,11 +1411,12 @@ static void _ocf_mngt_attach_init_instance(ocf_mngt_pipeline_t pipeline, _ocf_mngt_init_instance_load(context); return; default: - ocf_mngt_pipeline_finish(context->pipeline, -OCF_ERR_INVAL); + ocf_pipeline_finish(context->pipeline, -OCF_ERR_INVAL); } } -static void _ocf_mngt_attach_clean_pol(ocf_mngt_pipeline_t pipeline, void *priv) +static void _ocf_mngt_attach_clean_pol(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1415,12 +1426,12 @@ static void _ocf_mngt_attach_clean_pol(ocf_mngt_pipeline_t pipeline, void *priv) if (cache->device->init_mode != ocf_init_mode_load) { result = _ocf_mngt_cache_add_cores_t_clean_pol(cache); if (result) { - ocf_mngt_pipeline_finish(context->pipeline, result); + ocf_pipeline_finish(context->pipeline, result); return; } } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } static void _ocf_mngt_attach_flush_metadata_complete(void *priv, int error) @@ -1431,16 +1442,16 @@ static void _ocf_mngt_attach_flush_metadata_complete(void *priv, int error) if (error) { ocf_cache_log(cache, log_err, "ERROR: Cannot save cache state\n"); - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_WRITE_CACHE); return; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void _ocf_mngt_attach_flush_metadata(ocf_mngt_pipeline_t pipeline, - void *priv) +static void _ocf_mngt_attach_flush_metadata(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1463,7 +1474,7 @@ static void _ocf_mngt_attach_discard_complete(void *priv, int error) if (ocf_volume_is_atomic(&cache->device->volume)) { ocf_cache_log(cache, log_err, "This step is required" " for atomic mode!\n"); - ocf_mngt_pipeline_finish(context->pipeline, error); + ocf_pipeline_finish(context->pipeline, error); return; } @@ -1471,10 +1482,11 @@ static void _ocf_mngt_attach_discard_complete(void *priv, int error) " performance!\n"); } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void _ocf_mngt_attach_discard(ocf_mngt_pipeline_t pipeline, void *priv) +static void _ocf_mngt_attach_discard(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1483,12 +1495,12 @@ static void _ocf_mngt_attach_discard(ocf_mngt_pipeline_t pipeline, void *priv) bool discard = cache->device->volume.features.discard_zeroes; if (cache->device->init_mode == ocf_init_mode_load) { - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); return; } if (!context->cfg.discard_on_start) { - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); return; } @@ -1508,12 +1520,13 @@ static void _ocf_mngt_attach_flush_complete(void *priv, int error) struct ocf_cache_attach_context *context = priv; if (error) - ocf_mngt_pipeline_finish(context->pipeline, error); + ocf_pipeline_finish(context->pipeline, error); else - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void _ocf_mngt_attach_flush(ocf_mngt_pipeline_t pipeline, void *priv) +static void _ocf_mngt_attach_flush(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1523,7 +1536,7 @@ static void _ocf_mngt_attach_flush(ocf_mngt_pipeline_t pipeline, void *priv) ocf_submit_volume_flush(&cache->device->volume, _ocf_mngt_attach_flush_complete, context); } else { - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } } @@ -1534,16 +1547,16 @@ static void _ocf_mngt_attach_shutdown_status_complete(void *priv, int error) if (error) { ocf_cache_log(cache, log_err, "Cannot flush shutdown status\n"); - ocf_mngt_pipeline_finish(context->pipeline, + ocf_pipeline_finish(context->pipeline, -OCF_ERR_WRITE_CACHE); return; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void _ocf_mngt_attach_shutdown_status(ocf_mngt_pipeline_t pipeline, - void *priv) +static void _ocf_mngt_attach_shutdown_status(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1553,7 +1566,8 @@ static void _ocf_mngt_attach_shutdown_status(ocf_mngt_pipeline_t pipeline, _ocf_mngt_attach_shutdown_status_complete, context); } -static void _ocf_mngt_attach_post_init(ocf_mngt_pipeline_t pipeline, void *priv) +static void _ocf_mngt_attach_post_init(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_cache_attach_context *context = priv; ocf_cache_t cache = context->cache; @@ -1564,7 +1578,7 @@ static void _ocf_mngt_attach_post_init(ocf_mngt_pipeline_t pipeline, void *priv) if (result) { ocf_cache_log(cache, log_err, "Error while starting cleaner\n"); - ocf_mngt_pipeline_finish(context->pipeline, result); + ocf_pipeline_finish(context->pipeline, result); return; } context->flags.cleaner_started = true; @@ -1575,59 +1589,66 @@ static void _ocf_mngt_attach_post_init(ocf_mngt_pipeline_t pipeline, void *priv) env_atomic_set(&cache->attached, 1); - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -ocf_mngt_pipeline_step_t _ocf_mngt_cache_attach_pipeline_steps[] = { - _ocf_mngt_attach_cache_device, - _ocf_mngt_attach_check_ram, - _ocf_mngt_attach_load_properties, - _ocf_mngt_attach_prepare_metadata, - _ocf_mngt_test_volume, - _ocf_mngt_attach_load_superblock, - _ocf_mngt_attach_init_instance, - _ocf_mngt_attach_clean_pol, - _ocf_mngt_attach_flush_metadata, - _ocf_mngt_attach_discard, - _ocf_mngt_attach_flush, - _ocf_mngt_attach_shutdown_status, - _ocf_mngt_attach_post_init, - NULL, -}; - -static void _ocf_mngt_cache_attach_finish(ocf_mngt_pipeline_t pipeline, +static void _ocf_mngt_cache_attach_finish(ocf_pipeline_t pipeline, void *priv, int error) { struct ocf_cache_attach_context *context = priv; - ocf_mngt_pipeline_destroy(context->pipeline); - if (error) _ocf_mngt_attach_handle_error(context); context->cmpl(context->cache, context->priv1, context->priv2, error); + env_vfree(context->cfg.uuid.data); - env_vfree(context); + ocf_pipeline_destroy(context->pipeline); } +struct ocf_pipeline_properties _ocf_mngt_cache_attach_pipeline_properties = { + .priv_size = sizeof(struct ocf_cache_attach_context), + .finish = _ocf_mngt_cache_attach_finish, + .steps = { + OCF_PL_STEP(_ocf_mngt_attach_cache_device), + OCF_PL_STEP(_ocf_mngt_attach_check_ram), + OCF_PL_STEP(_ocf_mngt_attach_load_properties), + OCF_PL_STEP(_ocf_mngt_attach_prepare_metadata), + OCF_PL_STEP(_ocf_mngt_test_volume), + OCF_PL_STEP(_ocf_mngt_attach_load_superblock), + OCF_PL_STEP(_ocf_mngt_attach_init_instance), + OCF_PL_STEP(_ocf_mngt_attach_clean_pol), + OCF_PL_STEP(_ocf_mngt_attach_flush_metadata), + OCF_PL_STEP(_ocf_mngt_attach_discard), + OCF_PL_STEP(_ocf_mngt_attach_flush), + OCF_PL_STEP(_ocf_mngt_attach_shutdown_status), + OCF_PL_STEP(_ocf_mngt_attach_post_init), + OCF_PL_STEP_TERMINATOR(), + }, +}; + static void _ocf_mngt_cache_attach(ocf_cache_t cache, struct ocf_mngt_cache_device_config *cfg, bool load, _ocf_mngt_cache_attach_end_t cmpl, void *priv1, void *priv2) { struct ocf_cache_attach_context *context; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; void *data; int result; - context = env_vzalloc(sizeof(*context)); - if (!context) { - context->cmpl(cache, priv1, priv2, -OCF_ERR_NO_MEM); + result = ocf_pipeline_create(&pipeline, cache, + &_ocf_mngt_cache_attach_pipeline_properties); + if (result) { + cmpl(cache, priv1, priv2, -OCF_ERR_NO_MEM); return; } + context = ocf_pipeline_get_priv(pipeline); + context->cmpl = cmpl; context->priv1 = priv1; context->priv2 = priv2; + context->pipeline = pipeline; context->cache = cache; context->cfg = *cfg; @@ -1635,7 +1656,7 @@ static void _ocf_mngt_cache_attach(ocf_cache_t cache, data = env_vmalloc(cfg->uuid.size); if (!data) { result = -OCF_ERR_NO_MEM; - goto err_context; + goto err_pipeline; } result = env_memcpy(data, cfg->uuid.size, cfg->uuid.data, @@ -1652,23 +1673,15 @@ static void _ocf_mngt_cache_attach(ocf_cache_t cache, ocf_init_mode_load : ocf_init_mode_init; } - result = ocf_mngt_pipeline_create(&pipeline, cache, - _ocf_mngt_cache_attach_pipeline_steps, - _ocf_mngt_cache_attach_finish, context); - if (result) - goto err_uuid; - - context->pipeline = pipeline; - _ocf_mngt_init_attached_nonpersistent(cache); - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); return; err_uuid: env_vfree(data); -err_context: - env_vfree(context); +err_pipeline: + ocf_pipeline_destroy(pipeline); cmpl(cache, priv1, priv2, result); } @@ -1962,26 +1975,26 @@ void ocf_mngt_cache_load(ocf_cache_t cache, struct ocf_mngt_cache_stop_context { ocf_mngt_cache_stop_end_t cmpl; void *priv; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; ocf_cache_t cache; ocf_ctx_t ctx; char cache_name[OCF_CACHE_NAME_SIZE]; int error; }; -static void ocf_mngt_cache_stop_wait_io(ocf_mngt_pipeline_t pipeline, - void *priv) +static void ocf_mngt_cache_stop_wait_io(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; /* TODO: Make this asynchronous! */ ocf_cache_wait_for_io_finish(cache); - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); } -static void ocf_mngt_cache_stop_remove_cores(ocf_mngt_pipeline_t pipeline, - void *priv) +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; @@ -2001,7 +2014,7 @@ static void ocf_mngt_cache_stop_remove_cores(ocf_mngt_pipeline_t pipeline, } ENV_BUG_ON(cache->conf_meta->core_count != 0); - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); } static void ocf_mngt_cache_stop_unplug_complete(void *priv, int error) @@ -2009,17 +2022,17 @@ static void ocf_mngt_cache_stop_unplug_complete(void *priv, int error) struct ocf_mngt_cache_stop_context *context = priv; context->error = error; - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void ocf_mngt_cache_stop_unplug(ocf_mngt_pipeline_t pipeline, - void *priv) +static void ocf_mngt_cache_stop_unplug(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; if (!env_atomic_read(&cache->attached)) { - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); return; } @@ -2027,8 +2040,8 @@ static void ocf_mngt_cache_stop_unplug(ocf_mngt_pipeline_t pipeline, ocf_mngt_cache_stop_unplug_complete, context); } -static void ocf_mngt_cache_stop_put_io_queues(ocf_mngt_pipeline_t pipeline, - void *priv) +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; @@ -2037,26 +2050,16 @@ static void ocf_mngt_cache_stop_put_io_queues(ocf_mngt_pipeline_t pipeline, list_for_each_entry_safe(queue, tmp_queue, &cache->io_queues, list) ocf_queue_put(queue); - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); } -ocf_mngt_pipeline_step_t ocf_mngt_cache_stop_pipeline_steps[] = { - ocf_mngt_cache_stop_wait_io, - ocf_mngt_cache_stop_remove_cores, - ocf_mngt_cache_stop_unplug, - ocf_mngt_cache_stop_put_io_queues, - NULL, -}; - -static void ocf_mngt_cache_stop_finish(ocf_mngt_pipeline_t pipeline, +static void ocf_mngt_cache_stop_finish(ocf_pipeline_t pipeline, void *priv, int error) { struct ocf_mngt_cache_stop_context *context = priv; ocf_cache_t cache = context->cache; ocf_ctx_t ctx = context->ctx; - ocf_mngt_pipeline_destroy(context->pipeline); - if (error) context->error = error; @@ -2082,40 +2085,39 @@ static void ocf_mngt_cache_stop_finish(ocf_mngt_pipeline_t pipeline, } context->cmpl(cache, context->priv, context->error); - env_vfree(context); + + ocf_pipeline_destroy(context->pipeline); } +struct ocf_pipeline_properties ocf_mngt_cache_stop_pipeline_properties = { + .priv_size = sizeof(struct ocf_mngt_cache_stop_context), + .finish = ocf_mngt_cache_stop_finish, + .steps = { + OCF_PL_STEP(ocf_mngt_cache_stop_wait_io), + OCF_PL_STEP(ocf_mngt_cache_stop_remove_cores), + OCF_PL_STEP(ocf_mngt_cache_stop_unplug), + OCF_PL_STEP(ocf_mngt_cache_stop_put_io_queues), + OCF_PL_STEP_TERMINATOR(), + }, +}; + void ocf_mngt_cache_stop(ocf_cache_t cache, ocf_mngt_cache_stop_end_t cmpl, void *priv) { struct ocf_mngt_cache_stop_context *context; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; int result; OCF_CHECK_NULL(cache); - context = env_vzalloc(sizeof(*context)); - if (!context) { + result = ocf_pipeline_create(&pipeline, cache, + &ocf_mngt_cache_stop_pipeline_properties); + if (result) { cmpl(cache, priv, -OCF_ERR_NO_MEM); return; } - result = env_strncpy(context->cache_name, sizeof(context->cache_name), - ocf_cache_get_name(cache), sizeof(context->cache_name)); - if (result) { - env_vfree(context); - cmpl(cache, priv, -OCF_ERR_NO_MEM); - return; - } - - result = ocf_mngt_pipeline_create(&pipeline, cache, - ocf_mngt_cache_stop_pipeline_steps, - ocf_mngt_cache_stop_finish, context); - if (result) { - env_vfree(context); - cmpl(cache, priv, -OCF_ERR_NO_MEM); - return; - } + context = ocf_pipeline_get_priv(pipeline); context->cmpl = cmpl; context->priv = priv; @@ -2123,12 +2125,20 @@ void ocf_mngt_cache_stop(ocf_cache_t cache, context->cache = cache; context->ctx = cache->owner; + result = env_strncpy(context->cache_name, sizeof(context->cache_name), + ocf_cache_get_name(cache), sizeof(context->cache_name)); + if (result) { + ocf_pipeline_destroy(pipeline); + cmpl(cache, priv, -OCF_ERR_NO_MEM); + return; + } + ocf_cache_log(cache, log_info, "Stopping cache\n"); env_bit_set(ocf_cache_state_stopping, &cache->cache_state); env_bit_clear(ocf_cache_state_running, &cache->cache_state); - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); } void ocf_mngt_cache_save(ocf_cache_t cache, @@ -2263,7 +2273,7 @@ int ocf_mngt_cache_get_fallback_pt_error_threshold(ocf_cache_t cache, struct ocf_mngt_cache_detach_context { ocf_mngt_cache_detach_end_t cmpl; void *priv; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; ocf_cache_t cache; }; @@ -2273,15 +2283,15 @@ static void ocf_mngt_cache_detach_flush_cmpl(ocf_cache_t cache, struct ocf_mngt_cache_detach_context *context = priv; if (error) { - ocf_mngt_pipeline_finish(context->pipeline, error); + ocf_pipeline_finish(context->pipeline, error); return; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void ocf_mngt_cache_detach_flush(ocf_mngt_pipeline_t pipeline, - void *priv) +static void ocf_mngt_cache_detach_flush(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_mngt_cache_detach_context *context = priv; ocf_cache_t cache = context->cache; @@ -2290,8 +2300,8 @@ static void ocf_mngt_cache_detach_flush(ocf_mngt_pipeline_t pipeline, context); } -static void ocf_mngt_cache_detach_wait_pending(ocf_mngt_pipeline_t pipeline, - void *priv) +static void ocf_mngt_cache_detach_wait_pending(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_mngt_cache_detach_context *context = priv; ocf_cache_t cache = context->cache; @@ -2302,11 +2312,11 @@ static void ocf_mngt_cache_detach_wait_pending(ocf_mngt_pipeline_t pipeline, env_waitqueue_wait(cache->pending_cache_wq, !env_atomic_read(&cache->pending_cache_requests)); - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void ocf_mngt_cache_detach_update_metadata(ocf_mngt_pipeline_t pipeline, - void *priv) +static void ocf_mngt_cache_detach_update_metadata(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_mngt_cache_detach_context *context = priv; ocf_cache_t cache = context->cache; @@ -2323,7 +2333,7 @@ static void ocf_mngt_cache_detach_update_metadata(ocf_mngt_pipeline_t pipeline, j++; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } static void ocf_mngt_cache_detach_unplug_complete(void *priv, int error) @@ -2331,15 +2341,15 @@ static void ocf_mngt_cache_detach_unplug_complete(void *priv, int error) struct ocf_mngt_cache_detach_context *context = priv; if (error) { - ocf_mngt_pipeline_finish(context->pipeline, error); + ocf_pipeline_finish(context->pipeline, error); return; } - ocf_mngt_pipeline_next(context->pipeline); + ocf_pipeline_next(context->pipeline); } -static void ocf_mngt_cache_detach_unplug(ocf_mngt_pipeline_t pipeline, - void *priv) +static void ocf_mngt_cache_detach_unplug(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg) { struct ocf_mngt_cache_detach_context *context = priv; ocf_cache_t cache = context->cache; @@ -2350,22 +2360,12 @@ static void ocf_mngt_cache_detach_unplug(ocf_mngt_pipeline_t pipeline, ocf_mngt_cache_detach_unplug_complete, context); } -ocf_mngt_pipeline_step_t ocf_mngt_cache_detach_pipeline_steps[] = { - ocf_mngt_cache_detach_flush, - ocf_mngt_cache_detach_wait_pending, - ocf_mngt_cache_detach_update_metadata, - ocf_mngt_cache_detach_unplug, - NULL, -}; - -static void ocf_mngt_cache_detach_finish(ocf_mngt_pipeline_t pipeline, +static void ocf_mngt_cache_detach_finish(ocf_pipeline_t pipeline, void *priv, int error) { struct ocf_mngt_cache_detach_context *context = priv; ocf_cache_t cache = context->cache; - ocf_mngt_pipeline_destroy(context->pipeline); - ENV_BUG_ON(env_atomic_dec_return(&cache->flush_started) < 0); if (!error) { @@ -2381,14 +2381,27 @@ static void ocf_mngt_cache_detach_finish(ocf_mngt_pipeline_t pipeline, } context->cmpl(cache, context->priv, error); - env_vfree(context); + + ocf_pipeline_destroy(context->pipeline); } +struct ocf_pipeline_properties ocf_mngt_cache_detach_pipeline_properties = { + .priv_size = sizeof(struct ocf_mngt_cache_detach_context), + .finish = ocf_mngt_cache_detach_finish, + .steps = { + OCF_PL_STEP(ocf_mngt_cache_detach_flush), + OCF_PL_STEP(ocf_mngt_cache_detach_wait_pending), + OCF_PL_STEP(ocf_mngt_cache_detach_update_metadata), + OCF_PL_STEP(ocf_mngt_cache_detach_unplug), + OCF_PL_STEP_TERMINATOR(), + }, +}; + void ocf_mngt_cache_detach(ocf_cache_t cache, ocf_mngt_cache_detach_end_t cmpl, void *priv) { struct ocf_mngt_cache_detach_context *context; - ocf_mngt_pipeline_t pipeline; + ocf_pipeline_t pipeline; int result; OCF_CHECK_NULL(cache); @@ -2398,20 +2411,14 @@ void ocf_mngt_cache_detach(ocf_cache_t cache, return; } - context = env_vzalloc(sizeof(*context)); - if (!context) { + result = ocf_pipeline_create(&pipeline, cache, + &ocf_mngt_cache_detach_pipeline_properties); + if (result) { cmpl(cache, priv, -OCF_ERR_NO_MEM); return; } - result = ocf_mngt_pipeline_create(&pipeline, cache, - ocf_mngt_cache_detach_pipeline_steps, - ocf_mngt_cache_detach_finish, context); - if (result) { - env_vfree(context); - cmpl(cache, priv, -OCF_ERR_NO_MEM); - return; - } + context = ocf_pipeline_get_priv(pipeline); context->cmpl = cmpl; context->priv = priv; @@ -2421,5 +2428,5 @@ void ocf_mngt_cache_detach(ocf_cache_t cache, /* prevent dirty io */ env_atomic_inc(&cache->flush_started); - ocf_mngt_pipeline_next(pipeline); + ocf_pipeline_next(pipeline); } diff --git a/src/mngt/ocf_mngt_common.c b/src/mngt/ocf_mngt_common.c index e18a0cc..03e426b 100644 --- a/src/mngt/ocf_mngt_common.c +++ b/src/mngt/ocf_mngt_common.c @@ -458,83 +458,3 @@ int ocf_mngt_cache_visit_reverse(ocf_ctx_t ocf_ctx, return result; } - -struct ocf_mngt_pipeline { - ocf_mngt_pipeline_step_t *steps; - int next_step; - ocf_mngt_pipeline_end_t cmpl; - struct ocf_request *req; - bool finish; - int error; - - void *priv; -}; - -static int _ocf_mngt_pipeline_run_step(struct ocf_request *req) -{ - ocf_mngt_pipeline_t pipeline = req->priv; - - if (pipeline->steps[pipeline->next_step] && !pipeline->finish) - pipeline->steps[pipeline->next_step++](pipeline, pipeline->priv); - else - pipeline->cmpl(pipeline, pipeline->priv, pipeline->error); - - return 0; -} - -static const struct ocf_io_if _io_if_pipeline = { - .read = _ocf_mngt_pipeline_run_step, - .write = _ocf_mngt_pipeline_run_step, -}; - -int ocf_mngt_pipeline_create(ocf_mngt_pipeline_t *pipeline, ocf_cache_t cache, - ocf_mngt_pipeline_step_t *steps, ocf_mngt_pipeline_end_t cmpl, - void *priv) -{ - ocf_mngt_pipeline_t tmp_pipeline; - struct ocf_request *req; - - tmp_pipeline = env_vzalloc(sizeof(struct ocf_mngt_pipeline)); - if (!tmp_pipeline) - return -OCF_ERR_NO_MEM; - - req = ocf_req_new(cache->mngt_queue, NULL, 0, 0, 0); - if (!req) { - env_vfree(tmp_pipeline); - return -OCF_ERR_NO_MEM; - } - - tmp_pipeline->steps = steps; - tmp_pipeline->next_step = 0; - tmp_pipeline->cmpl = cmpl; - tmp_pipeline->req = req; - tmp_pipeline->finish = false; - tmp_pipeline->error = 0; - tmp_pipeline->priv = priv; - - req->info.internal = true; - req->io_if = &_io_if_pipeline; - req->priv = tmp_pipeline; - - *pipeline = tmp_pipeline; - - return 0; -} - -void ocf_mngt_pipeline_destroy(ocf_mngt_pipeline_t pipeline) -{ - ocf_req_put(pipeline->req); - env_vfree(pipeline); -} - -void ocf_mngt_pipeline_next(ocf_mngt_pipeline_t pipeline) -{ - ocf_engine_push_req_front(pipeline->req, true); -} - -void ocf_mngt_pipeline_finish(ocf_mngt_pipeline_t pipeline, int error) -{ - pipeline->finish = true; - pipeline->error = error; - ocf_engine_push_req_front(pipeline->req, true); -} diff --git a/src/mngt/ocf_mngt_common.h b/src/mngt/ocf_mngt_common.h index 4a27ade..66b7735 100644 --- a/src/mngt/ocf_mngt_common.h +++ b/src/mngt/ocf_mngt_common.h @@ -30,22 +30,4 @@ int ocf_mngt_add_partition_to_cache(struct ocf_cache *cache, bool ocf_mngt_is_cache_locked(ocf_cache_t cache); -typedef struct ocf_mngt_pipeline *ocf_mngt_pipeline_t; - -typedef void (*ocf_mngt_pipeline_step_t)(ocf_mngt_pipeline_t pipeline, - void *priv); - -typedef void (*ocf_mngt_pipeline_end_t)(ocf_mngt_pipeline_t pipeline, - void *priv, int error); - -int ocf_mngt_pipeline_create(ocf_mngt_pipeline_t *pipeline, ocf_cache_t cache, - ocf_mngt_pipeline_step_t *steps, ocf_mngt_pipeline_end_t cmpl, - void *priv); - -void ocf_mngt_pipeline_destroy(ocf_mngt_pipeline_t pipeline); - -void ocf_mngt_pipeline_next(ocf_mngt_pipeline_t pipeline); - -void ocf_mngt_pipeline_finish(ocf_mngt_pipeline_t pipeline, int error); - #endif /* __OCF_MNGT_COMMON_H__ */ diff --git a/src/utils/utils_pipeline.c b/src/utils/utils_pipeline.c new file mode 100644 index 0000000..79496e0 --- /dev/null +++ b/src/utils/utils_pipeline.c @@ -0,0 +1,126 @@ +#include "ocf/ocf.h" +#include "../engine/cache_engine.h" +#include "../engine/engine_common.h" +#include "utils_pipeline.h" +#include "utils_req.h" + +struct ocf_pipeline { + struct ocf_pipeline_properties *properties; + struct ocf_request *req; + int next_step; + int next_arg; + bool finish; + int error; + + void *priv; +}; + +static int _ocf_pipeline_run_step(struct ocf_request *req) +{ + ocf_pipeline_t pipeline = req->priv; + struct ocf_pipeline_step *step; + ocf_pipeline_arg_t arg; + + if (pipeline->finish) { + pipeline->properties->finish(pipeline, pipeline->priv, + pipeline->error); + return 0; + } + + while (true) { + step = &pipeline->properties->steps[pipeline->next_step]; + switch (step->type) { + case ocf_pipeline_step_single: + pipeline->next_step++; + step->hndl(pipeline, pipeline->priv, &step->arg); + return 0; + case ocf_pipeline_step_foreach: + arg = &step->args[pipeline->next_arg++]; + if (arg->type == ocf_pipeline_arg_terminator) { + pipeline->next_arg = 0; + pipeline->next_step++; + continue; + } + step->hndl(pipeline, pipeline->priv, arg); + return 0; + case ocf_pipeline_step_terminator: + pipeline->properties->finish(pipeline, pipeline->priv, + pipeline->error); + return 0; + default: + ENV_BUG(); + } + } + + return 0; +} + +static const struct ocf_io_if _io_if_pipeline = { + .read = _ocf_pipeline_run_step, + .write = _ocf_pipeline_run_step, +}; + +int ocf_pipeline_create(ocf_pipeline_t *pipeline, ocf_cache_t cache, + struct ocf_pipeline_properties *properties) +{ + ocf_pipeline_t tmp_pipeline; + struct ocf_request *req; + + tmp_pipeline = env_vzalloc(sizeof(*tmp_pipeline) + + properties->priv_size); + if (!tmp_pipeline) + return -OCF_ERR_NO_MEM; + + if (properties->priv_size > 0) { + tmp_pipeline->priv = (void *)tmp_pipeline + + sizeof(*tmp_pipeline); + } + + req = ocf_req_new(cache->mngt_queue, NULL, 0, 0, 0); + if (!req) { + env_vfree(tmp_pipeline); + return -OCF_ERR_NO_MEM; + } + + tmp_pipeline->properties = properties; + tmp_pipeline->req = req; + tmp_pipeline->next_step = 0; + tmp_pipeline->finish = false; + tmp_pipeline->error = 0; + + req->info.internal = true; + req->io_if = &_io_if_pipeline; + req->priv = tmp_pipeline; + + *pipeline = tmp_pipeline; + + return 0; +} + +void ocf_pipeline_destroy(ocf_pipeline_t pipeline) +{ + ocf_req_put(pipeline->req); + env_vfree(pipeline); +} + +void ocf_pipeline_set_priv(ocf_pipeline_t pipeline, void *priv) +{ + pipeline->priv = priv; +} + +void *ocf_pipeline_get_priv(ocf_pipeline_t pipeline) +{ + return pipeline->priv; +} + +void ocf_pipeline_next(ocf_pipeline_t pipeline) +{ + ocf_engine_push_req_front(pipeline->req, true); +} + +void ocf_pipeline_finish(ocf_pipeline_t pipeline, int error) +{ + pipeline->finish = true; + pipeline->error = error; + ocf_engine_push_req_front(pipeline->req, true); +} diff --git a/src/utils/utils_pipeline.h b/src/utils/utils_pipeline.h new file mode 100644 index 0000000..cd962f1 --- /dev/null +++ b/src/utils/utils_pipeline.h @@ -0,0 +1,134 @@ +/* + * Copyright(c) 2019 Intel Corporation + * SPDX-License-Identifier: BSD-3-Clause-Clear + */ + +#ifndef __UTILS_PIPELINE_H__ +#define __UTILS_PIPELINE_H__ + +#include "../ocf_cache_priv.h" + +enum ocf_pipeline_step_type { + ocf_pipeline_step_single, + ocf_pipeline_step_foreach, + ocf_pipeline_step_terminator, +}; + +enum ocf_pipeline_arg_type { + ocf_pipeline_arg_none, + ocf_pipeline_arg_int, + ocf_pipeline_arg_ptr, + ocf_pipeline_arg_terminator, +}; + +struct ocf_pipeline_arg { + enum ocf_pipeline_arg_type type; + union { + int i; + void *p; + } val; +}; + +typedef struct ocf_pipeline_arg *ocf_pipeline_arg_t; + +#define OCF_PL_ARG_NONE() \ + { .type = ocf_pipeline_arg_none, } + +#define OCF_PL_ARG_INT(_int) \ + { .type = ocf_pipeline_arg_int, .val.i = _int } + +#define OCF_PL_ARG_PTR(_ptr) \ + { .type = ocf_pipeline_arg_ptr, .val.p = _ptr } + +#define OCF_PL_ARG_TERMINATOR() \ + { .type = ocf_pipeline_arg_terminator, } + +static inline int ocf_pipeline_arg_get_int(ocf_pipeline_arg_t arg) +{ + ENV_BUG_ON(arg->type != ocf_pipeline_arg_int); + + return arg->val.i; +} + +static inline void *ocf_pipeline_arg_get_ptr(ocf_pipeline_arg_t arg) +{ + ENV_BUG_ON(arg->type != ocf_pipeline_arg_ptr); + + return arg->val.p; +} + +typedef struct ocf_pipeline *ocf_pipeline_t; + +typedef void (*ocf_pipeline_step_hndl_t)(ocf_pipeline_t pipeline, + void *priv, ocf_pipeline_arg_t arg); + +typedef void (*ocf_pipeline_finish_t)(ocf_pipeline_t pipeline, + void *priv, int error); + +struct ocf_pipeline_step { + enum ocf_pipeline_step_type type; + ocf_pipeline_step_hndl_t hndl; + union { + struct ocf_pipeline_arg arg; + struct ocf_pipeline_arg *args; + }; +}; + +#define OCF_PL_STEP(_hndl) \ + { \ + .type = ocf_pipeline_step_single, \ + .hndl = _hndl, \ + } + +#define OCF_PL_STEP_ARG_INT(_hndl, _int) \ + { \ + .type = ocf_pipeline_step_single, \ + .hndl = _hndl, \ + .arg = { \ + .type = ocf_pipeline_arg_int, \ + .val.i = _int, \ + } \ + } + +#define OCF_PL_STEP_ARG_PTR(_hndl, _ptr) \ + { \ + .type = ocf_pipeline_step_single, \ + .hndl = _hndl, \ + .arg = { \ + .type = ocf_pipeline_arg_ptr, \ + .val.p = _ptr, \ + } \ + } + +#define OCF_PL_STEP_FOREACH(_hndl, _args) \ + { \ + .type = ocf_pipeline_step_foreach, \ + .hndl = _hndl, \ + .args = _args, \ + } + +#define OCF_PL_STEP_TERMINATOR() \ + { \ + .type = ocf_pipeline_step_terminator, \ + } + +struct ocf_pipeline_properties { + uint32_t priv_size; + ocf_pipeline_finish_t finish; + struct ocf_pipeline_step steps[]; +}; + +int ocf_pipeline_create(ocf_pipeline_t *pipeline, ocf_cache_t cache, + struct ocf_pipeline_properties *properties); + +void ocf_pipeline_set_priv(ocf_pipeline_t pipeline, void *priv); + +void *ocf_pipeline_get_priv(ocf_pipeline_t pipeline); + +void ocf_pipeline_destroy(ocf_pipeline_t pipeline); + +void ocf_pipeline_next(ocf_pipeline_t pipeline); + +void ocf_pipeline_finish(ocf_pipeline_t pipeline, int error); + +#endif /* __UTILS_PIPELINE_H__ */ diff --git a/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mng_set_cache_mode_test.c b/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mng_set_cache_mode_test.c index b57addd..94f74a7 100644 --- a/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mng_set_cache_mode_test.c +++ b/tests/unit/tests/mngt/ocf_mngt_cache.c/_cache_mng_set_cache_mode_test.c @@ -34,6 +34,7 @@ #include "../utils/utils_device.h" #include "../utils/utils_io.h" #include "../utils/utils_cache_line.h" +#include "../utils/utils_pipeline.h" #include "../ocf_utils.h" #include "../concurrency/ocf_concurrency.h" #include "../eviction/ops.h" @@ -103,132 +104,152 @@ char *__wrap_ocf_cache_get_name(ocf_cache_t cache) } void __wrap__ocf_mngt_test_volume_initial_write( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_test_volume_first_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume_discard( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume_second_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_cache_device( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_check_ram( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_load_properties( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_prepare_metadata( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_load_superblock( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_init_instance( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_clean_pol( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_flush_metadata( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_discard( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_flush( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_shutdown_status( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_post_init( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_wait_io( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_remove_cores( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_unplug( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_put_io_queues( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_flush( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_wait_pending( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_update_metadata( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_unplug( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume_first_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) +{ +} + +void __wrap__ocf_mngt_test_volume_finish( + ocf_pipeline_t pipeline, void *priv, int error) +{ +} + +void __wrap__ocf_mngt_cache_attach_finish( + ocf_pipeline_t pipeline, void *priv, int error) +{ +} + +void __wrap_ocf_mngt_cache_stop_finish( + ocf_pipeline_t pipeline, void *priv, int error) +{ +} + +void __wrap_ocf_mngt_cache_detach_finish( + ocf_pipeline_t pipeline, void *priv, int error) { } diff --git a/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c b/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c index b506dc6..711c5ca 100644 --- a/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c +++ b/tests/unit/tests/mngt/ocf_mngt_cache.c/ocf_mngt_cache_set_fallback_pt_error_threshold.c @@ -29,6 +29,7 @@ #include "../utils/utils_device.h" #include "../utils/utils_io.h" #include "../utils/utils_cache_line.h" +#include "../utils/utils_pipeline.h" #include "../ocf_utils.h" #include "../concurrency/ocf_concurrency.h" #include "../eviction/ops.h" @@ -60,132 +61,152 @@ char *__wrap_ocf_cache_get_name(ocf_cache_t cache) } void __wrap__ocf_mngt_test_volume_initial_write( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_test_volume_first_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume_discard( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume_second_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_cache_device( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_check_ram( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_load_properties( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_prepare_metadata( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_load_superblock( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_init_instance( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_clean_pol( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_flush_metadata( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_discard( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_flush( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_shutdown_status( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_attach_post_init( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_wait_io( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_remove_cores( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_unplug( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_stop_put_io_queues( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_flush( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_wait_pending( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_update_metadata( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap_ocf_mngt_cache_detach_unplug( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) { } void __wrap__ocf_mngt_test_volume_first_read( - ocf_mngt_pipeline_t test_pipeline, void *priv) + ocf_pipeline_t pipeline, void *priv, ocf_pipeline_arg_t arg) +{ +} + +void __wrap__ocf_mngt_test_volume_finish( + ocf_pipeline_t pipeline, void *priv, int error) +{ +} + +void __wrap__ocf_mngt_cache_attach_finish( + ocf_pipeline_t pipeline, void *priv, int error) +{ +} + +void __wrap_ocf_mngt_cache_stop_finish( + ocf_pipeline_t pipeline, void *priv, int error) +{ +} + +void __wrap_ocf_mngt_cache_detach_finish( + ocf_pipeline_t pipeline, void *priv, int error) { }