From 8304ed84b869240220b41b7bb0378990e261f335 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 29 Aug 2019 08:10:06 -0400 Subject: [PATCH 01/11] More precise percentage value in stats builder. Signed-off-by: Michal Mielewczyk --- inc/ocf_stats_builder.h | 4 ++-- src/ocf_stats_builder.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/inc/ocf_stats_builder.h b/inc/ocf_stats_builder.h index 48a67e6..d2e6989 100644 --- a/inc/ocf_stats_builder.h +++ b/inc/ocf_stats_builder.h @@ -20,8 +20,8 @@ struct ocf_stat { /** Value */ uint64_t value; - /** percent x10 */ - uint64_t percent; + /** percent x100 */ + uint64_t fraction; }; /** diff --git a/src/ocf_stats_builder.c b/src/ocf_stats_builder.c index f1d6948..476a02b 100644 --- a/src/ocf_stats_builder.c +++ b/src/ocf_stats_builder.c @@ -18,11 +18,11 @@ } \ } while (0) -static uint64_t _percentage(uint64_t numerator, uint64_t denominator) +static uint64_t _fraction(uint64_t numerator, uint64_t denominator) { uint64_t result; if (denominator) { - result = 1000 * numerator / denominator; + result = 10000 * numerator / denominator; } else { result = 0; } @@ -59,7 +59,7 @@ static uint64_t _get_cache_occupancy(ocf_cache_t cache) static void _set(struct ocf_stat *stat, uint64_t value, uint64_t denominator) { stat->value = value; - stat->percent = _percentage(value, denominator); + stat->fraction = _fraction(value, denominator); } static void _fill_req(struct ocf_stats_requests *req, struct ocf_stats_core *s) From 2450d3da4b58111d814b79f3b9a050d538fd4788 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Mon, 19 Aug 2019 07:50:41 -0400 Subject: [PATCH 02/11] Move block stats counters to ioclass section. Signed-off-by: Michal Mielewczyk --- src/ocf_stats.c | 10 ++++------ src/ocf_stats_priv.h | 6 +++--- src/utils/utils_cleaner.c | 18 ++++++++++-------- src/utils/utils_io.c | 14 +++++++------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/ocf_stats.c b/src/ocf_stats.c index 0cb49e0..574b2b4 100644 --- a/src/ocf_stats.c +++ b/src/ocf_stats.c @@ -47,6 +47,8 @@ static void ocf_stats_part_init(struct ocf_counters_part *stats) ocf_stats_req_init(&stats->write_reqs); ocf_stats_block_init(&stats->blocks); + ocf_stats_block_init(&stats->core_blocks); + ocf_stats_block_init(&stats->cache_blocks); } static void ocf_stats_error_init(struct ocf_counters_error *stats) @@ -77,9 +79,6 @@ void ocf_core_stats_initialize(ocf_core_t core) exp_obj_stats = core->counters; - ocf_stats_block_init(&exp_obj_stats->core_blocks); - ocf_stats_block_init(&exp_obj_stats->cache_blocks); - ocf_stats_error_init(&exp_obj_stats->cache_errors); ocf_stats_error_init(&exp_obj_stats->core_errors); @@ -240,9 +239,6 @@ int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats) env_atomic_read(&core->runtime_meta->cached_clines); - copy_block_stats(&stats->core_volume, &core_stats->core_blocks); - copy_block_stats(&stats->cache_volume, &core_stats->cache_blocks); - copy_error_stats(&stats->core_errors, &core_stats->core_errors); copy_error_stats(&stats->cache_errors, @@ -262,6 +258,8 @@ int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats) &curr->write_reqs); accum_block_stats(&stats->core, &curr->blocks); + accum_block_stats(&stats->core_volume, &curr->core_blocks); + accum_block_stats(&stats->cache_volume, &curr->cache_blocks); stats->cache_occupancy += env_atomic_read(&core->runtime_meta-> part_counters[i].cached_clines); diff --git a/src/ocf_stats_priv.h b/src/ocf_stats_priv.h index 71c3982..7d29199 100644 --- a/src/ocf_stats_priv.h +++ b/src/ocf_stats_priv.h @@ -31,6 +31,9 @@ struct ocf_counters_part { struct ocf_counters_req write_reqs; struct ocf_counters_block blocks; + + struct ocf_counters_block core_blocks; + struct ocf_counters_block cache_blocks; }; #ifdef OCF_DEBUG_STATS @@ -44,9 +47,6 @@ struct ocf_counters_debug { #endif struct ocf_counters_core { - struct ocf_counters_block core_blocks; - struct ocf_counters_block cache_blocks; - struct ocf_counters_error core_errors; struct ocf_counters_error cache_errors; diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index ad9c458..2bd5635 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -480,13 +480,14 @@ static void _ocf_cleaner_core_io_for_dirty_range(struct ocf_request *req, uint64_t addr, offset; int err; ocf_cache_t cache = req->cache; - ocf_core_t core = ocf_cache_get_core(cache, iter->core_id); struct ocf_io *io; - struct ocf_counters_block *core_stats = - &cache->core[iter->core_id].counters->core_blocks; + struct ocf_counters_block *core_stats; + ocf_core_t core = ocf_cache_get_core(cache, iter->core_id); ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); + core_stats = &core->counters->part_counters[part_id].core_blocks; + addr = (ocf_line_size(cache) * iter->core_line) + SECTORS_TO_BYTES(begin); offset = (ocf_line_size(cache) * iter->hash) @@ -637,7 +638,8 @@ static void _ocf_cleaner_cache_io_cmpl(struct ocf_io *io, int error) */ static int _ocf_cleaner_fire_cache(struct ocf_request *req) { - struct ocf_cache *cache = req->cache; + ocf_cache_t cache = req->cache; + ocf_core_t core; uint32_t i; struct ocf_map_info *iter = req->map; uint64_t addr, offset; @@ -650,14 +652,12 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) env_atomic_inc(&req->req_remaining); for (i = 0; i < req->core_line_count; i++, iter++) { - if (iter->core_id == OCF_CORE_MAX) + core = ocf_cache_get_core(cache, iter->core_id); + if (!core) continue; if (iter->status == LOOKUP_MISS) continue; - cache_stats = &cache->core[iter->core_id]. - counters->cache_blocks; - OCF_DEBUG_PARAM(req->cache, "Cache read, line = %u", iter->coll_idx); @@ -670,6 +670,8 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); + cache_stats = &core->counters->part_counters[part_id].cache_blocks; + io = ocf_new_cache_io(cache, req->io_queue, addr, ocf_line_size(cache), OCF_READ, part_id, 0); diff --git a/src/utils/utils_io.c b/src/utils/utils_io.c index c57e731..1137dc5 100644 --- a/src/utils/utils_io.c +++ b/src/utils/utils_io.c @@ -229,7 +229,7 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, { struct ocf_counters_block *cache_stats; uint64_t flags = req->ioi.io.flags; - uint32_t class = req->ioi.io.io_class; + uint32_t io_class = req->ioi.io.io_class; uint64_t addr, bytes, total_bytes = 0; struct ocf_io *io; int err; @@ -240,7 +240,7 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, ENV_BUG_ON(req->byte_length < offset + size); ENV_BUG_ON(first_cl + reqs > req->core_line_count); - cache_stats = &req->core->counters->cache_blocks; + cache_stats = &req->core->counters->part_counters[io_class].cache_blocks; if (reqs == 1) { addr = ocf_metadata_map_lg2phy(cache, @@ -251,7 +251,7 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, bytes = size; io = ocf_new_cache_io(cache, req->io_queue, - addr, bytes, dir, class, flags); + addr, bytes, dir, io_class, flags); if (!io) { callback(req, -OCF_ERR_NO_MEM); goto update_stats; @@ -298,7 +298,7 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, ENV_BUG_ON(bytes == 0); io = ocf_new_cache_io(cache, req->io_queue, - addr, bytes, dir, class, flags); + addr, bytes, dir, io_class, flags); if (!io) { /* Finish all IOs which left with ERROR */ for (; i < reqs; i++) @@ -334,19 +334,19 @@ void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req, { struct ocf_counters_block *core_stats; uint64_t flags = req->ioi.io.flags; - uint32_t class = req->ioi.io.io_class; + uint32_t io_class = req->ioi.io.io_class; int dir = req->rw; struct ocf_io *io; int err; - core_stats = &req->core->counters->core_blocks; + core_stats = &req->core->counters->part_counters[io_class].core_blocks; if (dir == OCF_WRITE) env_atomic64_add(req->byte_length, &core_stats->write_bytes); else if (dir == OCF_READ) env_atomic64_add(req->byte_length, &core_stats->read_bytes); io = ocf_volume_new_io(volume, req->io_queue, req->byte_position, - req->byte_length, dir, class, flags); + req->byte_length, dir, io_class, flags); if (!io) { callback(req, -OCF_ERR_NO_MEM); return; From f9da89263b34babbdbab2a585460cfd994d3b613 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Mon, 26 Aug 2019 07:23:05 -0400 Subject: [PATCH 03/11] Stats builder for ioclass statistics. Signed-off-by: Michal Mielewczyk --- inc/ocf_stats.h | 24 +++-- inc/ocf_stats_builder.h | 34 +++++- src/ocf_stats.c | 2 + src/ocf_stats_builder.c | 232 ++++++++++++++++++++++++++++++++++++---- 4 files changed, 259 insertions(+), 33 deletions(-) diff --git a/inc/ocf_stats.h b/inc/ocf_stats.h index cfafd68..f792d1a 100644 --- a/inc/ocf_stats.h +++ b/inc/ocf_stats.h @@ -62,15 +62,6 @@ struct ocf_stats_block { * Statistics appropriate for given IO class */ struct ocf_stats_io_class { - /** Read requests statistics */ - struct ocf_stats_req read_reqs; - - /** Writes requests statistics */ - struct ocf_stats_req write_reqs; - - /** Block requests statistics */ - struct ocf_stats_block blocks; - /** Number of cache lines available for given partition */ uint64_t free_clines; @@ -79,6 +70,21 @@ struct ocf_stats_io_class { /** Number of dirty cache lines assigned to specific partition */ uint64_t dirty_clines; + + /** Read requests statistics */ + struct ocf_stats_req read_reqs; + + /** Writes requests statistics */ + struct ocf_stats_req write_reqs; + + /** Block requests submitted by user to this core */ + struct ocf_stats_block blocks; + + /** Block requests for cache volume statistics */ + struct ocf_stats_block cache_blocks; + + /** Block requests for core volume statistics */ + struct ocf_stats_block core_blocks; }; #define IO_PACKET_NO 12 diff --git a/inc/ocf_stats_builder.h b/inc/ocf_stats_builder.h index d2e6989..1ee736d 100644 --- a/inc/ocf_stats_builder.h +++ b/inc/ocf_stats_builder.h @@ -172,7 +172,7 @@ int ocf_stats_collect_cache(ocf_cache_t cache, /** * @param Collect statistics for given core * - * @param cache Core for each statistics will be collected + * @param core Core for which statistics will be collected * @param usage Usage statistics * @param req Request statistics * @param blocks Blocks statistics @@ -187,4 +187,36 @@ int ocf_stats_collect_core(ocf_core_t core, struct ocf_stats_blocks *blocks, struct ocf_stats_errors *errors); +/** + * @param Collect statistics for given ioclass + * + * @param core Core handle for which statistics will be collected + * @param part_id Ioclass id for which statistics will be collected + * @param usage Usage statistics + * @param req Request statistics + * @param blocks Blocks statistics + * + * @retval 0 Success + * @retval Non-zero Error + */ +int ocf_stats_collect_part_core(ocf_core_t core, ocf_part_id_t part_id, + struct ocf_stats_usage *usage, struct ocf_stats_requests *req, + struct ocf_stats_blocks *blocks); + +/** + * @param Collect statistics for given ioclass + * + * @param cache Cache instance for which statistics will be collected + * @param part_id Ioclass id for which statistics will be collected + * @param usage Usage statistics + * @param req Request statistics + * @param blocks Blocks statistics + * + * @retval 0 Success + * @retval Non-zero Error + */ +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); + #endif /* __OCF_STATS_BUILDER_H__ */ diff --git a/src/ocf_stats.c b/src/ocf_stats.c index 574b2b4..b7f8880 100644 --- a/src/ocf_stats.c +++ b/src/ocf_stats.c @@ -198,6 +198,8 @@ int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id, copy_req_stats(&stats->write_reqs, &part_stat->write_reqs); copy_block_stats(&stats->blocks, &part_stat->blocks); + copy_block_stats(&stats->cache_blocks, &part_stat->cache_blocks); + copy_block_stats(&stats->core_blocks, &part_stat->core_blocks); return 0; } diff --git a/src/ocf_stats_builder.c b/src/ocf_stats_builder.c index 476a02b..53d33f3 100644 --- a/src/ocf_stats_builder.c +++ b/src/ocf_stats_builder.c @@ -94,6 +94,39 @@ static void _fill_req(struct ocf_stats_requests *req, struct ocf_stats_core *s) _set(&req->total, total, total); } +static void _fill_req_part(struct ocf_stats_requests *req, + struct ocf_stats_io_class *s) +{ + uint64_t serviced = s->read_reqs.total + s->write_reqs.total; + uint64_t total = serviced + s->read_reqs.pass_through + + s->write_reqs.pass_through; + uint64_t hit; + + /* Reads Section */ + hit = s->read_reqs.total - (s->read_reqs.full_miss + + s->read_reqs.partial_miss); + _set(&req->rd_hits, hit, total); + _set(&req->rd_partial_misses, s->read_reqs.partial_miss, total); + _set(&req->rd_full_misses, s->read_reqs.full_miss, total); + _set(&req->rd_total, s->read_reqs.total, total); + + /* Write Section */ + hit = s->write_reqs.total - (s->write_reqs.full_miss + + s->write_reqs.partial_miss); + _set(&req->wr_hits, hit, total); + _set(&req->wr_partial_misses, s->write_reqs.partial_miss, total); + _set(&req->wr_full_misses, s->write_reqs.full_miss, total); + _set(&req->wr_total, s->write_reqs.total, total); + + /* Pass-Through section */ + _set(&req->rd_pt, s->read_reqs.pass_through, total); + _set(&req->wr_pt, s->write_reqs.pass_through, total); + + /* Summary */ + _set(&req->serviced, serviced, total); + _set(&req->total, total, total); +} + static void _fill_blocks(struct ocf_stats_blocks *blocks, struct ocf_stats_core *s) { @@ -124,6 +157,36 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks, _set(&blocks->volume_total, total, total); } +static void _fill_blocks_part(struct ocf_stats_blocks *blocks, + struct ocf_stats_io_class *s) +{ + uint64_t rd, wr, total; + + /* Core volume */ + rd = _bytes4k(s->core_blocks.read); + wr = _bytes4k(s->core_blocks.write); + total = rd + wr; + _set(&blocks->core_volume_rd, rd, total); + _set(&blocks->core_volume_wr, wr, total); + _set(&blocks->core_volume_total, total, total); + + /* Cache volume */ + rd = _bytes4k(s->cache_blocks.read); + wr = _bytes4k(s->cache_blocks.write); + total = rd + wr; + _set(&blocks->cache_volume_rd, rd, total); + _set(&blocks->cache_volume_wr, wr, total); + _set(&blocks->cache_volume_total, total, total); + + /* Core (cache volume) */ + rd = _bytes4k(s->blocks.read); + wr = _bytes4k(s->blocks.write); + total = rd + wr; + _set(&blocks->volume_rd, rd, total); + _set(&blocks->volume_wr, wr, total); + _set(&blocks->volume_total, total, total); +} + static void _fill_errors(struct ocf_stats_errors *errors, struct ocf_stats_core *s) { @@ -149,6 +212,152 @@ static void _fill_errors(struct ocf_stats_errors *errors, _set(&errors->total, total, total); } +static void _accumulate_block(struct ocf_stats_block *to, + const struct ocf_stats_block *from) +{ + to->read += from->read; + to->write += from->write; +} + +static void _accumulate_reqs(struct ocf_stats_req *to, + const struct ocf_stats_req *from) +{ + to->full_miss += from->full_miss; + to->partial_miss += from->partial_miss; + to->total += from->total; + to->pass_through += from->pass_through; +} + +static void _accumulate_errors(struct ocf_stats_error *to, + const struct ocf_stats_error *from) +{ + to->read += from->read; + 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) +{ + 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; + + result = ocf_core_io_class_get_stats(core, part_id, &stats); + if (result) + return result; + + total->occupancy_clines += stats.occupancy_clines; + total->dirty_clines += stats.dirty_clines; + total->free_clines = stats.free_clines; + + _accumulate_block(&total->cache_blocks, &stats.cache_blocks); + _accumulate_block(&total->core_blocks, &stats.core_blocks); + _accumulate_block(&total->blocks, &stats.blocks); + + _accumulate_reqs(&total->read_reqs, &stats.read_reqs); + _accumulate_reqs(&total->write_reqs, &stats.write_reqs); + + return 0; +} + +static void _ocf_stats_part_fill(ocf_cache_t cache, ocf_part_id_t part_id, + struct ocf_stats_io_class *stats , struct ocf_stats_usage *usage, + struct ocf_stats_requests *req, struct ocf_stats_blocks *blocks) +{ + uint64_t cache_size, cache_line_size; + + cache_line_size = ocf_cache_get_line_size(cache); + cache_size = cache->conf_meta->cachelines; + + if (usage) { + _set(&usage->occupancy, + _lines4k(stats->occupancy_clines, cache_line_size), + _lines4k(cache_size, cache_line_size)); + + if (part_id == PARTITION_DEFAULT) { + _set(&usage->free, + _lines4k(stats->free_clines, cache_line_size), + _lines4k(cache_size, cache_line_size)); + } else { + _set(&usage->free, + _lines4k(0, cache_line_size), + _lines4k(0, cache_line_size)); + } + + _set(&usage->clean, + _lines4k(stats->occupancy_clines - stats->dirty_clines, + cache_line_size), + _lines4k(stats->occupancy_clines, cache_line_size)); + + _set(&usage->dirty, + _lines4k(stats->dirty_clines, cache_line_size), + _lines4k(stats->occupancy_clines, cache_line_size)); + } + + if (req) + _fill_req_part(req, stats); + + if (blocks) + _fill_blocks_part(blocks, stats); +} + +int ocf_stats_collect_part_core(ocf_core_t core, ocf_part_id_t part_id, + struct ocf_stats_usage *usage, struct ocf_stats_requests *req, + struct ocf_stats_blocks *blocks) +{ + struct ocf_stats_io_class s; + ocf_cache_t cache; + int result = 0; + + OCF_CHECK_NULL(core); + + cache = ocf_core_get_cache(core); + + _ocf_stats_zero(usage); + _ocf_stats_zero(req); + _ocf_stats_zero(blocks); + + result = ocf_core_io_class_get_stats(core, part_id, &s); + if (result) + return result; + + _ocf_stats_part_fill(cache, part_id, &s, usage, req, blocks); + + return result; +} + +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; + int result = 0; + + OCF_CHECK_NULL(cache); + + _ocf_stats_zero(usage); + _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; + + _ocf_stats_part_fill(cache, part_id, &s, usage, req, blocks); + + return result; +} + int ocf_stats_collect_core(ocf_core_t core, struct ocf_stats_usage *usage, struct ocf_stats_requests *req, @@ -206,29 +415,6 @@ int ocf_stats_collect_core(ocf_core_t core, return 0; } -static void _accumulate_block(struct ocf_stats_block *to, - const struct ocf_stats_block *from) -{ - to->read += from->read; - to->write += from->write; -} - -static void _accumulate_reqs(struct ocf_stats_req *to, - const struct ocf_stats_req *from) -{ - to->full_miss += from->full_miss; - to->partial_miss += from->partial_miss; - to->total += from->total; - to->pass_through += from->pass_through; -} - -static void _accumulate_errors(struct ocf_stats_error *to, - const struct ocf_stats_error *from) -{ - to->read += from->read; - to->write += from->write; -} - static int _accumulate_stats(ocf_core_t core, void *cntx) { struct ocf_stats_core stats, *total = cntx; From 89de6038c19130e314747c2a710b5033e81a53d0 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Mon, 2 Sep 2019 09:07:19 -0400 Subject: [PATCH 04/11] Split retrieving core stats and config info into two functions. Signed-off-by: Michal Mielewczyk --- inc/ocf_core.h | 37 +++++++++++++++++++++++++++++++++++++ inc/ocf_stats.h | 18 ------------------ src/ocf_core.c | 35 +++++++++++++++++++++++++++++++++++ src/ocf_stats.c | 27 --------------------------- 4 files changed, 72 insertions(+), 45 deletions(-) diff --git a/inc/ocf_core.h b/inc/ocf_core.h index 24b099c..435dd74 100644 --- a/inc/ocf_core.h +++ b/inc/ocf_core.h @@ -16,6 +16,32 @@ #include "ocf_io.h" #include "ocf_mngt.h" +struct ocf_core_info { + /** Core size in cache line size unit */ + uint64_t core_size; + + /** Core size in bytes unit */ + uint64_t core_size_bytes; + + /** Fields refers ongoing flush operation */ + struct { + /** Number of blocks flushed in ongoing flush operation */ + uint32_t flushed; + + /** Number of blocks left to flush in ongoing flush operation */ + uint32_t dirty; + }; + + /** How long core is dirty in seconds unit */ + uint32_t dirty_for; + + /** Sequential cutoff threshold (in bytes) */ + uint32_t seq_cutoff_threshold; + + /** Sequential cutoff policy */ + ocf_seq_cutoff_policy seq_cutoff_policy; +}; + /** * @brief Get OCF core by name * @@ -202,4 +228,15 @@ typedef int (*ocf_core_visitor_t)(ocf_core_t core, void *cntx); int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx, bool only_opened); +/** + * @brief Get info of given core object + * + * @param[in] core Core object + * @param[out] info Core info structure + * + * @retval 0 Success + * @retval Non-zero Fail + */ +int ocf_core_get_info(ocf_core_t core, struct ocf_core_info *info); + #endif /* __OCF_CORE_H__ */ diff --git a/inc/ocf_stats.h b/inc/ocf_stats.h index f792d1a..4906023 100644 --- a/inc/ocf_stats.h +++ b/inc/ocf_stats.h @@ -111,24 +111,12 @@ struct ocf_stats_core_debug { * @brief OCF core statistics */ struct ocf_stats_core { - /** Core size in cache line size unit */ - uint64_t core_size; - - /** Core size in bytes unit */ - uint64_t core_size_bytes; - /** Number of cache lines allocated in the cache for this core */ uint32_t cache_occupancy; /** Number of dirty cache lines allocated in the cache for this core */ uint32_t dirty; - /** Number of block flushed in ongoing flush operation */ - uint32_t flushed; - - /** How long core is dirty in seconds unit */ - uint32_t dirty_for; - /** Read requests statistics */ struct ocf_stats_req read_reqs; @@ -152,12 +140,6 @@ struct ocf_stats_core { /** Debug statistics */ struct ocf_stats_core_debug debug_stat; - - /** Sequential cutoff threshold (in bytes) */ - uint32_t seq_cutoff_threshold; - - /** Sequential cutoff policy */ - ocf_seq_cutoff_policy seq_cutoff_policy; }; /** diff --git a/src/ocf_core.c b/src/ocf_core.c index c346aee..5c8dcfe 100644 --- a/src/ocf_core.c +++ b/src/ocf_core.c @@ -143,6 +143,13 @@ int ocf_core_visit(ocf_cache_t cache, ocf_core_visitor_t visitor, void *cntx, /* *** HELPER FUNCTIONS *** */ +static uint32_t _calc_dirty_for(uint64_t dirty_since) +{ + return dirty_since ? + (env_ticks_to_msecs(env_get_tick_count() - dirty_since) / 1000) + : 0; +} + static inline struct ocf_request *ocf_io_to_req(struct ocf_io *io) { struct ocf_io_internal *ioi; @@ -585,3 +592,31 @@ int ocf_core_volume_type_init(ocf_ctx_t ctx) &ocf_core_volume_properties, &ocf_core_volume_extended); } + +int ocf_core_get_info(ocf_core_t core, struct ocf_core_info *info) +{ + ocf_cache_t cache; + + OCF_CHECK_NULL(core); + + cache = ocf_core_get_cache(core); + + if (!info) + return -OCF_ERR_INVAL; + + ENV_BUG_ON(env_memset(info, sizeof(*info), 0)); + + info->core_size_bytes = ocf_volume_get_length(&core->volume); + info->core_size = ocf_bytes_2_lines_round_up(cache, + info->core_size_bytes); + info->seq_cutoff_threshold = ocf_core_get_seq_cutoff_threshold(core); + info->seq_cutoff_policy = ocf_core_get_seq_cutoff_policy(core); + + info->flushed = env_atomic_read(&core->flushed); + info->dirty = env_atomic_read(&core->runtime_meta->dirty_clines); + + info->dirty_for = _calc_dirty_for( + env_atomic64_read(&core->runtime_meta->dirty_since)); + + return 0; +} diff --git a/src/ocf_stats.c b/src/ocf_stats.c index b7f8880..b670149 100644 --- a/src/ocf_stats.c +++ b/src/ocf_stats.c @@ -204,26 +204,14 @@ int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id, return 0; } -static uint32_t _calc_dirty_for(uint64_t dirty_since) -{ - return dirty_since ? - (env_ticks_to_msecs(env_get_tick_count() - dirty_since) / 1000) - : 0; -} - int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats) { uint32_t i; - ocf_core_id_t core_id; - ocf_cache_t cache; struct ocf_counters_core *core_stats = NULL; struct ocf_counters_part *curr = NULL; OCF_CHECK_NULL(core); - core_id = ocf_core_get_id(core); - cache = ocf_core_get_cache(core); - if (!stats) return -OCF_ERR_INVAL; @@ -231,16 +219,6 @@ int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats) ENV_BUG_ON(env_memset(stats, sizeof(*stats), 0)); - stats->core_size_bytes = ocf_volume_get_length( - &cache->core[core_id].volume); - stats->core_size = ocf_bytes_2_lines_round_up(cache, - stats->core_size_bytes); - stats->seq_cutoff_threshold = ocf_core_get_seq_cutoff_threshold(core); - stats->seq_cutoff_policy = ocf_core_get_seq_cutoff_policy(core); - - - env_atomic_read(&core->runtime_meta->cached_clines); - copy_error_stats(&stats->core_errors, &core_stats->core_errors); copy_error_stats(&stats->cache_errors, @@ -269,11 +247,6 @@ int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats) part_counters[i].dirty_clines); } - stats->flushed = env_atomic_read(&core->flushed); - - stats->dirty_for = _calc_dirty_for( - env_atomic64_read(&core->runtime_meta->dirty_since)); - return 0; } From 5f357272d13c59b3e321bf84957bbcf28aaaa94b Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Wed, 4 Sep 2019 07:37:52 -0400 Subject: [PATCH 05/11] pyocf: adjust pyocf to new core stats api Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/core.py | 20 ++++++++++---------- tests/functional/pyocf/types/stats/core.py | 11 +---------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/tests/functional/pyocf/types/core.py b/tests/functional/pyocf/types/core.py index 9d39683..5c2564e 100644 --- a/tests/functional/pyocf/types/core.py +++ b/tests/functional/pyocf/types/core.py @@ -25,7 +25,7 @@ from .data import Data from .io import Io, IoDir from .queue import Queue from .shared import Uuid, OcfCompletion, OcfError, SeqCutOffPolicy -from .stats.core import CoreStats +from .stats.core import CoreInfo from .stats.shared import UsageStats, RequestsStats, BlocksStats, ErrorsStats from .volume import Volume from ..ocf import OcfLib @@ -111,7 +111,7 @@ class Core: return Io.from_pointer(io) def get_stats(self): - core_stats = CoreStats() + core_info = CoreInfo() usage = UsageStats() req = RequestsStats() blocks = BlocksStats() @@ -125,8 +125,8 @@ class Core: self.cache.read_unlock() raise OcfError("Failed collecting core stats", status) - status = self.cache.owner.lib.ocf_core_get_stats( - self.handle, byref(core_stats) + status = self.cache.owner.lib.ocf_core_get_info( + self.handle, byref(core_info) ) if status: self.cache.read_unlock() @@ -134,10 +134,10 @@ class Core: self.cache.read_unlock() return { - "size": Size(core_stats.core_size_bytes), - "dirty_for": timedelta(seconds=core_stats.dirty_for), - "seq_cutoff_policy": SeqCutOffPolicy(core_stats.seq_cutoff_policy), - "seq_cutoff_threshold": core_stats.seq_cutoff_threshold, + "size": Size(core_info.core_size_bytes), + "dirty_for": timedelta(seconds=core_info.dirty_for), + "seq_cutoff_policy": SeqCutOffPolicy(core_info.seq_cutoff_policy), + "seq_cutoff_threshold": core_info.seq_cutoff_threshold, "usage": struct_to_dict(usage), "req": struct_to_dict(req), "blocks": struct_to_dict(blocks), @@ -207,8 +207,8 @@ lib.ocf_mngt_core_set_seq_cutoff_policy.argtypes = [c_void_p, c_uint32] lib.ocf_mngt_core_set_seq_cutoff_policy.restype = c_int lib.ocf_stats_collect_core.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] lib.ocf_stats_collect_core.restype = c_int -lib.ocf_core_get_stats.argtypes = [c_void_p, c_void_p] -lib.ocf_core_get_stats.restype = c_int +lib.ocf_core_get_info.argtypes = [c_void_p, c_void_p] +lib.ocf_core_get_info.restype = c_int lib.ocf_core_new_io_wrapper.argtypes = [ c_void_p, c_void_p, diff --git a/tests/functional/pyocf/types/stats/core.py b/tests/functional/pyocf/types/stats/core.py index 5aaacce..dd2d066 100644 --- a/tests/functional/pyocf/types/stats/core.py +++ b/tests/functional/pyocf/types/stats/core.py @@ -9,22 +9,13 @@ from ctypes import c_uint32, c_uint64, Structure from .shared import OcfStatsReq, OcfStatsBlock, OcfStatsDebug, OcfStatsError -class CoreStats(Structure): +class CoreInfo(Structure): _fields_ = [ ("core_size", c_uint64), ("core_size_bytes", c_uint64), - ("cache_occupancy", c_uint32), ("dirty", c_uint32), ("flushed", c_uint32), ("dirty_for", c_uint32), - ("read_reqs", OcfStatsReq), - ("write_reqs", OcfStatsReq), - ("cache_volume", OcfStatsBlock), - ("core_volume", OcfStatsBlock), - ("core", OcfStatsBlock), - ("cache_errors", OcfStatsError), - ("core_errors", OcfStatsError), - ("debug_stat", OcfStatsDebug), ("seq_cutoff_threshold", c_uint32), ("seq_cutoff_policy", c_uint32), ] From 42d6dbbf114484166dd3b6f2369eb92f56f624ce Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 3 Sep 2019 04:15:36 -0400 Subject: [PATCH 06/11] Remove low-level stats getters from public API. Since stats builder is implemented for retrieving cache, core and ioclass stats, adapters should use it instead. Signed-off-by: Michal Mielewczyk --- inc/ocf.h | 1 - inc/ocf_stats.h | 326 ++++++++++++++++++++++------------------ inc/ocf_stats_builder.h | 222 --------------------------- src/ocf_stats_priv.h | 167 ++++++++++++++++++++ 4 files changed, 348 insertions(+), 368 deletions(-) delete mode 100644 inc/ocf_stats_builder.h diff --git a/inc/ocf.h b/inc/ocf.h index 07c98b0..7b01411 100644 --- a/inc/ocf.h +++ b/inc/ocf.h @@ -29,7 +29,6 @@ #include "ocf_metadata_updater.h" #include "ocf_io_class.h" #include "ocf_stats.h" -#include "ocf_stats_builder.h" #include "ocf_mngt.h" #include "ocf_ctx.h" #include "ocf_err.h" diff --git a/inc/ocf_stats.h b/inc/ocf_stats.h index 4906023..141483b 100644 --- a/inc/ocf_stats.h +++ b/inc/ocf_stats.h @@ -14,133 +14,210 @@ #ifndef __OCF_STATS_H__ #define __OCF_STATS_H__ -struct ocf_io; +/** + * Entire row of statistcs + */ +struct ocf_stat { + /** Value */ + uint64_t value; + /** percent x100 */ + uint64_t fraction; +}; /** - * @brief OCF requests statistics like hit, miss, etc... + * @brief Usage statistics in 4 KiB unit * - * @note To calculate number of hits request do: - * total - (partial_miss + full_miss) + * An example of presenting statistics: + *
+ * ╔══════════════════╤══════════╤═══════╤═════════════╗
+ * ║ Usage statistics │  Count   │   %   │   Units     ║
+ * ╠══════════════════╪══════════╪═══════╪═════════════╣
+ * ║ Occupancy        │       20 │  50.0 │ 4KiB blocks ║
+ * ║ Free             │       20 │  50.0 │ 4KiB blocks ║
+ * ║ Clean            │       15 │  75.0 │ 4KiB blocks ║
+ * ║ Dirty            │        5 │  25.0 │ 4KiB blocks ║
+ * ╚══════════════════╧══════════╧═══════╧═════════════╝
+ * 
*/ -struct ocf_stats_req { - /** Number of partial misses */ - uint64_t partial_miss; - - /** Number of full misses */ - uint64_t full_miss; - - /** Total of requests */ - uint64_t total; - - /** Pass-through requests */ - uint64_t pass_through; +struct ocf_stats_usage { + struct ocf_stat occupancy; + struct ocf_stat free; + struct ocf_stat clean; + struct ocf_stat dirty; }; /** - * @brief OCF error statistics + * @brief Requests statistcs + * + * An example of presenting statistics: + *
+ * ╔══════════════════════╤═══════╤═══════╤══════════╗
+ * ║ Request statistics   │ Count │   %   │ Units    ║
+ * ╠══════════════════════╪═══════╪═══════╪══════════╣
+ * ║ Read hits            │    10 │   4.5 │ Requests ║
+ * ║ Read partial misses  │     1 │   0.5 │ Requests ║
+ * ║ Read full misses     │   211 │  95.0 │ Requests ║
+ * ║ Read total           │   222 │ 100.0 │ Requests ║
+ * ╟──────────────────────┼───────┼───────┼──────────╢
+ * ║ Write hits           │     0 │   0.0 │ Requests ║
+ * ║ Write partial misses │     0 │   0.0 │ Requests ║
+ * ║ Write full misses    │     0 │   0.0 │ Requests ║
+ * ║ Write total          │     0 │   0.0 │ Requests ║
+ * ╟──────────────────────┼───────┼───────┼──────────╢
+ * ║ Pass-Through reads   │     0 │   0.0 │ Requests ║
+ * ║ Pass-Through writes  │     0 │   0.0 │ Requests ║
+ * ║ Serviced requests    │   222 │ 100.0 │ Requests ║
+ * ╟──────────────────────┼───────┼───────┼──────────╢
+ * ║ Total requests       │   222 │ 100.0 │ Requests ║
+ * ╚══════════════════════╧═══════╧═══════╧══════════╝
+ * 
*/ -struct ocf_stats_error { - /** Read errors */ - uint32_t read; - - /** Write errors */ - uint32_t write; +struct ocf_stats_requests { + struct ocf_stat rd_hits; + struct ocf_stat rd_partial_misses; + struct ocf_stat rd_full_misses; + struct ocf_stat rd_total; + struct ocf_stat wr_hits; + struct ocf_stat wr_partial_misses; + struct ocf_stat wr_full_misses; + struct ocf_stat wr_total; + struct ocf_stat rd_pt; + struct ocf_stat wr_pt; + struct ocf_stat serviced; + struct ocf_stat total; }; /** - * @brief OCF block statistics in bytes + * @brief Block statistics + * + * An example of presenting statistics: + *
+ * ╔════════════════════════════════════╤═══════╤═══════╤═════════════╗
+ * ║ Block statistics                   │ Count │   %   │   Units     ║
+ * ╠════════════════════════════════════╪═══════╪═══════╪═════════════╣
+ * ║ Reads from core volume(s)          │   426 │ 100.0 │ 4KiB blocks ║
+ * ║ Writes to core volume(s)           │     0 │   0.0 │ 4KiB blocks ║
+ * ║ Total to/from core volume (s)      │   426 │ 100.0 │ 4KiB blocks ║
+ * ╟────────────────────────────────────┼───────┼───────┼─────────────╢
+ * ║ Reads from cache volume            │    13 │   3.0 │ 4KiB blocks ║
+ * ║ Writes to cache volume             │   426 │  97.0 │ 4KiB blocks ║
+ * ║ Total to/from cache volume         │   439 │ 100.0 │ 4KiB blocks ║
+ * ╟────────────────────────────────────┼───────┼───────┼─────────────╢
+ * ║ Reads from core(s)                 │   439 │ 100.0 │ 4KiB blocks ║
+ * ║ Writes to core(s)                  │     0 │   0.0 │ 4KiB blocks ║
+ * ║ Total to/from core(s)              │   439 │ 100.0 │ 4KiB blocks ║
+ * ╚════════════════════════════════════╧═══════╧═══════╧═════════════╝
+ * 
*/ -struct ocf_stats_block { - /** Number of blocks read */ - uint64_t read; - - /** Number of blocks written */ - uint64_t write; +struct ocf_stats_blocks { + struct ocf_stat core_volume_rd; + struct ocf_stat core_volume_wr; + struct ocf_stat core_volume_total; + struct ocf_stat cache_volume_rd; + struct ocf_stat cache_volume_wr; + struct ocf_stat cache_volume_total; + struct ocf_stat volume_rd; + struct ocf_stat volume_wr; + struct ocf_stat volume_total; }; /** - * Statistics appropriate for given IO class + * @brief Errors statistics + * + * An example of presenting statistics: + *
+ * ╔════════════════════╤═══════╤═════╤══════════╗
+ * ║ Error statistics   │ Count │  %  │ Units    ║
+ * ╠════════════════════╪═══════╪═════╪══════════╣
+ * ║ Cache read errors  │     0 │ 0.0 │ Requests ║
+ * ║ Cache write errors │     0 │ 0.0 │ Requests ║
+ * ║ Cache total errors │     0 │ 0.0 │ Requests ║
+ * ╟────────────────────┼───────┼─────┼──────────╢
+ * ║ Core read errors   │     0 │ 0.0 │ Requests ║
+ * ║ Core write errors  │     0 │ 0.0 │ Requests ║
+ * ║ Core total errors  │     0 │ 0.0 │ Requests ║
+ * ╟────────────────────┼───────┼─────┼──────────╢
+ * ║ Total errors       │     0 │ 0.0 │ Requests ║
+ * ╚════════════════════╧═══════╧═════╧══════════╝
+ * 
*/ -struct ocf_stats_io_class { - /** Number of cache lines available for given partition */ - uint64_t free_clines; - - /** Number of cache lines within lru list */ - uint64_t occupancy_clines; - - /** Number of dirty cache lines assigned to specific partition */ - uint64_t dirty_clines; - - /** Read requests statistics */ - struct ocf_stats_req read_reqs; - - /** Writes requests statistics */ - struct ocf_stats_req write_reqs; - - /** Block requests submitted by user to this core */ - struct ocf_stats_block blocks; - - /** Block requests for cache volume statistics */ - struct ocf_stats_block cache_blocks; - - /** Block requests for core volume statistics */ - struct ocf_stats_block core_blocks; -}; - -#define IO_PACKET_NO 12 -#define IO_ALIGN_NO 4 - -/** - * @brief Core debug statistics - */ -struct ocf_stats_core_debug { - /** I/O sizes being read (grouped by packets) */ - uint64_t read_size[IO_PACKET_NO]; - - /** I/O sizes being written (grouped by packets) */ - uint64_t write_size[IO_PACKET_NO]; - - /** I/O alignment for reads */ - uint64_t read_align[IO_ALIGN_NO]; - - /** I/O alignment for writes */ - uint64_t write_align[IO_ALIGN_NO]; +struct ocf_stats_errors { + struct ocf_stat core_volume_rd; + struct ocf_stat core_volume_wr; + struct ocf_stat core_volume_total; + struct ocf_stat cache_volume_rd; + struct ocf_stat cache_volume_wr; + struct ocf_stat cache_volume_total; + struct ocf_stat total; }; /** - * @brief OCF core statistics + * @param Collect statistics for given cache + * + * @param cache Cache instance for which statistics will be collected + * @param usage Usage statistics + * @param req Request statistics + * @param blocks Blocks statistics + * @param errors Errors statistics + * + * @retval 0 Success + * @retval Non-zero Error */ -struct ocf_stats_core { - /** Number of cache lines allocated in the cache for this core */ - uint32_t cache_occupancy; +int ocf_stats_collect_cache(ocf_cache_t cache, + struct ocf_stats_usage *usage, + struct ocf_stats_requests *req, + struct ocf_stats_blocks *blocks, + struct ocf_stats_errors *errors); - /** Number of dirty cache lines allocated in the cache for this core */ - uint32_t dirty; +/** + * @param Collect statistics for given core + * + * @param core Core for which statistics will be collected + * @param usage Usage statistics + * @param req Request statistics + * @param blocks Blocks statistics + * @param errors Errors statistics + * + * @retval 0 Success + * @retval Non-zero Error + */ +int ocf_stats_collect_core(ocf_core_t core, + struct ocf_stats_usage *usage, + struct ocf_stats_requests *req, + struct ocf_stats_blocks *blocks, + struct ocf_stats_errors *errors); - /** Read requests statistics */ - struct ocf_stats_req read_reqs; +/** + * @param Collect statistics for given ioclass + * + * @param core Core handle for which statistics will be collected + * @param part_id Ioclass id for which statistics will be collected + * @param usage Usage statistics + * @param req Request statistics + * @param blocks Blocks statistics + * + * @retval 0 Success + * @retval Non-zero Error + */ +int ocf_stats_collect_part_core(ocf_core_t core, ocf_part_id_t part_id, + struct ocf_stats_usage *usage, struct ocf_stats_requests *req, + struct ocf_stats_blocks *blocks); - /** Write requests statistics */ - struct ocf_stats_req write_reqs; - - /** Block requests for cache volume statistics */ - struct ocf_stats_block cache_volume; - - /** Block requests for core volume statistics */ - struct ocf_stats_block core_volume; - - /** Block requests submitted by user to this core */ - struct ocf_stats_block core; - - /** Cache volume error statistics */ - struct ocf_stats_error cache_errors; - - /** Core volume error statistics */ - struct ocf_stats_error core_errors; - - /** Debug statistics */ - struct ocf_stats_core_debug debug_stat; -}; +/** + * @param Collect statistics for given ioclass + * + * @param cache Cache instance for which statistics will be collected + * @param part_id Ioclass id for which statistics will be collected + * @param usage Usage statistics + * @param req Request statistics + * @param blocks Blocks statistics + * + * @retval 0 Success + * @retval Non-zero Error + */ +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); /** * @brief Initialize or reset core statistics @@ -160,45 +237,4 @@ void ocf_core_stats_initialize(ocf_core_t core); */ void ocf_core_stats_initialize_all(ocf_cache_t cache); -/** - * @brief ocf_core_io_class_get_stats retrieve io class statistics - * for given core - * - * Retrieve buffer of cache statistics for given cache instance. - * - * @param[in] core core handle to which request pertains - * @param[in] part_id IO class, stats of which are requested - * @param[out] stats statistic structure that shall be filled as - * a result of this function invocation. - * - * @result zero upon successful completion; error code otherwise - */ -int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id, - struct ocf_stats_io_class *stats); - -/** - * @brief retrieve core stats - * - * Retrieve ocf per core stats (for all IO classes together) - * - * @param[in] core core ID to which request pertains - * @param[out] stats statistics structure that shall be filled as - * a result of this function invocation. - * - * @result zero upon successful completion; error code otherwise - */ -int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats); - -/** - * @brief update stats given IO request - * - * Function meant to update stats for IO request. - * - * @note This function shall be invoked for eac IO request processed - * - * @param[in] core to which request pertains - * @param[in] io request for which stats are being updated - */ -void ocf_core_update_stats(ocf_core_t core, struct ocf_io *io); - #endif /* __OCF_STATS_H__ */ diff --git a/inc/ocf_stats_builder.h b/inc/ocf_stats_builder.h deleted file mode 100644 index 1ee736d..0000000 --- a/inc/ocf_stats_builder.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright(c) 2012-2018 Intel Corporation - * SPDX-License-Identifier: BSD-3-Clause-Clear - */ - -/** - * @file - * @brief OCF API for collecting statistics - * - * This file contains routines pertaining to retrieval and - * manipulation of OCF IO statistics. - */ - -#ifndef __OCF_STATS_BUILDER_H__ -#define __OCF_STATS_BUILDER_H__ - -/** - * Entire row of statistcs - */ -struct ocf_stat { - /** Value */ - uint64_t value; - /** percent x100 */ - uint64_t fraction; -}; - -/** - * @brief Usage statistics in 4 KiB unit - * - * An example of presenting statistics: - *
- * ╔══════════════════╤══════════╤═══════╤═════════════╗
- * ║ Usage statistics │  Count   │   %   │   Units     ║
- * ╠══════════════════╪══════════╪═══════╪═════════════╣
- * ║ Occupancy        │       20 │  50.0 │ 4KiB blocks ║
- * ║ Free             │       20 │  50.0 │ 4KiB blocks ║
- * ║ Clean            │       15 │  75.0 │ 4KiB blocks ║
- * ║ Dirty            │        5 │  25.0 │ 4KiB blocks ║
- * ╚══════════════════╧══════════╧═══════╧═════════════╝
- * 
- */ -struct ocf_stats_usage { - struct ocf_stat occupancy; - struct ocf_stat free; - struct ocf_stat clean; - struct ocf_stat dirty; -}; - -/** - * @brief Requests statistcs - * - * An example of presenting statistics: - *
- * ╔══════════════════════╤═══════╤═══════╤══════════╗
- * ║ Request statistics   │ Count │   %   │ Units    ║
- * ╠══════════════════════╪═══════╪═══════╪══════════╣
- * ║ Read hits            │    10 │   4.5 │ Requests ║
- * ║ Read partial misses  │     1 │   0.5 │ Requests ║
- * ║ Read full misses     │   211 │  95.0 │ Requests ║
- * ║ Read total           │   222 │ 100.0 │ Requests ║
- * ╟──────────────────────┼───────┼───────┼──────────╢
- * ║ Write hits           │     0 │   0.0 │ Requests ║
- * ║ Write partial misses │     0 │   0.0 │ Requests ║
- * ║ Write full misses    │     0 │   0.0 │ Requests ║
- * ║ Write total          │     0 │   0.0 │ Requests ║
- * ╟──────────────────────┼───────┼───────┼──────────╢
- * ║ Pass-Through reads   │     0 │   0.0 │ Requests ║
- * ║ Pass-Through writes  │     0 │   0.0 │ Requests ║
- * ║ Serviced requests    │   222 │ 100.0 │ Requests ║
- * ╟──────────────────────┼───────┼───────┼──────────╢
- * ║ Total requests       │   222 │ 100.0 │ Requests ║
- * ╚══════════════════════╧═══════╧═══════╧══════════╝
- * 
- */ -struct ocf_stats_requests { - struct ocf_stat rd_hits; - struct ocf_stat rd_partial_misses; - struct ocf_stat rd_full_misses; - struct ocf_stat rd_total; - struct ocf_stat wr_hits; - struct ocf_stat wr_partial_misses; - struct ocf_stat wr_full_misses; - struct ocf_stat wr_total; - struct ocf_stat rd_pt; - struct ocf_stat wr_pt; - struct ocf_stat serviced; - struct ocf_stat total; -}; - -/** - * @brief Block statistics - * - * An example of presenting statistics: - *
- * ╔════════════════════════════════════╤═══════╤═══════╤═════════════╗
- * ║ Block statistics                   │ Count │   %   │   Units     ║
- * ╠════════════════════════════════════╪═══════╪═══════╪═════════════╣
- * ║ Reads from core volume(s)     │   426 │ 100.0 │ 4KiB blocks ║
- * ║ Writes to core volume(s)      │     0 │   0.0 │ 4KiB blocks ║
- * ║ Total to/from core volume (s) │   426 │ 100.0 │ 4KiB blocks ║
- * ╟────────────────────────────────────┼───────┼───────┼─────────────╢
- * ║ Reads from cache volume       │    13 │   3.0 │ 4KiB blocks ║
- * ║ Writes to cache volume        │   426 │  97.0 │ 4KiB blocks ║
- * ║ Total to/from cache volume    │   439 │ 100.0 │ 4KiB blocks ║
- * ╟────────────────────────────────────┼───────┼───────┼─────────────╢
- * ║ Reads from core(s)                 │   439 │ 100.0 │ 4KiB blocks ║
- * ║ Writes to core(s)                  │     0 │   0.0 │ 4KiB blocks ║
- * ║ Total to/from core(s)              │   439 │ 100.0 │ 4KiB blocks ║
- * ╚════════════════════════════════════╧═══════╧═══════╧═════════════╝
- * 
- */ -struct ocf_stats_blocks { - struct ocf_stat core_volume_rd; - struct ocf_stat core_volume_wr; - struct ocf_stat core_volume_total; - struct ocf_stat cache_volume_rd; - struct ocf_stat cache_volume_wr; - struct ocf_stat cache_volume_total; - struct ocf_stat volume_rd; - struct ocf_stat volume_wr; - struct ocf_stat volume_total; -}; - -/** - * @brief Errors statistics - * - * An example of presenting statistics: - *
- * ╔════════════════════╤═══════╤═════╤══════════╗
- * ║ Error statistics   │ Count │  %  │ Units    ║
- * ╠════════════════════╪═══════╪═════╪══════════╣
- * ║ Cache read errors  │     0 │ 0.0 │ Requests ║
- * ║ Cache write errors │     0 │ 0.0 │ Requests ║
- * ║ Cache total errors │     0 │ 0.0 │ Requests ║
- * ╟────────────────────┼───────┼─────┼──────────╢
- * ║ Core read errors   │     0 │ 0.0 │ Requests ║
- * ║ Core write errors  │     0 │ 0.0 │ Requests ║
- * ║ Core total errors  │     0 │ 0.0 │ Requests ║
- * ╟────────────────────┼───────┼─────┼──────────╢
- * ║ Total errors       │     0 │ 0.0 │ Requests ║
- * ╚════════════════════╧═══════╧═════╧══════════╝
- * 
- */ -struct ocf_stats_errors { - struct ocf_stat core_volume_rd; - struct ocf_stat core_volume_wr; - struct ocf_stat core_volume_total; - struct ocf_stat cache_volume_rd; - struct ocf_stat cache_volume_wr; - struct ocf_stat cache_volume_total; - struct ocf_stat total; -}; - -/** - * @param Collect statistics for given cache - * - * @param cache Cache instance for each statistics will be collected - * @param usage Usage statistics - * @param req Request statistics - * @param blocks Blocks statistics - * @param errors Errors statistics - * - * @retval 0 Success - * @retval Non-zero Error - */ -int ocf_stats_collect_cache(ocf_cache_t cache, - struct ocf_stats_usage *usage, - struct ocf_stats_requests *req, - struct ocf_stats_blocks *blocks, - struct ocf_stats_errors *errors); - -/** - * @param Collect statistics for given core - * - * @param core Core for which statistics will be collected - * @param usage Usage statistics - * @param req Request statistics - * @param blocks Blocks statistics - * @param errors Errors statistics - * - * @retval 0 Success - * @retval Non-zero Error - */ -int ocf_stats_collect_core(ocf_core_t core, - struct ocf_stats_usage *usage, - struct ocf_stats_requests *req, - struct ocf_stats_blocks *blocks, - struct ocf_stats_errors *errors); - -/** - * @param Collect statistics for given ioclass - * - * @param core Core handle for which statistics will be collected - * @param part_id Ioclass id for which statistics will be collected - * @param usage Usage statistics - * @param req Request statistics - * @param blocks Blocks statistics - * - * @retval 0 Success - * @retval Non-zero Error - */ -int ocf_stats_collect_part_core(ocf_core_t core, ocf_part_id_t part_id, - struct ocf_stats_usage *usage, struct ocf_stats_requests *req, - struct ocf_stats_blocks *blocks); - -/** - * @param Collect statistics for given ioclass - * - * @param cache Cache instance for which statistics will be collected - * @param part_id Ioclass id for which statistics will be collected - * @param usage Usage statistics - * @param req Request statistics - * @param blocks Blocks statistics - * - * @retval 0 Success - * @retval Non-zero Error - */ -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); - -#endif /* __OCF_STATS_BUILDER_H__ */ diff --git a/src/ocf_stats_priv.h b/src/ocf_stats_priv.h index 7d29199..93c65c9 100644 --- a/src/ocf_stats_priv.h +++ b/src/ocf_stats_priv.h @@ -23,6 +23,132 @@ struct ocf_counters_req { env_atomic64 pass_through; }; +/** + * @brief OCF requests statistics like hit, miss, etc... + * + * @note To calculate number of hits request do: + * total - (partial_miss + full_miss) + */ +struct ocf_stats_req { + /** Number of partial misses */ + uint64_t partial_miss; + + /** Number of full misses */ + uint64_t full_miss; + + /** Total of requests */ + uint64_t total; + + /** Pass-through requests */ + uint64_t pass_through; +}; + +/** + * @brief OCF error statistics + */ +struct ocf_stats_error { + /** Read errors */ + uint32_t read; + + /** Write errors */ + uint32_t write; +}; + +/** + * @brief OCF block statistics in bytes + */ +struct ocf_stats_block { + /** Number of blocks read */ + uint64_t read; + + /** Number of blocks written */ + uint64_t write; +}; + +/** + * Statistics appropriate for given IO class + */ +struct ocf_stats_io_class { + /** Number of cache lines available for given partition */ + uint64_t free_clines; + + /** Number of cache lines within lru list */ + uint64_t occupancy_clines; + + /** Number of dirty cache lines assigned to specific partition */ + uint64_t dirty_clines; + + /** Read requests statistics */ + struct ocf_stats_req read_reqs; + + /** Writes requests statistics */ + struct ocf_stats_req write_reqs; + + /** Block requests for ocf volume statistics */ + struct ocf_stats_block blocks; + + /** Block requests for cache volume statistics */ + struct ocf_stats_block cache_blocks; + + /** Block requests for core volume statistics */ + struct ocf_stats_block core_blocks; +}; + +#define IO_PACKET_NO 12 +#define IO_ALIGN_NO 4 + +/** + * @brief Core debug statistics + */ +struct ocf_stats_core_debug { + /** I/O sizes being read (grouped by packets) */ + uint64_t read_size[IO_PACKET_NO]; + + /** I/O sizes being written (grouped by packets) */ + uint64_t write_size[IO_PACKET_NO]; + + /** I/O alignment for reads */ + uint64_t read_align[IO_ALIGN_NO]; + + /** I/O alignment for writes */ + uint64_t write_align[IO_ALIGN_NO]; +}; + +/** + * @brief OCF core statistics + */ +struct ocf_stats_core { + /** Number of cache lines allocated in the cache for this core */ + uint32_t cache_occupancy; + + /** Number of dirty cache lines allocated in the cache for this core */ + uint32_t dirty; + + /** Read requests statistics */ + struct ocf_stats_req read_reqs; + + /** Write requests statistics */ + struct ocf_stats_req write_reqs; + + /** Block requests for cache volume statistics */ + struct ocf_stats_block cache_volume; + + /** Block requests for core volume statistics */ + struct ocf_stats_block core_volume; + + /** Block requests submitted by user to this core */ + struct ocf_stats_block core; + + /** Cache volume error statistics */ + struct ocf_stats_error cache_errors; + + /** Core volume error statistics */ + struct ocf_stats_error core_errors; + + /** Debug statistics */ + struct ocf_stats_core_debug debug_stat; +}; + /** * statistics appropriate for given io class. */ @@ -56,4 +182,45 @@ struct ocf_counters_core { #endif }; +/** + * @brief ocf_core_io_class_get_stats retrieve io class statistics + * for given core + * + * Retrieve buffer of cache statistics for given cache instance. + * + * @param[in] core core handle to which request pertains + * @param[in] part_id IO class, stats of which are requested + * @param[out] stats statistic structure that shall be filled as + * a result of this function invocation. + * + * @result zero upon successful completion; error code otherwise + */ +int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id, + struct ocf_stats_io_class *stats); + +/** + * @brief retrieve core stats + * + * Retrieve ocf per core stats (for all IO classes together) + * + * @param[in] core core ID to which request pertains + * @param[out] stats statistics structure that shall be filled as + * a result of this function invocation. + * + * @result zero upon successful completion; error code otherwise + */ +int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats); + +/** + * @brief update DEBUG stats given IO request + * + * Function meant to update DEBUG stats for IO request. + * + * @note This function shall be invoked for each IO request processed + * + * @param[in] core to which request pertains + * @param[in] io request for which stats are being updated + */ +void ocf_core_update_stats(ocf_core_t core, struct ocf_io *io); + #endif From 0d4f4d3294f97ac822ad3a3b7a1a9d728de8892c Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 5 Sep 2019 05:27:03 -0400 Subject: [PATCH 07/11] Added API for updating statistics. Signed-off-by: Michal Mielewczyk --- inc/ocf_stats.h | 5 +- src/ocf_stats.c | 113 +++++++++++++++++++++++++++++++++++++++++++ src/ocf_stats_priv.h | 15 ++++++ 3 files changed, 130 insertions(+), 3 deletions(-) diff --git a/inc/ocf_stats.h b/inc/ocf_stats.h index 141483b..b326c74 100644 --- a/inc/ocf_stats.h +++ b/inc/ocf_stats.h @@ -5,10 +5,9 @@ /** * @file - * @brief OCF API for getting and reseting statistics + * @brief OCF API for updating and reseting statistics * - * This file contains routines pertaining to retrieval and - * manipulation of OCF IO statistics. + * This file contains routines pertaining to manipulation of OCF IO statistics. */ #ifndef __OCF_STATS_H__ diff --git a/src/ocf_stats.c b/src/ocf_stats.c index b670149..51a14f1 100644 --- a/src/ocf_stats.c +++ b/src/ocf_stats.c @@ -57,6 +57,119 @@ static void ocf_stats_error_init(struct ocf_counters_error *stats) env_atomic_set(&stats->write, 0); } +static void _ocf_stats_block_update(struct ocf_counters_block *counters, int dir, + uint64_t bytes) +{ + switch (dir) { + case OCF_READ: + env_atomic64_add(bytes, &counters->read_bytes); + break; + case OCF_WRITE: + env_atomic64_add(bytes, &counters->write_bytes); + break; + default: + ENV_BUG(); + } +} + +void ocf_core_stats_vol_block_update(ocf_core_t core, ocf_part_id_t part_id, + int dir, uint64_t bytes) +{ + struct ocf_counters_block *counters = + &core->counters->part_counters[part_id].blocks; + + _ocf_stats_block_update(counters, dir, bytes); +} + +void ocf_core_stats_cache_block_update(ocf_core_t core, ocf_part_id_t part_id, + int dir, uint64_t bytes) +{ + struct ocf_counters_block *counters = + &core->counters->part_counters[part_id].cache_blocks; + + _ocf_stats_block_update(counters, dir, bytes); +} + +void ocf_core_stats_core_block_update(ocf_core_t core, ocf_part_id_t part_id, + int dir, uint64_t bytes) +{ + struct ocf_counters_block *counters = + &core->counters->part_counters[part_id].core_blocks; + + _ocf_stats_block_update(counters, dir, bytes); +} + +void ocf_core_stats_request_update(ocf_core_t core, ocf_part_id_t part_id, + uint8_t dir, uint64_t hit_no, uint64_t core_line_count) +{ + struct ocf_counters_req *counters; + + switch (dir) { + case OCF_READ: + counters = &core->counters->part_counters[part_id].read_reqs; + break; + case OCF_WRITE: + counters = &core->counters->part_counters[part_id].write_reqs; + break; + default: + ENV_BUG(); + } + + env_atomic64_inc(&counters->total); + + if (hit_no == 0) + env_atomic64_inc(&counters->full_miss); + else if (hit_no < core_line_count) + env_atomic64_inc(&counters->partial_miss); +} + +void ocf_core_stats_request_pt_update(ocf_core_t core, ocf_part_id_t part_id, + uint8_t dir, uint64_t hit_no, uint64_t core_line_count) +{ + struct ocf_counters_req *counters; + + switch (dir) { + case OCF_READ: + counters = &core->counters->part_counters[part_id].read_reqs; + break; + case OCF_WRITE: + counters = &core->counters->part_counters[part_id].write_reqs; + break; + default: + ENV_BUG(); + } + + env_atomic64_inc(&counters->pass_through); +} + +static void _ocf_core_stats_error_update(struct ocf_counters_error *counters, + uint8_t dir) +{ + switch (dir) { + case OCF_READ: + env_atomic_inc(&counters->read); + break; + case OCF_WRITE: + env_atomic_inc(&counters->write); + break; + default: + ENV_BUG(); + } +} + +void ocf_core_stats_core_error_update(ocf_core_t core, uint8_t dir) +{ + struct ocf_counters_error *counters = &core->counters->core_errors; + + _ocf_core_stats_error_update(counters, dir); +} + +void ocf_core_stats_cache_error_update(ocf_core_t core, uint8_t dir) +{ + struct ocf_counters_error *counters = &core->counters->cache_errors; + + _ocf_core_stats_error_update(counters, dir); +} /******************************************************************** * Function that resets stats, debug and breakdown counters. diff --git a/src/ocf_stats_priv.h b/src/ocf_stats_priv.h index 93c65c9..59319dd 100644 --- a/src/ocf_stats_priv.h +++ b/src/ocf_stats_priv.h @@ -182,6 +182,21 @@ struct ocf_counters_core { #endif }; +void ocf_core_stats_core_block_update(ocf_core_t core, ocf_part_id_t part_id, + int dir, uint64_t bytes); +void ocf_core_stats_cache_block_update(ocf_core_t core, ocf_part_id_t part_id, + int dir, uint64_t bytes); +void ocf_core_stats_vol_block_update(ocf_core_t core, ocf_part_id_t part_id, + int dir, uint64_t bytes); + +void ocf_core_stats_request_update(ocf_core_t core, ocf_part_id_t part_id, + uint8_t dir, uint64_t hit_no, uint64_t core_line_count); +void ocf_core_stats_request_pt_update(ocf_core_t core, ocf_part_id_t part_id, + uint8_t dir, uint64_t hit_no, uint64_t core_line_count); + +void ocf_core_stats_core_error_update(ocf_core_t core, uint8_t dir); +void ocf_core_stats_cache_error_update(ocf_core_t core, uint8_t dir); + /** * @brief ocf_core_io_class_get_stats retrieve io class statistics * for given core From b4c384eb2d39b5b206697c4a43e64ed147fb768d Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 5 Sep 2019 06:03:40 -0400 Subject: [PATCH 08/11] Use API instead of raw variables to update error stats. Signed-off-by: Michal Mielewczyk --- src/engine/engine_bf.c | 2 +- src/engine/engine_d2c.c | 6 +----- src/engine/engine_fast.c | 2 +- src/engine/engine_inv.c | 2 +- src/engine/engine_pt.c | 2 +- src/engine/engine_rd.c | 4 ++-- src/engine/engine_wa.c | 2 +- src/engine/engine_wb.c | 2 +- src/engine/engine_wi.c | 4 ++-- src/engine/engine_wo.c | 4 ++-- src/engine/engine_wt.c | 4 ++-- src/engine/engine_zero.c | 2 +- src/utils/utils_cleaner.c | 6 ++---- 13 files changed, 18 insertions(+), 24 deletions(-) diff --git a/src/engine/engine_bf.c b/src/engine/engine_bf.c index 865b793..5899feb 100644 --- a/src/engine/engine_bf.c +++ b/src/engine/engine_bf.c @@ -61,7 +61,7 @@ static void _ocf_backfill_complete(struct ocf_request *req, int error) req->data = NULL; if (req->error) { - env_atomic_inc(&req->core->counters->cache_errors.write); + ocf_core_stats_cache_error_update(req->core, OCF_WRITE); ocf_engine_invalidate(req); } else { ocf_req_unlock(req); diff --git a/src/engine/engine_d2c.c b/src/engine/engine_d2c.c index 337769d..d88a964 100644 --- a/src/engine/engine_d2c.c +++ b/src/engine/engine_d2c.c @@ -16,17 +16,13 @@ static void _ocf_d2c_completion(struct ocf_request *req, int error) { - ocf_core_t core = req->core; req->error = error; OCF_DEBUG_RQ(req, "Completion"); if (req->error) { req->info.core_error = 1; - if (req->rw == OCF_READ) - env_atomic_inc(&core->counters->core_errors.read); - else - env_atomic_inc(&core->counters->core_errors.write); + ocf_core_stats_core_error_update(req->core, req->rw); } /* Complete request */ diff --git a/src/engine/engine_fast.c b/src/engine/engine_fast.c index 3921104..e62593d 100644 --- a/src/engine/engine_fast.c +++ b/src/engine/engine_fast.c @@ -43,7 +43,7 @@ static void _ocf_read_fast_complete(struct ocf_request *req, int error) if (req->error) { OCF_DEBUG_RQ(req, "ERROR"); - env_atomic_inc(&req->core->counters->cache_errors.read); + ocf_core_stats_cache_error_update(req->core, OCF_READ); ocf_engine_push_req_front_pt(req); } else { ocf_req_unlock(req); diff --git a/src/engine/engine_inv.c b/src/engine/engine_inv.c index fd30204..347d3cf 100644 --- a/src/engine/engine_inv.c +++ b/src/engine/engine_inv.c @@ -20,7 +20,7 @@ static void _ocf_invalidate_req(struct ocf_request *req, int error) { if (error) { req->error = error; - env_atomic_inc(&req->core->counters->cache_errors.write); + ocf_core_stats_cache_error_update(req->core, OCF_WRITE); } if (env_atomic_dec_return(&req->req_remaining)) diff --git a/src/engine/engine_pt.c b/src/engine/engine_pt.c index 852b953..fd73609 100644 --- a/src/engine/engine_pt.c +++ b/src/engine/engine_pt.c @@ -28,7 +28,7 @@ static void _ocf_read_pt_complete(struct ocf_request *req, int error) if (req->error) { req->info.core_error = 1; - env_atomic_inc(&req->core->counters->core_errors.read); + ocf_core_stats_core_error_update(req->core, OCF_READ); } /* Complete request */ diff --git a/src/engine/engine_rd.c b/src/engine/engine_rd.c index 4d6794f..2ca2d48 100644 --- a/src/engine/engine_rd.c +++ b/src/engine/engine_rd.c @@ -38,7 +38,7 @@ static void _ocf_read_generic_hit_complete(struct ocf_request *req, int error) OCF_DEBUG_RQ(req, "HIT completion"); if (req->error) { - env_atomic_inc(&req->core->counters->cache_errors.read); + ocf_core_stats_cache_error_update(req->core, OCF_READ); ocf_engine_push_req_front_pt(req); } else { @@ -77,7 +77,7 @@ static void _ocf_read_generic_miss_complete(struct ocf_request *req, int error) req->complete(req, req->error); req->info.core_error = 1; - env_atomic_inc(&req->core->counters->core_errors.read); + ocf_core_stats_core_error_update(req->core, OCF_READ); ctx_data_free(cache->owner, req->cp_data); req->cp_data = NULL; diff --git a/src/engine/engine_wa.c b/src/engine/engine_wa.c index 5613445..c41fd8b 100644 --- a/src/engine/engine_wa.c +++ b/src/engine/engine_wa.c @@ -24,7 +24,7 @@ static void _ocf_read_wa_complete(struct ocf_request *req, int error) if (req->error) { req->info.core_error = 1; - env_atomic_inc(&req->core->counters->core_errors.write); + ocf_core_stats_core_error_update(req->core, OCF_WRITE); } /* Complete request */ diff --git a/src/engine/engine_wb.c b/src/engine/engine_wb.c index 73cafc1..223cabf 100644 --- a/src/engine/engine_wb.c +++ b/src/engine/engine_wb.c @@ -89,7 +89,7 @@ static const struct ocf_io_if _io_if_wb_flush_metadata = { static void _ocf_write_wb_complete(struct ocf_request *req, int error) { if (error) { - env_atomic_inc(&req->core->counters->cache_errors.write); + ocf_core_stats_cache_error_update(req->core, OCF_WRITE); req->error |= error; } diff --git a/src/engine/engine_wi.c b/src/engine/engine_wi.c index 1fdae6b..6e8c285 100644 --- a/src/engine/engine_wi.c +++ b/src/engine/engine_wi.c @@ -26,7 +26,7 @@ static const struct ocf_io_if _io_if_wi_flush_metadata = { static void _ocf_write_wi_io_flush_metadata(struct ocf_request *req, int error) { if (error) { - env_atomic_inc(&req->core->counters->cache_errors.write); + ocf_core_stats_cache_error_update(req->core, OCF_WRITE); req->error |= error; } @@ -77,7 +77,7 @@ static void _ocf_write_wi_core_complete(struct ocf_request *req, int error) if (error) { req->error = error; req->info.core_error = 1; - env_atomic_inc(&req->core->counters->core_errors.write); + ocf_core_stats_core_error_update(req->core, OCF_WRITE); } if (env_atomic_dec_return(&req->req_remaining)) diff --git a/src/engine/engine_wo.c b/src/engine/engine_wo.c index f4fba5f..022d70b 100644 --- a/src/engine/engine_wo.c +++ b/src/engine/engine_wo.c @@ -21,7 +21,7 @@ static void ocf_read_wo_cache_complete(struct ocf_request *req, int error) { if (error) { - env_atomic_inc(&req->core->counters->cache_errors.read); + ocf_core_stats_cache_error_update(req->core, OCF_READ); req->error |= error; } @@ -148,7 +148,7 @@ static void _ocf_read_wo_core_complete(struct ocf_request *req, int error) if (error) { req->error |= error; req->info.core_error = 1; - env_atomic_inc(&req->core->counters->core_errors.read); + ocf_core_stats_core_error_update(req->core, OCF_READ); } /* if all mapped cachelines are clean, the data we've read from core diff --git a/src/engine/engine_wt.c b/src/engine/engine_wt.c index 0d70cec..ac5fc41 100644 --- a/src/engine/engine_wt.c +++ b/src/engine/engine_wt.c @@ -48,7 +48,7 @@ static void _ocf_write_wt_cache_complete(struct ocf_request *req, int error) { if (error) { req->error = req->error ?: error; - env_atomic_inc(&req->core->counters->cache_errors.write); + ocf_core_stats_cache_error_update(req->core, OCF_WRITE); if (req->error) inc_fallback_pt_error_counter(req->cache); @@ -62,7 +62,7 @@ static void _ocf_write_wt_core_complete(struct ocf_request *req, int error) if (error) { req->error = error; req->info.core_error = 1; - env_atomic_inc(&req->core->counters->core_errors.write); + ocf_core_stats_core_error_update(req->core, OCF_WRITE); } _ocf_write_wt_req_complete(req); diff --git a/src/engine/engine_zero.c b/src/engine/engine_zero.c index f3d0439..7caa52f 100644 --- a/src/engine/engine_zero.c +++ b/src/engine/engine_zero.c @@ -50,7 +50,7 @@ static const struct ocf_io_if _io_if_zero_purge = { static void _ocf_zero_io_flush_metadata(struct ocf_request *req, int error) { if (error) { - env_atomic_inc(&req->core->counters->cache_errors.write); + ocf_core_stats_cache_error_update(req->core, OCF_WRITE); req->error = error; } diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index 2bd5635..eb139a3 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -465,8 +465,7 @@ static void _ocf_cleaner_core_io_cmpl(struct ocf_io *io, int error) if (error) { map->invalid |= 1; _ocf_cleaner_set_error(req); - env_atomic_inc(&req->cache->core[map->core_id].counters-> - core_errors.write); + ocf_core_stats_core_error_update(req->core, OCF_WRITE); } _ocf_cleaner_core_io_end(req); @@ -623,8 +622,7 @@ static void _ocf_cleaner_cache_io_cmpl(struct ocf_io *io, int error) if (error) { map->invalid |= 1; _ocf_cleaner_set_error(req); - env_atomic_inc(&req->cache->core[map->core_id].counters-> - cache_errors.read); + ocf_core_stats_cache_error_update(req->core, OCF_READ); } _ocf_cleaner_cache_io_end(req); From 51c9c516a4ba36cd82d4d863bf265c86aeb1e302 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 5 Sep 2019 08:51:51 -0400 Subject: [PATCH 09/11] Use API instead of raw variables to update req stats. Signed-off-by: Michal Mielewczyk --- src/engine/engine_common.c | 22 ++-------------------- src/engine/engine_d2c.c | 9 ++------- src/engine/engine_pt.c | 4 ++-- src/engine/engine_wa.c | 4 ++-- src/engine/engine_wi.c | 4 ++-- 5 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/engine/engine_common.c b/src/engine/engine_common.c index 53a5fcc..2a03496 100644 --- a/src/engine/engine_common.c +++ b/src/engine/engine_common.c @@ -469,26 +469,8 @@ void ocf_engine_update_block_stats(struct ocf_request *req) void ocf_engine_update_request_stats(struct ocf_request *req) { - ocf_part_id_t part_id = req->part_id; - struct ocf_counters_req *reqs; - - switch (req->rw) { - case OCF_READ: - reqs = &req->core->counters->part_counters[part_id].read_reqs; - break; - case OCF_WRITE: - reqs = &req->core->counters->part_counters[part_id].write_reqs; - break; - default: - ENV_BUG(); - } - - env_atomic64_inc(&reqs->total); - - if (req->info.hit_no == 0) - env_atomic64_inc(&reqs->full_miss); - else if (req->info.hit_no < req->core_line_count) - env_atomic64_inc(&reqs->partial_miss); + ocf_core_stats_request_update(req->core, req->part_id, req->rw, + req->info.hit_no, req->core_line_count); } void ocf_engine_push_req_back(struct ocf_request *req, bool allow_sync) diff --git a/src/engine/engine_d2c.c b/src/engine/engine_d2c.c index d88a964..ef0c3c8 100644 --- a/src/engine/engine_d2c.c +++ b/src/engine/engine_d2c.c @@ -47,13 +47,8 @@ int ocf_io_d2c(struct ocf_request *req) ocf_engine_update_block_stats(req); - if (req->rw == OCF_READ) { - env_atomic64_inc(&core->counters-> - part_counters[req->part_id].read_reqs.pass_through); - } else { - env_atomic64_inc(&core->counters-> - part_counters[req->part_id].write_reqs.pass_through); - } + ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, + req->info.hit_no, req->core_line_count); /* Put OCF request - decrease reference counter */ ocf_req_put(req); diff --git a/src/engine/engine_pt.c b/src/engine/engine_pt.c index fd73609..bf18431 100644 --- a/src/engine/engine_pt.c +++ b/src/engine/engine_pt.c @@ -87,8 +87,8 @@ int ocf_read_pt_do(struct ocf_request *req) /* Update statistics */ ocf_engine_update_block_stats(req); - env_atomic64_inc(&req->core->counters-> - part_counters[req->part_id].read_reqs.pass_through); + ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, + req->info.hit_no, req->core_line_count); /* Put OCF request - decrease reference counter */ ocf_req_put(req); diff --git a/src/engine/engine_wa.c b/src/engine/engine_wa.c index c41fd8b..3c854c2 100644 --- a/src/engine/engine_wa.c +++ b/src/engine/engine_wa.c @@ -76,8 +76,8 @@ int ocf_write_wa(struct ocf_request *req) /* Update statistics */ ocf_engine_update_block_stats(req); - env_atomic64_inc(&req->core->counters-> - part_counters[req->part_id].write_reqs.pass_through); + ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, + req->info.hit_no, req->core_line_count); } /* Put OCF request - decrease reference counter */ diff --git a/src/engine/engine_wi.c b/src/engine/engine_wi.c index 6e8c285..b0d204c 100644 --- a/src/engine/engine_wi.c +++ b/src/engine/engine_wi.c @@ -112,8 +112,8 @@ static int _ocf_write_wi_do(struct ocf_request *req) /* Update statistics */ ocf_engine_update_block_stats(req); - env_atomic64_inc(&req->core->counters-> - part_counters[req->part_id].write_reqs.pass_through); + ocf_core_stats_request_pt_update(req->core, req->part_id, req->rw, + req->info.hit_no, req->core_line_count); /* Put OCF request - decrease reference counter */ ocf_req_put(req); From 01ce586e6a38a28b6d0fcefd26154a2b8814e43e Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 6 Sep 2019 05:02:16 -0400 Subject: [PATCH 10/11] Use API instead of raw variables to update block stats. Signed-off-by: Michal Mielewczyk --- src/engine/engine_common.c | 14 ++------------ src/utils/utils_cleaner.c | 12 ++++-------- src/utils/utils_io.c | 16 +++------------- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/src/engine/engine_common.c b/src/engine/engine_common.c index 2a03496..727d50f 100644 --- a/src/engine/engine_common.c +++ b/src/engine/engine_common.c @@ -453,18 +453,8 @@ void ocf_engine_clean(struct ocf_request *req) void ocf_engine_update_block_stats(struct ocf_request *req) { - ocf_part_id_t part_id = req->part_id; - struct ocf_counters_block *blocks; - - blocks = &req->core->counters-> - part_counters[part_id].blocks; - - if (req->rw == OCF_READ) - env_atomic64_add(req->byte_length, &blocks->read_bytes); - else if (req->rw == OCF_WRITE) - env_atomic64_add(req->byte_length, &blocks->write_bytes); - else - ENV_BUG(); + ocf_core_stats_vol_block_update(req->core, req->part_id, req->rw, + req->byte_length); } void ocf_engine_update_request_stats(struct ocf_request *req) diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index eb139a3..46b6106 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -480,13 +480,10 @@ static void _ocf_cleaner_core_io_for_dirty_range(struct ocf_request *req, int err; ocf_cache_t cache = req->cache; struct ocf_io *io; - struct ocf_counters_block *core_stats; ocf_core_t core = ocf_cache_get_core(cache, iter->core_id); ocf_part_id_t part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); - core_stats = &core->counters->part_counters[part_id].core_blocks; - addr = (ocf_line_size(cache) * iter->core_line) + SECTORS_TO_BYTES(begin); offset = (ocf_line_size(cache) * iter->hash) @@ -505,7 +502,8 @@ static void _ocf_cleaner_core_io_for_dirty_range(struct ocf_request *req, ocf_io_set_cmpl(io, iter, req, _ocf_cleaner_core_io_cmpl); - env_atomic64_add(SECTORS_TO_BYTES(end - begin), &core_stats->write_bytes); + ocf_core_stats_core_block_update(core, part_id, OCF_WRITE, + SECTORS_TO_BYTES(end - begin)); OCF_DEBUG_PARAM(req->cache, "Core write, line = %llu, " "sector = %llu, count = %llu", iter->core_line, begin, @@ -644,7 +642,6 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) ocf_part_id_t part_id; struct ocf_io *io; int err; - struct ocf_counters_block *cache_stats; /* Protect IO completion race */ env_atomic_inc(&req->req_remaining); @@ -668,8 +665,6 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); - cache_stats = &core->counters->part_counters[part_id].cache_blocks; - io = ocf_new_cache_io(cache, req->io_queue, addr, ocf_line_size(cache), OCF_READ, part_id, 0); @@ -689,7 +684,8 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) continue; } - env_atomic64_add(ocf_line_size(cache), &cache_stats->read_bytes); + ocf_core_stats_cache_block_update(core, part_id, OCF_READ, + ocf_line_size(cache)); ocf_volume_submit_io(io); } diff --git a/src/utils/utils_io.c b/src/utils/utils_io.c index 1137dc5..db98e7b 100644 --- a/src/utils/utils_io.c +++ b/src/utils/utils_io.c @@ -227,7 +227,6 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, struct ocf_request *req, int dir, uint64_t offset, uint64_t size, unsigned int reqs, ocf_req_end_t callback) { - struct ocf_counters_block *cache_stats; uint64_t flags = req->ioi.io.flags; uint32_t io_class = req->ioi.io.io_class; uint64_t addr, bytes, total_bytes = 0; @@ -240,8 +239,6 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, ENV_BUG_ON(req->byte_length < offset + size); ENV_BUG_ON(first_cl + reqs > req->core_line_count); - cache_stats = &req->core->counters->part_counters[io_class].cache_blocks; - if (reqs == 1) { addr = ocf_metadata_map_lg2phy(cache, req->map[first_cl].coll_idx); @@ -323,27 +320,20 @@ void ocf_submit_cache_reqs(struct ocf_cache *cache, ENV_BUG_ON(total_bytes != size); update_stats: - if (dir == OCF_WRITE) - env_atomic64_add(total_bytes, &cache_stats->write_bytes); - else if (dir == OCF_READ) - env_atomic64_add(total_bytes, &cache_stats->read_bytes); + ocf_core_stats_cache_block_update(req->core, io_class, dir, total_bytes); } void ocf_submit_volume_req(ocf_volume_t volume, struct ocf_request *req, ocf_req_end_t callback) { - struct ocf_counters_block *core_stats; uint64_t flags = req->ioi.io.flags; uint32_t io_class = req->ioi.io.io_class; int dir = req->rw; struct ocf_io *io; int err; - core_stats = &req->core->counters->part_counters[io_class].core_blocks; - if (dir == OCF_WRITE) - env_atomic64_add(req->byte_length, &core_stats->write_bytes); - else if (dir == OCF_READ) - env_atomic64_add(req->byte_length, &core_stats->read_bytes); + ocf_core_stats_core_block_update(req->core, io_class, dir, + req->byte_length); io = ocf_volume_new_io(volume, req->io_queue, req->byte_position, req->byte_length, dir, io_class, flags); From e6f032cae9710206ba7103b89de2a03dd139dc36 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 10 Sep 2019 07:51:00 -0400 Subject: [PATCH 11/11] Fix typo. Signed-off-by: Michal Mielewczyk --- src/engine/engine_fast.c | 2 +- src/engine/engine_wb.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/engine_fast.c b/src/engine/engine_fast.c index e62593d..d2a8153 100644 --- a/src/engine/engine_fast.c +++ b/src/engine/engine_fast.c @@ -91,7 +91,7 @@ static int _ocf_read_fast_do(struct ocf_request *req) ocf_engine_io_count(req), _ocf_read_fast_complete); - /* Updata statistics */ + /* Update statistics */ ocf_engine_update_request_stats(req); ocf_engine_update_block_stats(req); diff --git a/src/engine/engine_wb.c b/src/engine/engine_wb.c index 223cabf..f97793d 100644 --- a/src/engine/engine_wb.c +++ b/src/engine/engine_wb.c @@ -150,13 +150,13 @@ int ocf_write_wb_do(struct ocf_request *req) /* Get OCF request - increase reference counter */ ocf_req_get(req); - /* Updata status bits */ + /* Update status bits */ _ocf_write_wb_update_bits(req); /* Submit IO */ _ocf_write_wb_submit(req); - /* Updata statistics */ + /* Update statistics */ ocf_engine_update_request_stats(req); ocf_engine_update_block_stats(req);