From c46441b875dd0470ffdd03a71f2dd8656356c561 Mon Sep 17 00:00:00 2001 From: Robert Baldyga Date: Wed, 8 Apr 2026 13:07:50 +0200 Subject: [PATCH] cleaner: Introduce separate cleaner stats Signed-off-by: Robert Baldyga --- inc/ocf_stats.h | 3 ++ src/ocf_stats.c | 37 ++++++++++++++++ src/ocf_stats_builder.c | 43 ++++++++++++++++++- src/ocf_stats_priv.h | 21 +++++++++ src/utils/utils_cleaner.c | 9 ++-- tests/functional/pyocf/types/stats/shared.py | 3 ++ .../tests/eviction/test_eviction.py | 11 +++-- 7 files changed, 117 insertions(+), 10 deletions(-) diff --git a/inc/ocf_stats.h b/inc/ocf_stats.h index a526caf5..d218e8ed 100644 --- a/inc/ocf_stats.h +++ b/inc/ocf_stats.h @@ -96,6 +96,7 @@ struct ocf_stats_requests { struct ocf_stat wr_pt; struct ocf_stat serviced; struct ocf_stat prefetch[ocf_pf_num]; + struct ocf_stat cleaner; struct ocf_stat user; struct ocf_stat total; }; @@ -137,6 +138,8 @@ struct ocf_stats_blocks { struct ocf_stat pass_through_total; struct ocf_stat prefetch_core_rd[ocf_pf_num]; struct ocf_stat prefetch_cache_wr[ocf_pf_num]; + struct ocf_stat cleaner_cache_rd; + struct ocf_stat cleaner_core_wr; }; /** diff --git a/src/ocf_stats.c b/src/ocf_stats.c index 2f2ce222..bce0c609 100644 --- a/src/ocf_stats.c +++ b/src/ocf_stats.c @@ -54,6 +54,8 @@ static void ocf_stats_part_init(struct ocf_counters_part *stats) ocf_stats_req_init(&stats->prefetch_reqs[pf_id]); ocf_stats_block_init(&stats->prefetch_blocks[pf_id]); } + ocf_stats_req_init(&stats->cleaner_reqs); + ocf_stats_block_init(&stats->cleaner_blocks); ocf_stats_block_init(&stats->blocks); ocf_stats_block_init(&stats->core_blocks); @@ -132,6 +134,33 @@ void ocf_core_stats_pt_block_update(ocf_core_t core, ocf_part_id_t part_id, _ocf_stats_block_update(counters, dir, bytes); } +void ocf_core_stats_cache_block_update_cleaner(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].cleaner_blocks; + + _ocf_stats_block_update(counters, dir, bytes); +} + +void ocf_core_stats_core_block_update_cleaner(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].cleaner_blocks; + + _ocf_stats_block_update(counters, dir, bytes); +} + +void ocf_core_stats_request_update_cleaner(ocf_core_t core, + ocf_part_id_t part_id) +{ + struct ocf_counters_req *counters = + &core->counters->part_counters[part_id].cleaner_reqs; + + env_atomic64_inc(&counters->total); +} + 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, ocf_pf_id_t pf_id, uint8_t deferred) @@ -359,6 +388,9 @@ int ocf_core_io_class_get_stats(ocf_core_t core, ocf_part_id_t part_id, &part_stat->prefetch_blocks[pf_id]); } + copy_req_stats(&stats->cleaner_reqs, &part_stat->cleaner_reqs); + copy_block_stats(&stats->cleaner_blocks, &part_stat->cleaner_blocks); + 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); @@ -413,6 +445,11 @@ int ocf_core_get_stats(ocf_core_t core, struct ocf_stats_core *stats) &curr->prefetch_blocks[pf_id]); } + accum_req_stats(&stats->cleaner_reqs, + &curr->cleaner_reqs); + accum_block_stats(&stats->cleaner_blocks, + &curr->cleaner_blocks); + 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); diff --git a/src/ocf_stats_builder.c b/src/ocf_stats_builder.c index 54a64118..d995bf49 100644 --- a/src/ocf_stats_builder.c +++ b/src/ocf_stats_builder.c @@ -22,6 +22,8 @@ static void _fill_req(struct ocf_stats_requests *req, struct ocf_stats_core *s) s->write_reqs.pass_through; uint64_t hit; uint64_t prefetch_total = 0; + uint64_t cleaner_total; + uint64_t internal_total; ocf_pf_id_t pf_id; /* Reads Section */ @@ -55,9 +57,14 @@ static void _fill_req(struct ocf_stats_requests *req, struct ocf_stats_core *s) prefetch_total); } + /* Cleaner Section */ + cleaner_total = s->cleaner_reqs.total; + _set(&req->cleaner, cleaner_total, cleaner_total); + /* Summary */ + internal_total = prefetch_total + cleaner_total; _set(&req->user, total, total); - _set(&req->total, total + prefetch_total, total + prefetch_total); + _set(&req->total, total + internal_total, total + internal_total); } static void _fill_req_part(struct ocf_stats_requests *req, @@ -68,6 +75,8 @@ static void _fill_req_part(struct ocf_stats_requests *req, s->write_reqs.pass_through; uint64_t hit; uint64_t prefetch_total = 0; + uint64_t cleaner_total; + uint64_t internal_total; ocf_pf_id_t pf_id; /* Reads Section */ @@ -101,9 +110,14 @@ static void _fill_req_part(struct ocf_stats_requests *req, prefetch_total); } + /* Cleaner Section */ + cleaner_total = s->cleaner_reqs.total; + _set(&req->cleaner, cleaner_total, cleaner_total); + /* Summary */ + internal_total = prefetch_total + cleaner_total; _set(&req->total, total, total); - _set(&req->total, total + prefetch_total, total + prefetch_total); + _set(&req->total, total + internal_total, total + internal_total); } static void _fill_blocks(struct ocf_stats_blocks *blocks, @@ -111,6 +125,7 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks, { uint64_t rd, wr, total; uint64_t pf_rd, pf_wr; + uint64_t cl_rd, cl_wr; ocf_pf_id_t pf_id; /* Core volume */ @@ -120,6 +135,7 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks, for_each_pf(pf_id) total += _bytes4k(s->prefetch_blocks[pf_id].read); + total += _bytes4k(s->cleaner_blocks.write); _set(&blocks->core_volume_rd, rd, total); _set(&blocks->core_volume_wr, wr, total); @@ -132,6 +148,7 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks, for_each_pf(pf_id) total += _bytes4k(s->prefetch_blocks[pf_id].write); + total += _bytes4k(s->cleaner_blocks.read); _set(&blocks->cache_volume_rd, rd, total); _set(&blocks->cache_volume_wr, wr, total); @@ -162,6 +179,12 @@ static void _fill_blocks(struct ocf_stats_blocks *blocks, pf_wr = _bytes4k(s->prefetch_blocks[pf_id].write); _set(&blocks->prefetch_cache_wr[pf_id], pf_wr, total); } + + /* Cleaner */ + cl_rd = _bytes4k(s->cleaner_blocks.read); + _set(&blocks->cleaner_cache_rd, cl_rd, total); + cl_wr = _bytes4k(s->cleaner_blocks.write); + _set(&blocks->cleaner_core_wr, cl_wr, total); } static void _fill_blocks_part(struct ocf_stats_blocks *blocks, @@ -169,6 +192,7 @@ static void _fill_blocks_part(struct ocf_stats_blocks *blocks, { uint64_t rd, wr, total; uint64_t pf_rd, pf_wr; + uint64_t cl_rd, cl_wr; ocf_pf_id_t pf_id; /* Core volume */ @@ -178,6 +202,7 @@ static void _fill_blocks_part(struct ocf_stats_blocks *blocks, for_each_pf(pf_id) total += _bytes4k(s->prefetch_blocks[pf_id].read); + total += _bytes4k(s->cleaner_blocks.write); _set(&blocks->core_volume_rd, rd, total); _set(&blocks->core_volume_wr, wr, total); @@ -190,6 +215,7 @@ static void _fill_blocks_part(struct ocf_stats_blocks *blocks, for_each_pf(pf_id) total += _bytes4k(s->prefetch_blocks[pf_id].write); + total += _bytes4k(s->cleaner_blocks.read); _set(&blocks->cache_volume_rd, rd, total); _set(&blocks->cache_volume_wr, wr, total); @@ -220,6 +246,12 @@ static void _fill_blocks_part(struct ocf_stats_blocks *blocks, pf_wr = _bytes4k(s->prefetch_blocks[pf_id].write); _set(&blocks->prefetch_cache_wr[pf_id], pf_wr, total); } + + /* Cleaner */ + cl_rd = _bytes4k(s->cleaner_blocks.read); + _set(&blocks->cleaner_cache_rd, cl_rd, total); + cl_wr = _bytes4k(s->cleaner_blocks.write); + _set(&blocks->cleaner_core_wr, cl_wr, total); } static void _fill_errors(struct ocf_stats_errors *errors, @@ -309,6 +341,10 @@ static int _accumulate_io_class_stats(ocf_core_t core, void *cntx) &stats.prefetch_blocks[pf_id]); } + /* Cleaner section */ + _accumulate_reqs(&total->cleaner_reqs, &stats.cleaner_reqs); + _accumulate_block(&total->cleaner_blocks, &stats.cleaner_blocks); + return 0; } @@ -507,6 +543,9 @@ static int _accumulate_stats(ocf_core_t core, void *cntx) &stats.prefetch_blocks[pf_id]); } + _accumulate_reqs(&total->cleaner_reqs, &stats.cleaner_reqs); + _accumulate_block(&total->cleaner_blocks, &stats.cleaner_blocks); + return 0; } diff --git a/src/ocf_stats_priv.h b/src/ocf_stats_priv.h index 735eee89..892e8647 100644 --- a/src/ocf_stats_priv.h +++ b/src/ocf_stats_priv.h @@ -98,6 +98,12 @@ struct ocf_stats_io_class { /** Prefetch block per prefetcher */ struct ocf_stats_block prefetch_blocks[ocf_pf_num]; + /** Cleaner requests statistics */ + struct ocf_stats_req cleaner_reqs; + + /** Cleaner block statistics */ + struct ocf_stats_block cleaner_blocks; + /** Block requests for ocf volume statistics */ struct ocf_stats_block blocks; @@ -162,6 +168,12 @@ struct ocf_stats_core { /** Block requests submitted by Prefetcher to this core */ struct ocf_stats_block prefetch_blocks[ocf_pf_num]; + /** Cleaner requests statistics */ + struct ocf_stats_req cleaner_reqs; + + /** Cleaner block statistics */ + struct ocf_stats_block cleaner_blocks; + /** Pass Through block requests statistics */ struct ocf_stats_block pass_through_blocks; @@ -182,9 +194,11 @@ struct ocf_counters_part { struct ocf_counters_req read_reqs; struct ocf_counters_req write_reqs; struct ocf_counters_req prefetch_reqs[ocf_pf_num]; + struct ocf_counters_req cleaner_reqs; struct ocf_counters_block blocks; struct ocf_counters_block prefetch_blocks[ocf_pf_num]; + struct ocf_counters_block cleaner_blocks; struct ocf_counters_block core_blocks; struct ocf_counters_block cache_blocks; @@ -221,11 +235,18 @@ void ocf_core_stats_vol_block_update(ocf_core_t core, ocf_part_id_t part_id, void ocf_core_stats_pt_block_update(ocf_core_t core, ocf_part_id_t part_id, int dir, uint64_t bytes); +void ocf_core_stats_cache_block_update_cleaner(ocf_core_t core, + ocf_part_id_t part_id, int dir, uint64_t bytes); +void ocf_core_stats_core_block_update_cleaner(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, ocf_pf_id_t pf_id, uint8_t deferred); 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_request_update_cleaner(ocf_core_t core, + ocf_part_id_t part_id); 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); diff --git a/src/utils/utils_cleaner.c b/src/utils/utils_cleaner.c index 379fcc3f..56082102 100644 --- a/src/utils/utils_cleaner.c +++ b/src/utils/utils_cleaner.c @@ -436,8 +436,8 @@ static void _ocf_cleaner_core_io_for_dirty_range(struct ocf_request *req, offset = (ocf_line_size(cache) * iter->hash) + BLOCKS_TO_BYTES(begin); - ocf_core_stats_core_block_update(req->core, part_id, OCF_WRITE, - BLOCKS_TO_BYTES(end - begin), ocf_pf_none); + ocf_core_stats_core_block_update_cleaner(req->core, part_id, OCF_WRITE, + BLOCKS_TO_BYTES(end - begin)); OCF_DEBUG_PARAM(req->cache, "Core write, line = %llu, " "block = %llu, count = %llu", iter->core_line, begin, @@ -579,8 +579,9 @@ static int _ocf_cleaner_fire_cache(struct ocf_request *req) part_id = ocf_metadata_get_partition_id(cache, iter->coll_idx); - ocf_core_stats_cache_block_update(req->core, part_id, OCF_READ, - ocf_line_size(cache), ocf_pf_none); + ocf_core_stats_cache_block_update_cleaner(req->core, part_id, + OCF_READ, ocf_line_size(cache)); + ocf_core_stats_request_update_cleaner(req->core, part_id); req->addr = iter->core_line * ocf_line_size(cache); diff --git a/tests/functional/pyocf/types/stats/shared.py b/tests/functional/pyocf/types/stats/shared.py index c158b615..e121b785 100644 --- a/tests/functional/pyocf/types/stats/shared.py +++ b/tests/functional/pyocf/types/stats/shared.py @@ -64,6 +64,7 @@ class RequestsStats(Structure): ("wr_pt", _Stat), ("serviced", _Stat), ("prefetch", _Stat * PF_ID_NUM), + ("cleaner", _Stat), ("user", _Stat), ("total", _Stat), ] @@ -85,6 +86,8 @@ class BlocksStats(Structure): ("pt_total", _Stat), ("prefetch_core_rd", _Stat * PF_ID_NUM), ("prefetch_cache_wr", _Stat * PF_ID_NUM), + ("cleaner_cache_rd", _Stat), + ("cleaner_core_wr", _Stat), ] diff --git a/tests/functional/tests/eviction/test_eviction.py b/tests/functional/tests/eviction/test_eviction.py index 2170cf3c..8b61e20f 100644 --- a/tests/functional/tests/eviction/test_eviction.py +++ b/tests/functional/tests/eviction/test_eviction.py @@ -106,10 +106,13 @@ def test_write_size_greater_than_cache(pyocf_ctx, mode: CacheMode, cls: CacheLin assert pt_writes_first["value"] == 0 assert pt_writes_second["value"] == 1 assert second_block_sts["cache_volume_wr"]["value"] == valid_io_size.blocks_4k - assert ( - second_block_sts["core_volume_wr"]["value"] - == valid_io_size.blocks_4k + io_size_bigger_than_cache.blocks_4k - ) + if mode.lazy_write(): + assert second_block_sts["core_volume_wr"]["value"] == io_size_bigger_than_cache.blocks_4k + assert second_block_sts["cleaner_core_wr"]["value"] == valid_io_size.blocks_4k + else: + assert second_block_sts["core_volume_wr"]["value"] == ( + valid_io_size.blocks_4k + io_size_bigger_than_cache.blocks_4k + ) @pytest.mark.parametrize("io_dir", IoDir)