diff --git a/inc/ocf_core.h b/inc/ocf_core.h index 2b16e53b..7dee1e78 100644 --- a/inc/ocf_core.h +++ b/inc/ocf_core.h @@ -178,30 +178,35 @@ static inline void ocf_core_submit_discard(ocf_io_t io) } /** - * @brief Core visitor function type which is called back when iterating over - * cores. + * @brief Get first core of given cache * - * @param[in] core Core which is currently iterated (visited) - * @param[in] cntx Visitor context + * @param[in] cache OCF cache instance + * @param[in] only_opened Get only opened core * - * @retval 0 continue visiting cores - * @retval Non-zero stop iterating and return result + * @retval First core of the cache, or NULL if there are no matching cores */ -typedef int (*ocf_core_visitor_t)(ocf_core_t core, void *cntx); +ocf_core_t ocf_core_get_first(ocf_cache_t cache, bool only_opened); /** - * @brief Run visitor function for each core of given cache + * @brief Get next core of given cache * - * @param[in] cache OCF cache instance - * @param[in] visitor Visitor function - * @param[in] cntx Visitor context - * @param[in] only_opened Visit only opened cores + * @param[in] core Current core + * @param[in] only_opened Get only opened core * - * @retval 0 Success - * @retval Non-zero Fail + * @retval Next core of the cache, or NULL if there are no more matching cores + */ +ocf_core_t ocf_core_get_next(ocf_core_t core, bool only_opened); + +/** + * @brief Iterate over all cores of given cache + * + * @param[out] _core Loop cursor of type ocf_core_t + * @param[in] _cache OCF cache instance + * @param[in] _only_opened Iterate over opened cores only */ -int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx, - bool only_opened); +#define ocf_core_for_each(_core, _cache, _only_opened) \ + for (_core = ocf_core_get_first(_cache, _only_opened); _core; \ + _core = ocf_core_get_next(_core, _only_opened)) /** * @brief Get info of given core object diff --git a/src/mngt/ocf_mngt_cache.c b/src/mngt/ocf_mngt_cache.c index 63bd1351..1cc51605 100644 --- a/src/mngt/ocf_mngt_cache.c +++ b/src/mngt/ocf_mngt_cache.c @@ -3270,21 +3270,13 @@ void ocf_mngt_cache_attach(ocf_cache_t cache, _ocf_mngt_cache_attach(cache, cfg, _ocf_mngt_cache_attach_complete, cmpl, priv); } -static int _ocf_mngt_cache_load_core_log(ocf_core_t core, void *cntx) -{ - if (ocf_core_state_active == ocf_core_get_state(core)) - ocf_core_log(core, log_info, "Successfully added\n"); - else - ocf_core_log(core, log_warn, "Failed to initialize\n"); - - return 0; -} - static void _ocf_mngt_cache_load_log(ocf_cache_t cache) { ocf_cache_mode_t cache_mode = ocf_cache_get_mode(cache); ocf_cleaning_t cleaning_type = cache->cleaner.policy; ocf_promotion_t promotion_type = cache->conf_meta->promotion_policy_type; + ocf_core_t core; + ocf_core_id_t core_id; ocf_cache_log(cache, log_info, "Successfully loaded\n"); ocf_cache_log(cache, log_info, "Cache mode : %s\n", @@ -3293,8 +3285,13 @@ static void _ocf_mngt_cache_load_log(ocf_cache_t cache) ocf_cleaning_get_name(cleaning_type)); ocf_cache_log(cache, log_info, "Promotion policy : %s\n", ocf_promotion_policies[promotion_type].name); - ocf_core_visit(cache, _ocf_mngt_cache_load_core_log, - cache, false); + + for_each_core(cache, core, core_id) { + if (ocf_core_state_active == ocf_core_get_state(core)) + ocf_core_log(core, log_info, "Successfully added\n"); + else + ocf_core_log(core, log_warn, "Failed to initialize\n"); + } } static void _ocf_mngt_cache_load_complete(ocf_cache_t cache, void *priv1, diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index 331a9cc4..6b65656d 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -1017,9 +1017,9 @@ int ocf_mngt_core_get_user_metadata(ocf_core_t core, void *data, size_t size) OCF_CORE_USER_DATA_SIZE); } -static int _cache_mngt_set_core_seq_cutoff_threshold(ocf_core_t core, void *cntx) +static int _cache_mngt_set_core_seq_cutoff_threshold(ocf_core_t core, + uint32_t threshold) { - uint32_t threshold = *(uint32_t*) cntx; uint32_t threshold_old = ocf_core_get_seq_cutoff_threshold(core); if (threshold < OCF_SEQ_CUTOFF_MIN_THRESHOLD || @@ -1058,12 +1058,16 @@ int ocf_mngt_core_set_seq_cutoff_threshold(ocf_core_t core, uint32_t thresh) if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return _cache_mngt_set_core_seq_cutoff_threshold(core, &thresh); + return _cache_mngt_set_core_seq_cutoff_threshold(core, thresh); } int ocf_mngt_core_set_seq_cutoff_threshold_all(ocf_cache_t cache, uint32_t thresh) { + ocf_core_t core; + ocf_core_id_t core_id; + int result; + OCF_CHECK_NULL(cache); if (ocf_cache_is_standby(cache)) @@ -1072,8 +1076,16 @@ int ocf_mngt_core_set_seq_cutoff_threshold_all(ocf_cache_t cache, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return ocf_core_visit(cache, _cache_mngt_set_core_seq_cutoff_threshold, - &thresh, true); + for_each_core(cache, core, core_id) { + if (!core->opened) + continue; + result = _cache_mngt_set_core_seq_cutoff_threshold(core, + thresh); + if (result) + return result; + } + + return 0; } int ocf_mngt_core_get_seq_cutoff_threshold(ocf_core_t core, uint32_t *thresh) @@ -1107,9 +1119,9 @@ static const char *_cache_mngt_seq_cutoff_policy_get_name( return _ocf_seq_cutoff_policy_names[policy]; } -static int _cache_mngt_set_core_seq_cutoff_policy(ocf_core_t core, void *cntx) +static int _cache_mngt_set_core_seq_cutoff_policy(ocf_core_t core, + ocf_seq_cutoff_policy policy) { - ocf_seq_cutoff_policy policy = *(ocf_seq_cutoff_policy*) cntx; uint32_t policy_old = ocf_core_get_seq_cutoff_policy(core); if (policy_old == policy) { @@ -1149,11 +1161,16 @@ int ocf_mngt_core_set_seq_cutoff_policy(ocf_core_t core, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return _cache_mngt_set_core_seq_cutoff_policy(core, &policy); + return _cache_mngt_set_core_seq_cutoff_policy(core, policy); } + int ocf_mngt_core_set_seq_cutoff_policy_all(ocf_cache_t cache, ocf_seq_cutoff_policy policy) { + ocf_core_t core; + ocf_core_id_t core_id; + int result; + OCF_CHECK_NULL(cache); if (ocf_cache_is_standby(cache)) @@ -1162,8 +1179,15 @@ int ocf_mngt_core_set_seq_cutoff_policy_all(ocf_cache_t cache, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return ocf_core_visit(cache, _cache_mngt_set_core_seq_cutoff_policy, - &policy, true); + for_each_core(cache, core, core_id) { + if (!core->opened) + continue; + result = _cache_mngt_set_core_seq_cutoff_policy(core, policy); + if (result) + return result; + } + + return 0; } int ocf_mngt_core_get_seq_cutoff_policy(ocf_core_t core, @@ -1184,9 +1208,8 @@ int ocf_mngt_core_get_seq_cutoff_policy(ocf_core_t core, } static int _cache_mngt_set_core_seq_detect_promo_count(ocf_core_t core, - void *cntx) + uint32_t count) { - uint32_t count = *(uint32_t*) cntx; uint32_t count_old = ocf_core_get_seq_detect_promotion_count(core); if (count < OCF_SEQ_DETECT_MIN_PROMOTION_COUNT || @@ -1226,12 +1249,16 @@ int ocf_mngt_core_set_seq_detect_promotion_count(ocf_core_t core, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return _cache_mngt_set_core_seq_detect_promo_count(core, &count); + return _cache_mngt_set_core_seq_detect_promo_count(core, count); } int ocf_mngt_core_set_seq_detect_promotion_count_all(ocf_cache_t cache, uint32_t count) { + ocf_core_t core; + ocf_core_id_t core_id; + int result; + OCF_CHECK_NULL(cache); if (ocf_cache_is_standby(cache)) @@ -1240,9 +1267,16 @@ int ocf_mngt_core_set_seq_detect_promotion_count_all(ocf_cache_t cache, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return ocf_core_visit(cache, - _cache_mngt_set_core_seq_detect_promo_count, - &count, true); + for_each_core(cache, core, core_id) { + if (!core->opened) + continue; + result = _cache_mngt_set_core_seq_detect_promo_count(core, + count); + if (result) + return result; + } + + return 0; } int ocf_mngt_core_get_seq_detect_promotion_count(ocf_core_t core, @@ -1263,9 +1297,8 @@ int ocf_mngt_core_get_seq_detect_promotion_count(ocf_core_t core, } static int _cache_mngt_set_core_seq_detect_promo_threshold( - ocf_core_t core, void *cntx) + ocf_core_t core, uint32_t threshold) { - uint32_t threshold = *(uint32_t *) cntx; uint32_t threshold_old = ocf_core_get_seq_detect_promotion_threshold(core); @@ -1307,13 +1340,16 @@ int ocf_mngt_core_set_seq_detect_promotion_threshold(ocf_core_t core, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return _cache_mngt_set_core_seq_detect_promo_threshold(core, - &threshold); + return _cache_mngt_set_core_seq_detect_promo_threshold(core, threshold); } int ocf_mngt_core_set_seq_detect_promotion_threshold_all(ocf_cache_t cache, uint32_t threshold) { + ocf_core_t core; + ocf_core_id_t core_id; + int result; + OCF_CHECK_NULL(cache); if (ocf_cache_is_standby(cache)) @@ -1322,9 +1358,16 @@ int ocf_mngt_core_set_seq_detect_promotion_threshold_all(ocf_cache_t cache, if (!ocf_cache_is_device_attached(cache)) return -OCF_ERR_CACHE_DETACHED; - return ocf_core_visit(cache, - _cache_mngt_set_core_seq_detect_promo_threshold, - &threshold, true); + for_each_core(cache, core, core_id) { + if (!core->opened) + continue; + result = _cache_mngt_set_core_seq_detect_promo_threshold(core, + threshold); + if (result) + return result; + } + + return 0; } int ocf_mngt_core_get_seq_detect_promotion_threshold(ocf_core_t core, diff --git a/src/ocf_core.c b/src/ocf_core.c index 60358971..86d307ee 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -120,33 +120,35 @@ uint32_t ocf_core_get_seq_detect_promotion_threshold(ocf_core_t core) &core->conf_meta->seq_detect_promotion_threshold); } -int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx, +static ocf_core_t _ocf_core_get_next_from(ocf_cache_t cache, ocf_core_id_t id, bool only_opened) { - ocf_core_id_t id; - int result = 0; - - OCF_CHECK_NULL(cache); - - if (ocf_cache_is_standby(cache)) - return -OCF_ERR_CACHE_STANDBY; - - if (!visitor) - return -OCF_ERR_INVAL; - - for (id = 0; id < OCF_CORE_NUM; id++) { + for (; id < OCF_CORE_NUM; id++) { if (!env_bit_test(id, cache->conf_meta->valid_core_bitmap)) continue; if (only_opened && !cache->core[id].opened) continue; - result = visitor(&cache->core[id], cntx); - if (result) - break; + return &cache->core[id]; } - return result; + return NULL; +} + +ocf_core_t ocf_core_get_first(ocf_cache_t cache, bool only_opened) +{ + OCF_CHECK_NULL(cache); + + return _ocf_core_get_next_from(cache, 0, only_opened); +} + +ocf_core_t ocf_core_get_next(ocf_core_t core, bool only_opened) +{ + OCF_CHECK_NULL(core); + + return _ocf_core_get_next_from(ocf_core_get_cache(core), + ocf_core_get_id(core) + 1, only_opened); } /* *** HELPER FUNCTIONS *** */ diff --git a/src/ocf_stats_builder.c b/src/ocf_stats_builder.c index d995bf49..bab87cd0 100644 --- a/src/ocf_stats_builder.c +++ b/src/ocf_stats_builder.c @@ -7,6 +7,7 @@ #include "ocf/ocf.h" #include "ocf_priv.h" +#include "ocf_cache_priv.h" #include "ocf_env.h" #include "metadata/metadata.h" #include "engine/cache_engine.h" @@ -303,18 +304,11 @@ static void _accumulate_errors(struct ocf_stats_error *to, to->write += from->write; } -struct io_class_stats_context { - struct ocf_stats_io_class *stats; - ocf_part_id_t part_id; -}; - -static int _accumulate_io_class_stats(ocf_core_t core, void *cntx) +static int _accumulate_io_class_stats(ocf_core_t core, ocf_part_id_t part_id, + struct ocf_stats_io_class *total) { int result; struct ocf_stats_io_class stats; - struct ocf_stats_io_class *total = - ((struct io_class_stats_context*)cntx)->stats; - ocf_part_id_t part_id = ((struct io_class_stats_context*)cntx)->part_id; ocf_pf_id_t pf_id; result = ocf_core_io_class_get_stats(core, part_id, &stats); @@ -418,8 +412,9 @@ int ocf_stats_collect_part_cache(ocf_cache_t cache, ocf_part_id_t part_id, struct ocf_stats_usage *usage, struct ocf_stats_requests *req, struct ocf_stats_blocks *blocks) { - struct io_class_stats_context ctx; struct ocf_stats_io_class s = {}; + ocf_core_t core; + ocf_core_id_t core_id; int result = 0; OCF_CHECK_NULL(cache); @@ -434,12 +429,13 @@ int ocf_stats_collect_part_cache(ocf_cache_t cache, ocf_part_id_t part_id, _ocf_stats_zero(req); _ocf_stats_zero(blocks); - ctx.part_id = part_id; - ctx.stats = &s; - - result = ocf_core_visit(cache, _accumulate_io_class_stats, &ctx, true); - if (result) - return result; + for_each_core(cache, core, core_id) { + if (!core->opened) + continue; + result = _accumulate_io_class_stats(core, part_id, &s); + if (result) + return result; + } _ocf_stats_part_fill(cache, part_id, &s, usage, req, blocks); @@ -515,9 +511,9 @@ int ocf_stats_collect_core(ocf_core_t core, return result; } -static int _accumulate_stats(ocf_core_t core, void *cntx) +static int _accumulate_stats(ocf_core_t core, struct ocf_stats_core *total) { - struct ocf_stats_core stats, *total = cntx; + struct ocf_stats_core stats; int result; ocf_pf_id_t pf_id; @@ -558,6 +554,8 @@ int ocf_stats_collect_cache(ocf_cache_t cache, uint64_t cache_line_size; struct ocf_cache_info info; struct ocf_stats_core *s; + ocf_core_t core; + ocf_core_id_t core_id; int result; OCF_CHECK_NULL(cache); @@ -582,9 +580,13 @@ int ocf_stats_collect_cache(ocf_cache_t cache, _ocf_stats_zero(blocks); _ocf_stats_zero(errors); - result = ocf_core_visit(cache, _accumulate_stats, s, true); - if (result) - goto mem_free; + for_each_core(cache, core, core_id) { + if (!core->opened) + continue; + result = _accumulate_stats(core, s); + if (result) + goto mem_free; + } if (usage) { _set(&usage->occupancy,